|
Image
Image is a buffer with pixel data.
I put information in separate struct.
And added some usefull methods.
enum class slImageFormat : uint32_t
{
r8g8b8,
r8g8b8a8,
x1r5g5b5,
a4r4g4b4,
x4r4g4b4,
r5g6b5,
a1r5g5b5
};
struct slImageInfo
{
uint32_t m_width = 0;
uint32_t m_height = 0;
uint32_t m_bits = 32;
uint32_t m_pitch = 0;
slImageFormat m_format = slImageFormat::r8g8b8a8;
};
class slImage
{
public:
slImage();
~slImage();
uint8_t* m_data = 0;
uint32_t m_dataSize = 0;
slImageInfo m_info;
// fast creating
void Create(uint32_t x, uint32_t y);
// must be created
void FlipVertical();
// must be created
void FlipPixel();
// must be created
void Fill(const slColor& color);
void ConvertTo(slImageFormat);
};
Image loader
New library and new abstract class
class slImageLoader
{
public:
slImageLoader() {}
virtual ~slImageLoader() {}
virtual uint32_t GetSupportedFilesCount() = 0;
virtual slString GetSupportedFileExtension(uint32_t) = 0;
virtual slString GetSupportedFileName(uint32_t) = 0;
virtual slImage* Load(const char* path) = 0;
};
Create the object in new library
extern "C"
{
slImageLoader* SL_CDECL slImageLoaderDefault_create()
{
slImageLoaderImpl* il = slCreate<slImageLoaderImpl>();
return il;
}
}
Image loader implementation class look almost the same
with mesh loader.
class slImageLoaderImpl : public slImageLoader{
slImage* LoadBMP(const char* path);
public:
slImageLoaderImpl();
virtual ~slImageLoaderImpl();
virtual uint32_t GetSupportedFilesCount() final;
virtual slString GetSupportedFileExtension(uint32_t) final;
virtual slString GetSupportedFileName(uint32_t) final;
virtual slImage* Load(const char* path) final;
};
BMP
Load 32, 24, 16 bits
#pragma pack(push,2)
struct BitmapHeader {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
};
#pragma pack(pop)
struct ciexyzTriple {
int32_t ciexyzRed[3];
int32_t ciexyzGreen[3];
int32_t ciexyzBlue[3];
};
struct BitmapInfoHeader_v5 {
uint32_t bV5Size; // размер header в файле
int32_t bV5Width; // ширина
int32_t bV5Height; // высота
uint16_t bV5Planes; // хз что это, всегда 1
uint16_t bV5BitCount; // биты
uint32_t bV5Compression; // 1 - RLE 8bit, 2 - RLE 4bit, 3 или что-то, видимо, специальные обозначения у разработчиков 2D редакторов.
uint32_t bV5SizeImage; // размер массива пикселей/индексов
int32_t bV5XPelsPerMeter;// размер в чём-то, видимо для печати или вывода ещё кудато
int32_t bV5YPelsPerMeter;// для обычного использования в ПК не играет никакой роли
uint32_t bV5ClrUsed; // обычно тут ноль
uint32_t bV5ClrImportant;// и тут ноль
uint32_t bV5RedMask; // для определения позиции цветов
uint32_t bV5GreenMask; // в форматах типа x1r5g5b5
uint32_t bV5BlueMask;
uint32_t bV5AlphaMask;
uint32_t bV5CSType; // далее информация для более специализированного
ciexyzTriple bV5Endpoints; // использования.
uint32_t bV5GammaRed; // для передачи простой картинки достаточно того
uint32_t bV5GammaGreen; // что указано выше. А эта часть нужна для, например,
uint32_t bV5GammaBlue; // тех кто делает видео плеер, видео редактор
uint32_t bV5Intent; // что-то типа этого. Как бы универсальное решение
uint32_t bV5ProfileData; // от Microsoft
uint32_t bV5ProfileSize;
uint32_t bV5Reserved;
};
slImage* slImageLoaderImpl::LoadBMP(const char* path)
{
SL_ASSERT_ST(path);
FILE* file = 0;
fopen_s(&file, path, "rb");
if (!file)
{
slLog::PrintWarning("BMP: Image could not be opened\n");
return NULL;
}
BitmapHeader header;
BitmapInfoHeader_v5 info;
if (fread(&header, 1, sizeof(BitmapHeader), file) != sizeof(BitmapHeader))
{
slLog::PrintWarning("BMP: Not a correct BMP file\n");
fclose(file);
return 0;
}
if (header.bfType != 19778)
{
slLog::PrintWarning("BMP: Not a correct BMP file\n");
fclose(file);
return 0;
}
fread(&info, 1, sizeof(BitmapInfoHeader_v5), file);
if (info.bV5Size < 40U)
{
slLog::PrintWarning("BMP: Bad header size\n");
fclose(file);
return 0;
}
if (/*info.bV5BitCount != 1u &&
info.bV5BitCount != 4u &&
info.bV5BitCount != 8u &&*/
info.bV5BitCount != 16u &&
info.bV5BitCount != 24u &&
info.bV5BitCount != 32u)
{
slLog::PrintWarning("BMP: Bad bit count\n");
fclose(file);
return 0;
}
slImageInfo imageInfo;
slImage* image = NULL;
imageInfo.m_width = static_cast<uint32_t>(info.bV5Width);
imageInfo.m_height = static_cast<uint32_t>(info.bV5Height);
imageInfo.m_bits = info.bV5BitCount;
bool flipPixel = false;
if (imageInfo.m_bits == 24u)
{
imageInfo.m_format = slImageFormat::r8g8b8;
imageInfo.m_pitch = imageInfo.m_width * 3;
image = slCreate<slImage>();
image->m_dataSize = imageInfo.m_pitch * imageInfo.m_height;
image->m_data = (uint8_t*)slMemory::malloc(image->m_dataSize);
fseek(file, 54, SEEK_SET);
fread(image->m_data, 1, image->m_dataSize, file);
flipPixel = true;
}
else if (imageInfo.m_bits == 32u)
{
imageInfo.m_pitch = imageInfo.m_width * 4;
uint32_t offset = header.bfOffBits;
if (info.bV5Compression == 3 || info.bV5Compression == 0) // BI_BITFIELDS
{
fseek(file, offset, SEEK_SET);
imageInfo.m_format = slImageFormat::r8g8b8a8;
image = slCreate<slImage>();
image->m_dataSize = imageInfo.m_pitch * imageInfo.m_height;
image->m_data = (uint8_t*)slMemory::malloc(image->m_dataSize);
fread(image->m_data, 1, image->m_dataSize, file);
image->FlipPixel();
}
else
{
slLog::PrintWarning("BMP: unsupported format\n");
fclose(file);
return 0;
}
}
else if (imageInfo.m_bits == 16u)
{
if (info.bV5Size != 40U && info.bV5Size != 56u)
{
slLog::PrintWarning("BMP: unsupported format\n");
fclose(file);
return 0;
}
imageInfo.m_pitch = imageInfo.m_width * 2;
if (info.bV5RedMask == 3840 &&
info.bV5GreenMask == 240 &&
info.bV5BlueMask == 15)
{
if (info.bV5AlphaMask)
{
imageInfo.m_format = slImageFormat::a4r4g4b4;
}
else
{
imageInfo.m_format = slImageFormat::x4r4g4b4;
}
}
else if (info.bV5RedMask == 63488 &&
info.bV5GreenMask == 2016 &&
info.bV5BlueMask == 31)
{
imageInfo.m_format = slImageFormat::r5g6b5;
}
else if (info.bV5RedMask == 31744 &&
info.bV5GreenMask == 992 &&
info.bV5BlueMask == 31)
{
if (info.bV5AlphaMask)
imageInfo.m_format = slImageFormat::a1r5g5b5;
}
else
{
imageInfo.m_format = slImageFormat::x1r5g5b5;
}
fseek(file, 70, SEEK_SET);
image = slCreate<slImage>();
image->m_dataSize = imageInfo.m_pitch * imageInfo.m_height;
image->m_data = (uint8_t*)slMemory::malloc(image->m_dataSize);
fread(image->m_data, 1, image->m_dataSize, file);
}
if (image)
{
image->m_info = imageInfo;
image->ConvertTo(slImageFormat::r8g8b8a8);
image->FlipVertical();
if (flipPixel)
image->FlipPixel();
}
return image;
}
Loading.
Add methods in slFramework (I also renamed LoadMesh into SummonMesh)
static uint32_t GetImageLoadersNum();
static slImageLoader* GetImageLoader(uint32_t);
static slImage* SummonImage(const char*);
Implementation
uint32_t slFramework::GetImageLoadersNum()
{
return (uint32_t)g_framework->m_imageLoaders.size();
}
slImageLoader* slFramework::GetImageLoader(uint32_t i)
{
SL_ASSERT_ST(i < g_framework->m_imageLoaders.size());
return g_framework->m_imageLoaders[i];
}
slImage* slFramework::SummonImage(const char* path)
{
slStringA stra;
std::filesystem::path p = path;
auto e = p.extension();
uint32_t mln = GetImageLoadersNum();
for (uint32_t i = 0; i < mln; ++i)
{
auto il = GetImageLoader(i);
auto sfc = il->GetSupportedFilesCount();
for (uint32_t o = 0; o < sfc; ++o)
{
slString sfe = il->GetSupportedFileExtension(o);
sfe.insert(U".", 0);
sfe.to_lower();
sfe.to_utf8(stra);
auto stre = lowercase(e.generic_string());
if (strcmp((const char*)stra.m_data, stre.c_str()) == 0)
{
return il->Load(path);
}
}
}
return NULL;
}
Add function and link lib
extern "C"
{
slGS* SL_CDECL slGSD3D11_create();
slMeshLoader* SL_CDECL slMeshLoaderOBJ_create();
slImageLoader* SL_CDECL slImageLoaderDefault_create(); //new
}
SL_LINK_LIBRARY("slowlib.d3d11");
SL_LINK_LIBRARY("slowlib.meshloader");
SL_LINK_LIBRARY("slowlib.imageloader"); //new
...
g_framework->m_imageLoaders.push_back(slImageLoaderDefault_create());
Texture
Add new abstract class and more other things
enum class slTextureType : uint32_t
{
Texture2D,
RTT
};
enum class slTextureComparisonFunc : uint32_t
{
Never,
Less,
Equal,
LessEqual,
Greater,
NotEqual,
GreaterEqual,
Always
};
enum class slTextureAddressMode : uint32_t
{
Wrap,
Mirror,
Clamp,
Border,
MirrorOnce
};
enum class slTextureFilter : uint32_t
{
// min mag mip / point linear
PPP,
PPL,
PLP,
PLL,
LPP,
LPL,
LLP,
LLL,
ANISOTROPIC,
// comparison
CMP_PPP,
CMP_PPL,
CMP_PLP,
CMP_PLL,
CMP_LPP,
CMP_LPL,
CMP_LLP,
CMP_LLL,
CMP_ANISOTROPIC,
};
struct slTextureInfo
{
slImageInfo m_info;
slTextureType m_type = slTextureType::Texture2D;
slTextureComparisonFunc m_cmpFnc = slTextureComparisonFunc::Always;
slTextureAddressMode m_adrMode = slTextureAddressMode::Wrap;
slTextureFilter m_filter = slTextureFilter::PPP;
uint32_t m_anisotropicLevel = 1;
};
class slTexture
{
protected:
slTextureInfo m_info;
public:
slTexture() {}
virtual ~slTexture() {}
const slTextureInfo& GetInfo() { return m_info; }
};
GPU texture
class slGSD3D11Texture : public slTexture
{
public:
slGSD3D11Texture();
virtual ~slGSD3D11Texture();
ID3D11Texture2D* m_texture = 0;
ID3D11ShaderResourceView* m_textureResView = 0;
ID3D11SamplerState* m_samplerState = 0;
ID3D11RenderTargetView* m_RTV = 0;
slTextureInfo m_textureInfo;
};
Destructor
slGSD3D11Texture::~slGSD3D11Texture()
{
SLD3DSAFE_RELEASE(m_RTV);
SLD3DSAFE_RELEASE(m_samplerState);
SLD3DSAFE_RELEASE(m_textureResView);
SLD3DSAFE_RELEASE(m_texture);
}
Texture creation. Add new method in GS
virtual slTexture* SummonTexture(slImage*, const slTextureInfo&) = 0;
Implementation
slTexture* slGSD3D11::SummonTexture(slImage* img, const slTextureInfo& inf)
{
SL_ASSERT_ST(img);
slGSD3D11Texture* newTexture = 0;
ID3D11Texture2D* _texture = 0;
ID3D11ShaderResourceView* _textureResView = 0;
ID3D11SamplerState* _samplerState = 0;
ID3D11RenderTargetView* _RTV = 0;
D3D11_FILTER filter;
slTextureFilter tf = inf.m_filter;
switch (tf)
{
case slTextureFilter::PPP:
filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_MIP_POINT;
break;
case slTextureFilter::PPL:
filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
break;
case slTextureFilter::PLP:
filter = D3D11_FILTER::D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
break;
case slTextureFilter::PLL:
filter = D3D11_FILTER::D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
break;
case slTextureFilter::LPP:
filter = D3D11_FILTER::D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
break;
case slTextureFilter::LPL:
filter = D3D11_FILTER::D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
break;
case slTextureFilter::LLP:
filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
break;
case slTextureFilter::LLL:
filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_MIP_LINEAR;
break;
case slTextureFilter::ANISOTROPIC:
filter = D3D11_FILTER::D3D11_FILTER_ANISOTROPIC;
break;
case slTextureFilter::CMP_PPP:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
break;
case slTextureFilter::CMP_PPL:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR;
break;
case slTextureFilter::CMP_PLP:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT;
break;
case slTextureFilter::CMP_PLL:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR;
break;
case slTextureFilter::CMP_LPP:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT;
break;
case slTextureFilter::CMP_LPL:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
break;
case slTextureFilter::CMP_LLP:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
break;
case slTextureFilter::CMP_LLL:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
break;
case slTextureFilter::CMP_ANISOTROPIC:
filter = D3D11_FILTER::D3D11_FILTER_COMPARISON_ANISOTROPIC;
break;
default:
break;
}
HRESULT hr = 0;
if (inf.m_type == slTextureType::Texture2D)
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = img->m_info.m_width;
desc.Height = img->m_info.m_height;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
bool isGenMips = inf.m_generateMipmaps;
switch (img->m_info.m_format)
{
case slImageFormat::r8g8b8a8:
{
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
desc.MiscFlags = 0;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
if (isGenMips)
{
desc.MipLevels = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
hr = m_d3d11Device->CreateTexture2D(&desc, 0, &_texture);
if (FAILED(hr))
{
slLog::PrintError("Can't create 2D texture\n");
goto fail;
}
m_d3d11DevCon->UpdateSubresource(_texture, 0, NULL, img->m_data, img->m_info.m_pitch, 0);
}
else
{
D3D11_SUBRESOURCE_DATA initData;
ZeroMemory(&initData, sizeof(initData));
initData.pSysMem = img->m_data;
initData.SysMemPitch = img->m_info.m_pitch;
initData.SysMemSlicePitch = img->m_dataSize;
hr = m_d3d11Device->CreateTexture2D(&desc, &initData, &_texture);
if (FAILED(hr))
{
slLog::PrintError("Can't create 2D texture\n");
goto fail;
}
}
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory(&SRVDesc, sizeof(SRVDesc));
SRVDesc.Format = desc.Format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MostDetailedMip = 0;
SRVDesc.Texture2D.MipLevels = 1;
if (isGenMips)
SRVDesc.Texture2D.MipLevels = -1;
hr = m_d3d11Device->CreateShaderResourceView(_texture,
&SRVDesc, &_textureResView);
if (FAILED(hr))
{
slLog::PrintError("Can't create shader resource view\n");
goto fail;
}
}break;
default:
slLog::PrintError("Unsupported texture format\n");
goto fail;
}
if (isGenMips)
m_d3d11DevCon->GenerateMips(_textureResView);
}
else
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = img->m_info.m_width;
desc.Height = img->m_info.m_height;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
desc.MiscFlags = 0;
desc.ArraySize = 1;
desc.MipLevels = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
hr = m_d3d11Device->CreateTexture2D(&desc, NULL, &_texture);
if (FAILED(hr))
{
slLog::PrintError("Can't create render target texture\n");
goto fail;
}
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
renderTargetViewDesc.Format = desc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
hr = m_d3d11Device->CreateRenderTargetView(_texture, &renderTargetViewDesc, &_RTV);
if (FAILED(hr))
{
slLog::PrintError("Can't create render target view\n");
goto fail;
}
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory(&SRVDesc, sizeof(SRVDesc));
SRVDesc.Format = desc.Format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MostDetailedMip = 0;
SRVDesc.Texture2D.MipLevels = 1;
hr = m_d3d11Device->CreateShaderResourceView(_texture,
&SRVDesc, &_textureResView);
if (FAILED(hr))
{
slLog::PrintError("Can't create shader resource view\n");
goto fail;
}
//goto success;
}
D3D11_TEXTURE_ADDRESS_MODE tam;
switch (inf.m_adrMode)
{
case slTextureAddressMode::Wrap:
default:
tam = D3D11_TEXTURE_ADDRESS_WRAP;
break;
case slTextureAddressMode::Mirror:
tam = D3D11_TEXTURE_ADDRESS_MIRROR;
break;
case slTextureAddressMode::Clamp:
tam = D3D11_TEXTURE_ADDRESS_CLAMP;
break;
case slTextureAddressMode::Border:
tam = D3D11_TEXTURE_ADDRESS_BORDER;
break;
case slTextureAddressMode::MirrorOnce:
tam = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
break;
}
D3D11_COMPARISON_FUNC cmpFunc;
switch (inf.m_cmpFnc)
{
case slTextureComparisonFunc::Never:
cmpFunc = D3D11_COMPARISON_NEVER;
break;
case slTextureComparisonFunc::Less:
cmpFunc = D3D11_COMPARISON_LESS;
break;
case slTextureComparisonFunc::Equal:
cmpFunc = D3D11_COMPARISON_EQUAL;
break;
case slTextureComparisonFunc::LessEqual:
cmpFunc = D3D11_COMPARISON_LESS_EQUAL;
break;
case slTextureComparisonFunc::Greater:
cmpFunc = D3D11_COMPARISON_GREATER;
break;
case slTextureComparisonFunc::NotEqual:
cmpFunc = D3D11_COMPARISON_NOT_EQUAL;
break;
case slTextureComparisonFunc::GreaterEqual:
cmpFunc = D3D11_COMPARISON_GREATER_EQUAL;
break;
case slTextureComparisonFunc::Always:
default:
cmpFunc = D3D11_COMPARISON_ALWAYS;
break;
}
hr = createSamplerState(filter, tam, inf.m_anisotropicLevel,
&_samplerState, cmpFunc);
if (FAILED(hr))
{
slLog::PrintError("Can't create sampler state\n");
goto fail;
}
newTexture = slCreate<slGSD3D11Texture>();
newTexture->m_RTV = _RTV;
newTexture->m_samplerState = _samplerState;
newTexture->m_textureResView = _textureResView;
newTexture->m_texture = _texture;
newTexture->m_textureInfo = inf;
newTexture->m_textureInfo.m_imageInfo = img->m_info;
return newTexture;
fail:;
SLD3DSAFE_RELEASE(_RTV);
SLD3DSAFE_RELEASE(_samplerState);
SLD3DSAFE_RELEASE(_textureResView);
SLD3DSAFE_RELEASE(_texture);
return NULL;
}
I don't want to think a lot so just use goto.
And there is also Render Target Texture
slGSD3D11::createSamplerState
HRESULT slGSD3D11::createSamplerState(D3D11_FILTER filter,
D3D11_TEXTURE_ADDRESS_MODE addressMode,
uint32_t anisotropic_level,
ID3D11SamplerState** samplerState,
D3D11_COMPARISON_FUNC cmpFunc)
{
D3D11_SAMPLER_DESC samplerDesc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
samplerDesc.Filter = filter;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.AddressU = addressMode;
samplerDesc.AddressV = addressMode;
samplerDesc.AddressW = addressMode;
samplerDesc.ComparisonFunc = cmpFunc; //D3D11_COMPARISON_ALWAYS;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
samplerDesc.MaxAnisotropy = anisotropic_level;
return m_d3d11Device->CreateSamplerState(&samplerDesc, samplerState);
}
Using in shader
"Texture2D tex2d_1;\n"
"SamplerState tex2D_sampler_1;\n"
...
" output.color = tex2d_1.Sample(tex2D_sampler_1, input.uv) * BaseColor;\n"
if (material->m_maps[0].m_texture)
{
slGSD3D11Texture* _t = (slGSD3D11Texture*)material->m_maps[0].m_texture;
m_gs->m_d3d11DevCon->PSSetShaderResources(0, 1, &_t->m_textureResView);
m_gs->m_d3d11DevCon->PSSetSamplers(0, 1, &_t->m_samplerState);
}
Using in app. Modify class from previous article
bool Load(const char* p)
{
m_cb.m_model = this;
slFramework::SummonMesh(p, &m_cb);
slImage* image = slFramework::SummonImage("D:\\moon_64.bmp");
if (image)
{
printf("Image %ix%i\n", image->m_info.m_width, image->m_info.m_height);
slTextureInfo ti;
m_texture = m_gs->SummonTexture(image, ti);
m_material.m_maps[0].m_texture = m_texture;
slDestroy(image);
}
return m_meshBuffers.m_size > 0;
}
void Draw(slCamera* camera)
{
m_WVP = camera->m_projectionMatrix * camera->m_viewMatrix * m_W;
m_material.m_sunPosition.set(0.f, 1.f, 0.f);
slFramework::SetMatrix(slMatrixType::World, &m_W);
slFramework::SetMatrix(slMatrixType::WorldViewProjection, &m_WVP);
for (size_t i = 0; i < m_meshBuffers.m_size; ++i)
{
m_gs->SetMesh(m_meshBuffers.m_data[i]);
m_gs->SetMaterial(&m_material);
m_gs->Draw();
}
}
Download
|
|