-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTexture.cpp
More file actions
265 lines (218 loc) · 9.07 KB
/
Copy pathTexture.cpp
File metadata and controls
265 lines (218 loc) · 9.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
// ===========================================================================
/// <summary>
/// Texture.h
/// DirectXIntroduction
/// created by Mehrdad Soleimanimajd on 28.08.2019
/// </summary>
/// <created>ʆϒʅ, 28.08.2019</created>
/// <changed>ʆϒʅ, 04.07.2023</changed>
// ===========================================================================
#include "texture.h"
#include "Shared.h"
template <typename fileType>
Texture<fileType>::Texture (ID3D10Device1* dev, const char* path) :
device (dev), data (nullptr), texture (nullptr), textureView (nullptr)
{
try
{
HRESULT hR;
if (!Load (path))
{
PointerProvider::getFileLogger ()->push (logType::error, std::this_thread::get_id (), L"mainThread",
L"Loading the texture failed! file: "
+ Converter::strConverter (path));
if (data)
delete [] data;
data = nullptr;
return;
}
// texture description
D3D10_TEXTURE2D_DESC textureDesc;
textureDesc.Height = file.height;
textureDesc.Width = file.width;
textureDesc.MipLevels = 0;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // 32 bit RGBA
textureDesc.SampleDesc.Count = 1; // default
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D10_USAGE_DEFAULT;
// default (UpdateSubresource): higher speed memory, gets cache retention preference (for not removed or reloaded data)
// dynamic (Map,Unmap): will place in the not cached memory locations (data will be rewritten shortly)
// settings required for mipmaped textures
textureDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS;
// empty texture creation
hR = device->CreateTexture2D (&textureDesc, nullptr, &texture);
if (FAILED (hR))
{
PointerProvider::getFileLogger ()->push (logType::error, std::this_thread::get_id (), L"mainThread",
L"Creation of texture 2D failed!"
+ Converter::strConverter (path));
return;
}
// row pitch of targa image data
unsigned int rowPitch = (file.width * 4) * sizeof (char);
// targa image data array into texture
// note that the use of Map and Unmap is possible and generally a lot quicker
// recommendations for correct choice:
//-- Map and Unmap for data that is reloaded each frame or on a very regular basis.
//-- UpdateSubresource: for data that is loaded once or rarely during loading sequences
device->UpdateSubresource (texture, 0, nullptr, data, rowPitch, 0);
// shader view description
D3D10_SHADER_RESOURCE_VIEW_DESC shaderResdataDesc;
shaderResdataDesc.Format = textureDesc.Format;
shaderResdataDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
// important mipmap variables: below: full range of Mipmap levels for high quality texture rendering at any distance
shaderResdataDesc.Texture2D.MostDetailedMip = 0;
shaderResdataDesc.Texture2D.MipLevels = -1;
// texture shader resource view creation
// purpose: to set the texture in shaders
hR = device->CreateShaderResourceView (texture, &shaderResdataDesc, &textureView);
if (FAILED (hR))
{
PointerProvider::getFileLogger ()->push (logType::error, std::this_thread::get_id (), L"mainThread",
L"Creation of shader resource view failed!"
+ Converter::strConverter (path));
return;
}
textureView->GetDesc (&shaderResdataDesc);
// texture mipmaps generation
device->GenerateMips (textureView);
delete [] data;
data = nullptr;
} catch (const std::exception& ex)
{
PointerProvider::getFileLogger ()->push (logType::error, std::this_thread::get_id (), L"mainThread",
Converter::strConverter (ex.what ()));
}
};
// .tga loader specialization
//template<typename TargaHeader>
bool Texture<TargaHeader>::Load (const char* path)
{
try
{
FILE* filePtr {nullptr};
if (fopen_s (&filePtr, path, "rb") != 0) // open in binary for read
return false;
// read one full item (targa file Header) introduced by count parameter
// note that the function returns the number of full items successfully read
if (fread (&file, sizeof (TargaHeader), 1, filePtr) != 1) // file header
return false;
int imageSize {file.width * file.height * 4};
int imageSizeTmp {0}; // 24 bit targa image file support
if (file.bpp == 24) // if 24 bit (32 bit targa files with support for alpha channels)
imageSizeTmp = file.width * file.height * 3; // 32 bit image data size calculation
else
if (file.bpp == 32)
imageSizeTmp = imageSize;
else
return false;
unsigned char* temp; // targa format is stored upside down
temp = new (std::nothrow) unsigned char [imageSizeTmp]; // targa image data holder
if (!temp)
return false;
data = new (std::nothrow) unsigned char [imageSize]; // targa image data holder in correct order
if (!data)
return false;
if (fread (temp, 1, imageSizeTmp, filePtr) != imageSizeTmp)
{
delete [] temp;
return false;
}
if (fclose (filePtr) != 0)
{
delete [] temp;
return false;
}
if (file.bpp == 32) // if 24 bit (32 bit targa files with support for alpha channels)
{
int indexD {0}; // index (targa destination data array)
int indexS {imageSize - (file.width * 4)}; // index (the actual on disk targa image data)
// the actual restoring in correct order
for (int i = 0; i < file.height; i++)
{
for (int j = 0; j < file.width; j++)
{
data [indexD + 0] = temp [indexS + 0]; // Read
data [indexD + 1] = temp [indexS + 3]; // Green
data [indexD + 2] = temp [indexS + 2]; // Blue
data [indexD + 3] = temp [indexS + 1]; // Alpha
indexD += 4; // increment indices
indexS += 4;
}
indexS -= (file.width * 8); // set to begin of the column of next preceding row
}
} else
{
int indexD {0}; // index (targa destination data array)
int indexS {imageSizeTmp - (file.width * 3)}; // index (the actual on disk targa image data)
unsigned char alpha {0};
for (int i = 0; i < file.height; i++)
{
for (int j = 0; j < file.width; j++)
{
data [indexD + 0] = temp [indexS + 0]; // Read
data [indexD + 1] = temp [indexS + 2]; // Green
data [indexD + 2] = temp [indexS + 1]; // Blue
data [indexD + 3] = alpha; // Alpha
indexD += 4;
indexS += 3;
}
indexS -= (file.width * 6);
}
}
delete [] temp;
return true;
} catch (const std::exception& ex)
{
PointerProvider::getFileLogger ()->push (logType::error, std::this_thread::get_id (), L"mainThread",
Converter::strConverter (ex.what ()));
return false;
}
};
// .tga loader specialization
//template<typename PngHeader>
bool Texture<PngHeader>::Load (const char* path)
{
//Todo research more interesting formats to add
return false;
};
template<typename fileType>
ID3D10ShaderResourceView** const Texture<fileType>::getTexture ()
{
return &textureView;
};
template<typename fileType>
void Texture<fileType>::release ()
{
try
{
if (data)
delete [] data;
if (texture)
{
texture->Release ();
texture = nullptr;
}
if (textureView)
{
textureView->Release ();
textureView = nullptr;
}
device = nullptr;
} catch (const std::exception& ex)
{
PointerProvider::getFileLogger ()->push (logType::error, std::this_thread::get_id (), L"mainThread",
Converter::strConverter (ex.what ()));
}
};
void TextureClassLinker (void) // don't call this function: solution for linker error, when using templates.
{
ID3D10Device1* temp {nullptr};
Texture<TargaHeader> tempTex (temp, "");
tempTex.getTexture ();
tempTex.release ();
}