mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-24 16:48:18 -05:00
Support for Cube and Volume textures.
This commit is contained in:
parent
20e65aee2f
commit
fe1252d260
10 changed files with 685 additions and 287 deletions
|
@ -74,6 +74,8 @@ namespace bgfx
|
|||
#define BGFX_STATE_SRGBWRITE UINT64_C(0x0010000000000000)
|
||||
#define BGFX_STATE_MSAA UINT64_C(0x0020000000000000)
|
||||
|
||||
#define BGFX_STATE_RESERVED UINT64_C(0xff00000000000000)
|
||||
|
||||
#define BGFX_STATE_NONE UINT64_C(0x0000000000000000)
|
||||
#define BGFX_STATE_MASK UINT64_C(0xffffffffffffffff)
|
||||
#define BGFX_STATE_DEFAULT (0 \
|
||||
|
@ -107,16 +109,21 @@ namespace bgfx
|
|||
#define BGFX_TEXTURE_V_CLAMP UINT32_C(0x00000020)
|
||||
#define BGFX_TEXTURE_V_SHIFT 4
|
||||
#define BGFX_TEXTURE_V_MASK UINT32_C(0x00000030)
|
||||
#define BGFX_TEXTURE_MIN_POINT UINT32_C(0x00000100)
|
||||
#define BGFX_TEXTURE_W_REPEAT UINT32_C(0x00000000)
|
||||
#define BGFX_TEXTURE_W_MIRROR UINT32_C(0x00000100)
|
||||
#define BGFX_TEXTURE_W_CLAMP UINT32_C(0x00000200)
|
||||
#define BGFX_TEXTURE_W_SHIFT 4
|
||||
#define BGFX_TEXTURE_W_MASK UINT32_C(0x00000300)
|
||||
#define BGFX_TEXTURE_MIN_POINT UINT32_C(0x00001000)
|
||||
#define BGFX_TEXTURE_MIN_SHIFT 8
|
||||
#define BGFX_TEXTURE_MIN_MASK UINT32_C(0x00000100)
|
||||
#define BGFX_TEXTURE_MAG_POINT UINT32_C(0x00001000)
|
||||
#define BGFX_TEXTURE_MIN_MASK UINT32_C(0x00001000)
|
||||
#define BGFX_TEXTURE_MAG_POINT UINT32_C(0x00010000)
|
||||
#define BGFX_TEXTURE_MAG_SHIFT 12
|
||||
#define BGFX_TEXTURE_MAG_MASK UINT32_C(0x00001000)
|
||||
#define BGFX_TEXTURE_MIP_POINT UINT32_C(0x00010000)
|
||||
#define BGFX_TEXTURE_MAG_MASK UINT32_C(0x00010000)
|
||||
#define BGFX_TEXTURE_MIP_POINT UINT32_C(0x00100000)
|
||||
#define BGFX_TEXTURE_MIP_SHIFT 16
|
||||
#define BGFX_TEXTURE_MIP_MASK UINT32_C(0x00010000)
|
||||
#define BGFX_TEXTURE_SRGB UINT32_C(0x00020000)
|
||||
#define BGFX_TEXTURE_MIP_MASK UINT32_C(0x00100000)
|
||||
#define BGFX_TEXTURE_SRGB UINT32_C(0x00200000)
|
||||
|
||||
#define BGFX_RENDER_TARGET_NONE UINT32_C(0x00000000)
|
||||
#define BGFX_RENDER_TARGET_COLOR_RGBA UINT32_C(0x00000001)
|
||||
|
@ -157,6 +164,7 @@ namespace bgfx
|
|||
D3D9_UnableToCreateInterface,
|
||||
D3D9_UnableToCreateDevice,
|
||||
D3D9_UnableToCreateRenderTarget,
|
||||
D3D9_UnableToCreateTexture,
|
||||
OPENGL_UnableToCreateContext,
|
||||
};
|
||||
};
|
||||
|
|
13
src/bgfx_p.h
13
src/bgfx_p.h
|
@ -98,10 +98,13 @@ namespace std { namespace tr1 {} using namespace tr1; } // namespace std
|
|||
#define BGFX_STATE_TEX2 UINT64_C(0x0400000000000000)
|
||||
#define BGFX_STATE_TEX3 UINT64_C(0x0800000000000000)
|
||||
#define BGFX_STATE_TEX4 UINT64_C(0x1000000000000000)
|
||||
#define BGFX_STATE_TEX_MASK UINT64_C(0x1f00000000000000)
|
||||
#define BGFX_STATE_TEX_COUNT 5
|
||||
#define BGFX_STATE_TEX5 UINT64_C(0x2000000000000000)
|
||||
#define BGFX_STATE_TEX6 UINT64_C(0x4000000000000000)
|
||||
#define BGFX_STATE_TEX7 UINT64_C(0x8000000000000000)
|
||||
#define BGFX_STATE_TEX_MASK UINT64_C(0xff00000000000000)
|
||||
#define BGFX_STATE_TEX_COUNT 8
|
||||
|
||||
#define BGFX_SAMPLER_NONE UINT16_C(0x0000)
|
||||
#define BGFX_SAMPLER_TEXTURE UINT16_C(0x0000)
|
||||
#define BGFX_SAMPLER_RENDERTARGET_COLOR UINT16_C(0x0001)
|
||||
#define BGFX_SAMPLER_RENDERTARGET_DEPTH UINT16_C(0x0002)
|
||||
#define BGFX_SAMPLER_TYPE_MASK UINT16_C(0x0003)
|
||||
|
@ -843,7 +846,7 @@ namespace bgfx
|
|||
for (uint32_t ii = 0; ii < BGFX_STATE_TEX_COUNT; ++ii)
|
||||
{
|
||||
m_sampler[ii].m_idx = bgfx::invalidHandle;
|
||||
m_sampler[ii].m_flags = BGFX_SAMPLER_NONE;
|
||||
m_sampler[ii].m_flags = BGFX_SAMPLER_TEXTURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1037,7 +1040,7 @@ namespace bgfx
|
|||
m_flags |= BGFX_STATE_TEX0<<_stage;
|
||||
Sampler& sampler = m_state.m_sampler[_stage];
|
||||
sampler.m_idx = _handle.idx;
|
||||
sampler.m_flags = BGFX_SAMPLER_NONE;
|
||||
sampler.m_flags = BGFX_SAMPLER_TEXTURE;
|
||||
|
||||
if (bgfx::invalidHandle != _sampler.idx)
|
||||
{
|
||||
|
|
130
src/dds.cpp
130
src/dds.cpp
|
@ -19,6 +19,8 @@ namespace bgfx
|
|||
#define DDS_DXT4 MAKEFOURCC('D', 'X', 'T', '4')
|
||||
#define DDS_DXT5 MAKEFOURCC('D', 'X', 'T', '5')
|
||||
|
||||
#define D3DFMT_A16B16G16R16F 113
|
||||
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
|
@ -47,6 +49,11 @@ namespace bgfx
|
|||
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
|
||||
|
||||
#define DDS_CUBEMAP_ALLFACES (DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX \
|
||||
|DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY \
|
||||
|DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ)
|
||||
|
||||
#define DDSCAPS2_VOLUME 0x00200000
|
||||
|
||||
bool isDds(const Memory* _mem)
|
||||
|
@ -216,7 +223,7 @@ void Mip::decode(uint8_t* _dst)
|
|||
{
|
||||
const uint8_t* src = m_data;
|
||||
|
||||
if (0 != m_type)
|
||||
if (TextureFormat::Unknown > m_type)
|
||||
{
|
||||
uint32_t width = m_width/4;
|
||||
uint32_t height = m_height/4;
|
||||
|
@ -226,7 +233,7 @@ void Mip::decode(uint8_t* _dst)
|
|||
|
||||
switch (m_type)
|
||||
{
|
||||
case 1:
|
||||
case TextureFormat::Dxt1:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
|
@ -243,7 +250,7 @@ void Mip::decode(uint8_t* _dst)
|
|||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case TextureFormat::Dxt3:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
|
@ -262,7 +269,7 @@ void Mip::decode(uint8_t* _dst)
|
|||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case TextureFormat::Dxt5:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
|
@ -288,7 +295,8 @@ void Mip::decode(uint8_t* _dst)
|
|||
uint32_t height = m_height;
|
||||
|
||||
if (m_bpp == 1
|
||||
|| m_bpp == 4)
|
||||
|| m_bpp == 4
|
||||
|| m_bpp == 8)
|
||||
{
|
||||
uint32_t pitch = m_width*m_bpp;
|
||||
memcpy(_dst, src, pitch*height);
|
||||
|
@ -388,11 +396,21 @@ bool parseDds(Dds& _dds, const Memory* _mem)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool cubeMap = 0 != (caps[1] & DDSCAPS2_CUBEMAP);
|
||||
if (cubeMap)
|
||||
{
|
||||
if ( (caps[1] & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
|
||||
{
|
||||
// parital cube map is not supported.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
stream.skip(4); // reserved
|
||||
|
||||
uint8_t bpp = 1;
|
||||
uint8_t blockSize = 1;
|
||||
uint8_t type = 0;
|
||||
TextureFormat::Enum type = TextureFormat::Unknown;
|
||||
bool hasAlpha = pixelFlags & DDPF_ALPHAPIXELS;
|
||||
|
||||
if (pixelFlags & DDPF_FOURCC)
|
||||
|
@ -400,21 +418,27 @@ bool parseDds(Dds& _dds, const Memory* _mem)
|
|||
switch (fourcc)
|
||||
{
|
||||
case DDS_DXT1:
|
||||
type = 1;
|
||||
type = TextureFormat::Dxt1;
|
||||
blockSize = 8;
|
||||
break;
|
||||
|
||||
case DDS_DXT2:
|
||||
case DDS_DXT3:
|
||||
type = 2;
|
||||
type = TextureFormat::Dxt3;
|
||||
blockSize = 16;
|
||||
break;
|
||||
|
||||
case DDS_DXT4:
|
||||
case DDS_DXT5:
|
||||
type = 3;
|
||||
type = TextureFormat::Dxt5;
|
||||
blockSize = 16;
|
||||
break;
|
||||
|
||||
case D3DFMT_A16B16G16R16F:
|
||||
type = TextureFormat::ABGR16;
|
||||
blockSize = 8;
|
||||
bpp = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -422,82 +446,98 @@ bool parseDds(Dds& _dds, const Memory* _mem)
|
|||
switch (pixelFlags)
|
||||
{
|
||||
case DDPF_RGB:
|
||||
blockSize *= 3;
|
||||
type = TextureFormat::XRGB8;
|
||||
blockSize = 3;
|
||||
bpp = 3;
|
||||
break;
|
||||
|
||||
case DDPF_RGB|DDPF_ALPHAPIXELS:
|
||||
blockSize *= 4;
|
||||
type = TextureFormat::ARGB8;
|
||||
blockSize = 4;
|
||||
bpp = 4;
|
||||
break;
|
||||
|
||||
case DDPF_LUMINANCE:
|
||||
case DDPF_INDEXED:
|
||||
case DDPF_LUMINANCE:
|
||||
case DDPF_ALPHA:
|
||||
type = TextureFormat::L8;
|
||||
bpp = 1;
|
||||
break;
|
||||
|
||||
// type = TextureFormat::A8;
|
||||
// bpp = 1;
|
||||
// break;
|
||||
|
||||
default:
|
||||
bpp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_dds.m_type = type;
|
||||
_dds.m_width = width;
|
||||
_dds.m_height = height;
|
||||
_dds.m_depth = depth;
|
||||
_dds.m_blockSize = blockSize;
|
||||
_dds.m_numMips = (caps[0] & DDSCAPS_MIPMAP) ? mips : 1;
|
||||
_dds.m_bpp = bpp;
|
||||
_dds.m_type = type;
|
||||
_dds.m_hasAlpha = hasAlpha;
|
||||
_dds.m_cubeMap = cubeMap;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getRawImageData(const Dds& _dds, uint8_t _index, const Memory* _mem, Mip& _mip)
|
||||
bool getRawImageData(const Dds& _dds, uint8_t _side, uint8_t _lod, const Memory* _mem, Mip& _mip)
|
||||
{
|
||||
uint32_t width = _dds.m_width;
|
||||
uint32_t height = _dds.m_height;
|
||||
uint32_t blockSize = _dds.m_blockSize;
|
||||
uint32_t offset = DDS_IMAGE_DATA_OFFSET;
|
||||
uint8_t bpp = _dds.m_bpp;
|
||||
uint8_t type = _dds.m_type;
|
||||
TextureFormat::Enum type = _dds.m_type;
|
||||
bool hasAlpha = _dds.m_hasAlpha;
|
||||
|
||||
for (uint8_t ii = 0, num = _dds.m_numMips; ii < num; ++ii)
|
||||
for (uint8_t side = 0, numSides = _dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
uint32_t width = _dds.m_width;
|
||||
uint32_t height = _dds.m_height;
|
||||
uint32_t depth = _dds.m_depth;
|
||||
|
||||
uint32_t size = width*height*blockSize;
|
||||
if (0 != type)
|
||||
for (uint8_t lod = 0, num = _dds.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
width = uint32_max(1, (width + 3)>>2);
|
||||
height = uint32_max(1, (height + 3)>>2);
|
||||
size = width*height*blockSize;
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
depth = uint32_max(1, depth);
|
||||
|
||||
width <<= 2;
|
||||
height <<= 2;
|
||||
uint32_t size = width*height*depth*blockSize;
|
||||
if (TextureFormat::Unknown > type)
|
||||
{
|
||||
width = uint32_max(1, (width + 3)>>2);
|
||||
height = uint32_max(1, (height + 3)>>2);
|
||||
size = width*height*depth*blockSize;
|
||||
|
||||
width <<= 2;
|
||||
height <<= 2;
|
||||
}
|
||||
|
||||
if (side == _side
|
||||
&& lod == _lod)
|
||||
{
|
||||
_mip.m_width = width;
|
||||
_mip.m_height = height;
|
||||
_mip.m_blockSize = blockSize;
|
||||
_mip.m_size = size;
|
||||
_mip.m_data = _mem->data + offset;
|
||||
_mip.m_bpp = bpp;
|
||||
_mip.m_type = type;
|
||||
_mip.m_hasAlpha = hasAlpha;
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += size;
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
|
||||
if (ii == _index)
|
||||
{
|
||||
_mip.m_width = width;
|
||||
_mip.m_height = height;
|
||||
_mip.m_blockSize = blockSize;
|
||||
_mip.m_size = size;
|
||||
_mip.m_data = _mem->data + offset;
|
||||
_mip.m_bpp = bpp;
|
||||
_mip.m_type = type;
|
||||
_mip.m_hasAlpha = hasAlpha;
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += size;
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
22
src/dds.h
22
src/dds.h
|
@ -10,16 +10,34 @@
|
|||
|
||||
namespace bgfx
|
||||
{
|
||||
struct TextureFormat
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Dxt1,
|
||||
Dxt3,
|
||||
Dxt5,
|
||||
Unknown, // compressed formats are above
|
||||
L8,
|
||||
XRGB8,
|
||||
ARGB8,
|
||||
ABGR16,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct Dds
|
||||
{
|
||||
TextureFormat::Enum m_type;
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
uint32_t m_depth;
|
||||
uint8_t m_blockSize;
|
||||
uint8_t m_numMips;
|
||||
uint8_t m_bpp;
|
||||
uint8_t m_type;
|
||||
bool m_hasAlpha;
|
||||
bool m_cubeMap;
|
||||
};
|
||||
|
||||
struct Mip
|
||||
|
@ -39,7 +57,7 @@ namespace bgfx
|
|||
|
||||
bool isDds(const Memory* _mem);
|
||||
bool parseDds(Dds& _dds, const Memory* _mem);
|
||||
bool getRawImageData(const Dds& _dds, uint8_t _index, const Memory* _mem, Mip& _mip);
|
||||
bool getRawImageData(const Dds& _dds, uint8_t _side, uint8_t _index, const Memory* _mem, Mip& _mip);
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
|
|
|
@ -11,6 +11,34 @@
|
|||
// OpenGL 2.1 Reference Pages
|
||||
// http://www.opengl.org/sdk/docs/man/
|
||||
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
GL_IMPORT(false, PFNGLGETERRORPROC, glGetError);
|
||||
GL_IMPORT(false, PFNGLREADPIXELSPROC, glReadPixels);
|
||||
GL_IMPORT(false, PFNGLTEXIMAGE2DPROC, glTexImage2D);
|
||||
GL_IMPORT(false, PFNGLTEXPARAMETERIPROC, glTexParameteri);
|
||||
GL_IMPORT(false, PFNGLBINDTEXTUREPROC, glBindTexture);
|
||||
GL_IMPORT(false, PFNGLGENTEXTURESPROC, glGenTextures);
|
||||
GL_IMPORT(false, PFNGLDELETETEXTURESPROC, glDeleteTextures);
|
||||
GL_IMPORT(false, PFNGLCOLORMASKPROC, glColorMask);
|
||||
GL_IMPORT(false, PFNGLDEPTHFUNCPROC, glDepthFunc);
|
||||
GL_IMPORT(false, PFNGLDISABLEPROC, glDisable);
|
||||
GL_IMPORT(false, PFNGLVIEWPORTPROC, glViewport);
|
||||
GL_IMPORT(false, PFNGLDRAWELEMENTSPROC, glDrawElements);
|
||||
GL_IMPORT(false, PFNGLGETINTEGERVPROC, glGetIntegerv);
|
||||
GL_IMPORT(false, PFNGLGETSTRINGPROC, glGetString);
|
||||
GL_IMPORT(false, PFNGLDRAWARRAYSPROC, glDrawArrays);
|
||||
GL_IMPORT(false, PFNGLBLENDFUNCPROC, glBlendFunc);
|
||||
GL_IMPORT(false, PFNGLPOINTSIZEPROC, glPointSize);
|
||||
GL_IMPORT(false, PFNGLCULLFACEPROC, glCullFace);
|
||||
GL_IMPORT(false, PFNGLCLEARPROC, glClear);
|
||||
GL_IMPORT(false, PFNGLSCISSORPROC, glScissor);
|
||||
GL_IMPORT(false, PFNGLENABLEPROC, glEnable);
|
||||
GL_IMPORT(false, PFNGLCLEARSTENCILPROC, glClearStencil);
|
||||
GL_IMPORT(false, PFNGLDEPTHMASKPROC, glDepthMask);
|
||||
GL_IMPORT(false, PFNGLCLEARDEPTHPROC, glClearDepth);
|
||||
GL_IMPORT(false, PFNGLCLEARCOLORPROC, glClearColor);
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
||||
GL_IMPORT(false, PFNGLACTIVETEXTUREPROC, glActiveTexture);
|
||||
GL_IMPORT(false, PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D);
|
||||
GL_IMPORT(false, PFNGLBINDBUFFERPROC, glBindBuffer);
|
||||
|
@ -61,6 +89,9 @@ GL_IMPORT(false, PFNGLUNIFORM3FVPROC, glUniform3fv);
|
|||
GL_IMPORT(false, PFNGLUNIFORM4FVPROC, glUniform4fv);
|
||||
GL_IMPORT(false, PFNGLUNIFORMMATRIX3FVPROC, glUniformMatrix3fv);
|
||||
GL_IMPORT(false, PFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv);
|
||||
GL_IMPORT(false, PFNGLTEXIMAGE3DPROC, glTexImage3D);
|
||||
GL_IMPORT(false, PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D);
|
||||
GL_IMPORT(false, PFNGLCOPYTEXSUBIMAGE3DPROC, glCopyTexSubImage3D);
|
||||
|
||||
GL_IMPORT(false, PFNGLGENQUERIESPROC, glGenQueries);
|
||||
GL_IMPORT(false, PFNGLDELETEQUERIESPROC, glDeleteQueries);
|
||||
|
|
|
@ -114,6 +114,24 @@ namespace bgfx
|
|||
D3DTEXF_ANISOTROPIC,
|
||||
};
|
||||
|
||||
struct TextureFormatInfo
|
||||
{
|
||||
D3DFORMAT m_fmt;
|
||||
uint8_t m_bpp;
|
||||
};
|
||||
|
||||
static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
|
||||
{
|
||||
{ D3DFMT_DXT1, 1 },
|
||||
{ D3DFMT_DXT3, 1 },
|
||||
{ D3DFMT_DXT5, 1 },
|
||||
{ D3DFMT_UNKNOWN, 0 },
|
||||
{ D3DFMT_L8, 1 },
|
||||
{ D3DFMT_X8R8G8B8, 4 },
|
||||
{ D3DFMT_A8R8G8B8, 4 },
|
||||
{ D3DFMT_A16B16G16R16, 8 },
|
||||
};
|
||||
|
||||
struct RendererContext
|
||||
{
|
||||
RendererContext()
|
||||
|
@ -972,11 +990,146 @@ namespace bgfx
|
|||
DX_CHECK(s_renderCtx.m_device->CreateVertexShader(code, (IDirect3DVertexShader9**)&m_ptr) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Texture::createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips, D3DFORMAT _fmt)
|
||||
{
|
||||
m_type = Texture2D;
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture(_width
|
||||
, _height
|
||||
, _numMips
|
||||
, 0
|
||||
, _fmt
|
||||
, D3DPOOL_MANAGED
|
||||
, (IDirect3DTexture9**)&m_ptr
|
||||
, NULL
|
||||
) );
|
||||
|
||||
BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create texture (size: %dx%d, mips: %d, fmt: 0x%08x)."
|
||||
, _width
|
||||
, _height
|
||||
, _numMips
|
||||
, _fmt
|
||||
);
|
||||
}
|
||||
|
||||
void Texture::createVolumeTexture(uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _numMips, D3DFORMAT _fmt)
|
||||
{
|
||||
m_type = Texture3D;
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateVolumeTexture(_width
|
||||
, _height
|
||||
, _depth
|
||||
, _numMips
|
||||
, 0
|
||||
, _fmt
|
||||
, D3DPOOL_MANAGED
|
||||
, (IDirect3DVolumeTexture9**)&m_ptr
|
||||
, NULL
|
||||
) );
|
||||
|
||||
BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create volume texture (size: %dx%dx%d, mips: %d, fmt: 0x%08x)."
|
||||
, _width
|
||||
, _height
|
||||
, _depth
|
||||
, _numMips
|
||||
, _fmt
|
||||
);
|
||||
}
|
||||
|
||||
void Texture::createCubeTexture(uint32_t _edge, uint32_t _numMips, D3DFORMAT _fmt)
|
||||
{
|
||||
m_type = TextureCube;
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateCubeTexture(_edge
|
||||
, _numMips
|
||||
, 0
|
||||
, _fmt
|
||||
, D3DPOOL_MANAGED
|
||||
, (IDirect3DCubeTexture9**)&m_ptr
|
||||
, NULL
|
||||
) );
|
||||
|
||||
BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create cube texture (edge: %d, mips: %d, fmt: 0x%08x)."
|
||||
, _edge
|
||||
, _numMips
|
||||
, _fmt
|
||||
);
|
||||
}
|
||||
|
||||
uint8_t* Texture::lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Texture2D:
|
||||
{
|
||||
IDirect3DTexture9* texture = (IDirect3DTexture9*)m_ptr;
|
||||
D3DLOCKED_RECT rect;
|
||||
DX_CHECK(texture->LockRect(_lod, &rect, NULL, 0) );
|
||||
_pitch = rect.Pitch;
|
||||
_slicePitch = 0;
|
||||
return (uint8_t*)rect.pBits;
|
||||
}
|
||||
|
||||
case Texture3D:
|
||||
{
|
||||
IDirect3DVolumeTexture9* texture = (IDirect3DVolumeTexture9*)m_ptr;
|
||||
D3DLOCKED_BOX box;
|
||||
DX_CHECK(texture->LockBox(_lod, &box, NULL, 0) );
|
||||
_pitch = box.RowPitch;
|
||||
_slicePitch = box.SlicePitch;
|
||||
return (uint8_t*)box.pBits;
|
||||
}
|
||||
|
||||
case TextureCube:
|
||||
{
|
||||
IDirect3DCubeTexture9* texture = (IDirect3DCubeTexture9*)m_ptr;
|
||||
D3DLOCKED_RECT rect;
|
||||
DX_CHECK(texture->LockRect(D3DCUBEMAP_FACES(_side), _lod, &rect, NULL, 0) );
|
||||
_pitch = rect.Pitch;
|
||||
_slicePitch = 0;
|
||||
return (uint8_t*)rect.pBits;
|
||||
}
|
||||
}
|
||||
|
||||
BX_CHECK(false, "You should not be here.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Texture::unlock(uint8_t _side, uint8_t _lod)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Texture2D:
|
||||
{
|
||||
IDirect3DTexture9* texture = (IDirect3DTexture9*)m_ptr;
|
||||
DX_CHECK(texture->UnlockRect(_lod) );
|
||||
}
|
||||
return;
|
||||
|
||||
case Texture3D:
|
||||
{
|
||||
IDirect3DVolumeTexture9* texture = (IDirect3DVolumeTexture9*)m_ptr;
|
||||
DX_CHECK(texture->UnlockBox(_lod) );
|
||||
}
|
||||
return;
|
||||
|
||||
case TextureCube:
|
||||
{
|
||||
IDirect3DCubeTexture9* texture = (IDirect3DCubeTexture9*)m_ptr;
|
||||
DX_CHECK(texture->UnlockRect(D3DCUBEMAP_FACES(_side), _lod) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BX_CHECK(false, "You should not be here.");
|
||||
}
|
||||
|
||||
void Texture::create(const Memory* _mem, uint32_t _flags)
|
||||
{
|
||||
m_tau = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
|
||||
m_tav = s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT];
|
||||
m_taw = s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT];
|
||||
m_minFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
|
||||
m_magFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
|
||||
m_mipFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT];
|
||||
|
@ -986,112 +1139,93 @@ namespace bgfx
|
|||
|
||||
if (parseDds(dds, _mem) )
|
||||
{
|
||||
D3DFORMAT typefmt[4] =
|
||||
{
|
||||
D3DFMT_X8R8G8B8,
|
||||
D3DFMT_DXT1,
|
||||
D3DFMT_DXT3,
|
||||
D3DFMT_DXT5,
|
||||
};
|
||||
|
||||
D3DFORMAT fmt = typefmt[dds.m_type];
|
||||
|
||||
bool decompress = false;
|
||||
uint8_t bpp = dds.m_bpp;
|
||||
|
||||
if (0 == dds.m_type)
|
||||
bool decompress = false;
|
||||
|
||||
if (dds.m_cubeMap)
|
||||
{
|
||||
switch (dds.m_bpp)
|
||||
{
|
||||
case 1:
|
||||
fmt = D3DFMT_L8;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fmt = D3DFMT_A8R8G8B8;
|
||||
break;
|
||||
|
||||
default:
|
||||
fmt = D3DFMT_X8R8G8B8;
|
||||
break;
|
||||
}
|
||||
createCubeTexture(dds.m_width, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
|
||||
}
|
||||
else if (decompress)
|
||||
else if (dds.m_depth > 1)
|
||||
{
|
||||
fmt = D3DFMT_A8R8G8B8;
|
||||
bpp = 4;
|
||||
createVolumeTexture(dds.m_width, dds.m_height, dds.m_depth, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
createTexture(dds.m_width, dds.m_height, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
|
||||
}
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture(dds.m_width
|
||||
, dds.m_height
|
||||
, dds.m_numMips
|
||||
, 0
|
||||
, fmt
|
||||
, D3DPOOL_MANAGED
|
||||
, &m_ptr
|
||||
, NULL
|
||||
) );
|
||||
|
||||
if (decompress
|
||||
|| 0 == dds.m_type)
|
||||
|| TextureFormat::Unknown < dds.m_type)
|
||||
{
|
||||
uint32_t width = dds.m_width;
|
||||
uint32_t height = dds.m_height;
|
||||
|
||||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
uint32_t width = dds.m_width;
|
||||
uint32_t height = dds.m_height;
|
||||
uint32_t depth = dds.m_depth;
|
||||
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, lod, _mem, mip) )
|
||||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
D3DLOCKED_RECT rect;
|
||||
DX_CHECK(m_ptr->LockRect(lod, &rect, NULL, 0) );
|
||||
uint8_t* bits = (uint8_t*)rect.pBits;
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
depth = uint32_max(1, depth);
|
||||
|
||||
if (width != mip.m_width
|
||||
|| height != mip.m_height)
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, side, lod, _mem, mip) )
|
||||
{
|
||||
uint32_t srcpitch = mip.m_width*bpp;
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* bits = lock(side, lod, pitch, slicePitch);
|
||||
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mip.m_height);
|
||||
mip.decode(temp);
|
||||
|
||||
uint32_t dstpitch = rect.Pitch;
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
if (width != mip.m_width
|
||||
|| height != mip.m_height)
|
||||
{
|
||||
uint8_t* src = &temp[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
memcpy(dst, src, srcpitch);
|
||||
uint32_t srcpitch = mip.m_width*bpp;
|
||||
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mip.m_height);
|
||||
mip.decode(temp);
|
||||
|
||||
uint32_t dstpitch = pitch;
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
uint8_t* src = &temp[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
memcpy(dst, src, srcpitch);
|
||||
}
|
||||
|
||||
g_free(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mip.decode(bits);
|
||||
}
|
||||
|
||||
g_free(temp);
|
||||
unlock(side, lod);
|
||||
}
|
||||
else
|
||||
{
|
||||
mip.decode(bits);
|
||||
}
|
||||
|
||||
DX_CHECK(m_ptr->UnlockRect(lod) );
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t ii = 0, num = dds.m_numMips; ii < num; ++ii)
|
||||
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, ii, _mem, mip) )
|
||||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
D3DLOCKED_RECT rect;
|
||||
DX_CHECK(m_ptr->LockRect(ii, &rect, NULL, 0) );
|
||||
uint8_t* dst = (uint8_t*)rect.pBits;
|
||||
memcpy(dst, mip.m_data, mip.m_size);
|
||||
DX_CHECK(m_ptr->UnlockRect(ii) );
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, 0, lod, _mem, mip) )
|
||||
{
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* dst = lock(side, lod, pitch, slicePitch);
|
||||
|
||||
memcpy(dst, mip.m_data, mip.m_size);
|
||||
|
||||
unlock(side, lod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1119,26 +1253,20 @@ namespace bgfx
|
|||
|
||||
stream.align(16);
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture(width
|
||||
, height
|
||||
, numMips
|
||||
, 0
|
||||
, 1 == bpp ? D3DFMT_L8 : D3DFMT_A8R8G8B8
|
||||
, D3DPOOL_MANAGED
|
||||
, &m_ptr
|
||||
, NULL
|
||||
) );
|
||||
D3DFORMAT fmt = 1 == bpp ? D3DFMT_L8 : D3DFMT_A8R8G8B8;
|
||||
|
||||
createTexture(width, height, numMips, fmt);
|
||||
|
||||
for (uint8_t mip = 0; mip < numMips; ++mip)
|
||||
{
|
||||
width = uint32_max(width, 1);
|
||||
height = uint32_max(height, 1);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
DX_CHECK(m_ptr->LockRect(mip, &rect, NULL, 0) );
|
||||
uint8_t* dst = (uint8_t*)rect.pBits;
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* dst = lock(0, mip, pitch, slicePitch);
|
||||
stream.read(dst, width*height*bpp);
|
||||
DX_CHECK(m_ptr->UnlockRect(mip) );
|
||||
unlock(0, mip);
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
|
@ -1158,6 +1286,10 @@ namespace bgfx
|
|||
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, m_mipFilter) );
|
||||
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, m_tau) );
|
||||
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, m_tav) );
|
||||
if (m_type == Texture3D)
|
||||
{
|
||||
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSW, m_taw) );
|
||||
}
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, m_srgb) );
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
@ -1970,15 +2102,15 @@ namespace bgfx
|
|||
{
|
||||
switch (sampler.m_flags&BGFX_SAMPLER_TYPE_MASK)
|
||||
{
|
||||
case 0:
|
||||
case BGFX_SAMPLER_TEXTURE:
|
||||
s_renderCtx.m_textures[sampler.m_idx].commit(stage);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case BGFX_SAMPLER_RENDERTARGET_COLOR:
|
||||
s_renderCtx.m_renderTargets[sampler.m_idx].commit(stage);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case BGFX_SAMPLER_RENDERTARGET_DEPTH:
|
||||
// id = s_renderCtx.m_renderTargets[sampler.m_idx].m_depth.m_id;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -269,11 +269,25 @@ namespace bgfx
|
|||
|
||||
struct Texture
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Texture2D,
|
||||
Texture3D,
|
||||
TextureCube,
|
||||
};
|
||||
|
||||
Texture()
|
||||
: m_ptr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips, D3DFORMAT _fmt);
|
||||
void createVolumeTexture(uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _numMips, D3DFORMAT _fmt);
|
||||
void createCubeTexture(uint32_t _edge, uint32_t _numMips, D3DFORMAT _fmt);
|
||||
|
||||
uint8_t* lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch);
|
||||
void unlock(uint8_t _side, uint8_t _lod);
|
||||
|
||||
void create(const Memory* _mem, uint32_t _flags);
|
||||
|
||||
void destroy()
|
||||
|
@ -283,12 +297,14 @@ namespace bgfx
|
|||
|
||||
void commit(uint8_t _stage);
|
||||
|
||||
IDirect3DTexture9* m_ptr;
|
||||
IDirect3DBaseTexture9* m_ptr;
|
||||
D3DTEXTUREFILTERTYPE m_minFilter;
|
||||
D3DTEXTUREFILTERTYPE m_magFilter;
|
||||
D3DTEXTUREFILTERTYPE m_mipFilter;
|
||||
D3DTEXTUREADDRESS m_tau;
|
||||
D3DTEXTUREADDRESS m_tav;
|
||||
D3DTEXTUREADDRESS m_taw;
|
||||
Enum m_type;
|
||||
bool m_srgb;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
|
||||
namespace bgfx
|
||||
{
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
PFNWGLGETPROCADDRESSPROC wglGetProcAddress;
|
||||
PFNWGLMAKECURRENTPROC wglMakeCurrent;
|
||||
PFNWGLCREATECONTEXTPROC wglCreateContext;
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
||||
#define GL_IMPORT(_optional, _proto, _func) _proto _func
|
||||
#include "glimports.h"
|
||||
#undef GL_IMPORT
|
||||
|
@ -116,6 +122,18 @@ namespace bgfx
|
|||
#elif BX_PLATFORM_WINDOWS
|
||||
if (NULL == m_hdc)
|
||||
{
|
||||
m_opengl32dll = LoadLibrary("opengl32.dll");
|
||||
BGFX_FATAL(NULL != m_opengl32dll, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to load opengl32.dll.");
|
||||
|
||||
wglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(m_opengl32dll, "wglGetProcAddress");
|
||||
BGFX_FATAL(NULL != wglGetProcAddress, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed get wglGetProcAddress.");
|
||||
|
||||
wglMakeCurrent = (PFNWGLMAKECURRENTPROC)GetProcAddress(m_opengl32dll, "wglMakeCurrent");
|
||||
BGFX_FATAL(NULL != wglMakeCurrent, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed get wglMakeCurrent.");
|
||||
|
||||
wglCreateContext = (PFNWGLCREATECONTEXTPROC)GetProcAddress(m_opengl32dll, "wglCreateContext");
|
||||
BGFX_FATAL(NULL != wglCreateContext, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed get wglCreateContext.");
|
||||
|
||||
m_hdc = GetDC(g_bgfxHwnd);
|
||||
BGFX_FATAL(NULL != m_hdc, bgfx::Fatal::OPENGL_UnableToCreateContext, "GetDC failed!");
|
||||
|
||||
|
@ -148,6 +166,10 @@ namespace bgfx
|
|||
# define GL_IMPORT(_optional, _proto, _func) \
|
||||
{ \
|
||||
_func = (_proto)wglGetProcAddress(#_func); \
|
||||
if (_func == NULL) \
|
||||
{ \
|
||||
_func = (_proto)GetProcAddress(m_opengl32dll, #_func); \
|
||||
} \
|
||||
BGFX_FATAL(_optional || NULL != _func, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. wglGetProcAddress(\"%s\")", #_func); \
|
||||
}
|
||||
# include "glimports.h"
|
||||
|
@ -309,11 +331,6 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
|
||||
}
|
||||
|
||||
void saveScreenShot(Memory* _mem)
|
||||
{
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
@ -324,6 +341,18 @@ namespace bgfx
|
|||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
FreeLibrary(m_opengl32dll);
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
}
|
||||
|
||||
IndexBuffer m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
|
||||
VertexBuffer m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
|
||||
Shader m_vertexShaders[BGFX_CONFIG_MAX_VERTEX_SHADERS];
|
||||
|
@ -350,6 +379,7 @@ namespace bgfx
|
|||
const PPB_Instance* m_instInterface;
|
||||
const PPB_Graphics3D* m_graphicsInterface;
|
||||
#elif BX_PLATFORM_WINDOWS
|
||||
HMODULE m_opengl32dll;
|
||||
HGLRC m_context;
|
||||
HDC m_hdc;
|
||||
#elif BX_PLATFORM_LINUX
|
||||
|
@ -552,6 +582,30 @@ namespace bgfx
|
|||
GL_NEAREST,
|
||||
};
|
||||
|
||||
struct TextureFormatInfo
|
||||
{
|
||||
GLenum m_internalFmt;
|
||||
GLenum m_format;
|
||||
GLenum m_type;
|
||||
uint8_t m_bpp;
|
||||
};
|
||||
|
||||
static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
|
||||
{
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_ZERO, GL_ZERO, 1 },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_ZERO, GL_ZERO, 1 },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_ZERO, GL_ZERO, 1 },
|
||||
{ GL_ZERO, GL_ZERO, GL_ZERO, 0 },
|
||||
{ GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1 },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, 8 },
|
||||
#else
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 8 },
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
};
|
||||
|
||||
const char* glslTypeName(GLuint _type)
|
||||
{
|
||||
#define GLSL_TYPE(_ty) case _ty: return #_ty
|
||||
|
@ -915,125 +969,167 @@ namespace bgfx
|
|||
|
||||
void Texture::create(const Memory* _mem, uint32_t _flags)
|
||||
{
|
||||
m_target = GL_TEXTURE_2D;
|
||||
|
||||
GL_CHECK(glGenTextures(1, &m_id) );
|
||||
BX_CHECK(0 != m_id, "Failed to generate texture id.");
|
||||
GL_CHECK(glBindTexture(m_target, m_id) );
|
||||
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]) );
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]) );
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT]) );
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT]) );
|
||||
|
||||
Dds dds;
|
||||
|
||||
if (parseDds(dds, _mem) )
|
||||
{
|
||||
GLenum typefmt[4] =
|
||||
if (dds.m_cubeMap)
|
||||
{
|
||||
GL_RGBA,
|
||||
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
|
||||
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
|
||||
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
|
||||
};
|
||||
m_target = GL_TEXTURE_CUBE_MAP;
|
||||
}
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
else if (dds.m_depth > 1)
|
||||
{
|
||||
m_target = GL_TEXTURE_3D;
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
else
|
||||
{
|
||||
m_target = GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
GL_CHECK(glGenTextures(1, &m_id) );
|
||||
BX_CHECK(0 != m_id, "Failed to generate texture id.");
|
||||
GL_CHECK(glBindTexture(m_target, m_id) );
|
||||
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, 1 < dds.m_numMips ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) );
|
||||
|
||||
GLenum fmt = typefmt[dds.m_type];
|
||||
|
||||
uint32_t width = dds.m_width;
|
||||
uint32_t height = dds.m_height;
|
||||
const TextureFormatInfo& tfi = s_textureFormat[dds.m_type];
|
||||
GLenum internalFmt = tfi.m_internalFmt;
|
||||
|
||||
if (!s_renderCtx.m_dxtSupport
|
||||
|| 0 == dds.m_type)
|
||||
|| TextureFormat::Unknown < dds.m_type)
|
||||
{
|
||||
fmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
|
||||
|
||||
uint8_t bpp = 4;
|
||||
if (dds.m_type == 0
|
||||
&& dds.m_bpp == 1)
|
||||
if (internalFmt == GL_RGBA)
|
||||
{
|
||||
fmt = GL_LUMINANCE;
|
||||
bpp = 1;
|
||||
internalFmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
|
||||
}
|
||||
|
||||
uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*bpp);
|
||||
uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*tfi.m_bpp);
|
||||
|
||||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
GLenum target = m_target;
|
||||
if (dds.m_cubeMap)
|
||||
{
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
}
|
||||
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, lod, _mem, mip) )
|
||||
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
uint32_t width = dds.m_width;
|
||||
uint32_t height = dds.m_height;
|
||||
uint32_t depth = dds.m_depth;
|
||||
|
||||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
mip.decode(bits);
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
depth = uint32_max(1, depth);
|
||||
|
||||
if (GL_RGBA == fmt)
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, 0, lod, _mem, mip) )
|
||||
{
|
||||
uint32_t dstpitch = width*4;
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
mip.decode(bits);
|
||||
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
if (GL_RGBA == internalFmt)
|
||||
{
|
||||
uint32_t dstpitch = width*4;
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
uint8_t tmp = dst[0];
|
||||
dst[0] = dst[2];
|
||||
dst[2] = tmp;
|
||||
dst += 4;
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
uint8_t tmp = dst[0];
|
||||
dst[0] = dst[2];
|
||||
dst[2] = tmp;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
if (target == GL_TEXTURE_3D)
|
||||
{
|
||||
|
||||
GL_CHECK(glTexImage3D(target
|
||||
, lod
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
, depth
|
||||
, 0
|
||||
, tfi.m_format
|
||||
, tfi.m_type
|
||||
, bits
|
||||
) );
|
||||
}
|
||||
else
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
{
|
||||
GL_CHECK(glTexImage2D(target+side
|
||||
, lod
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
, 0
|
||||
, tfi.m_format
|
||||
, tfi.m_type
|
||||
, bits
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
GL_CHECK(glTexImage2D(m_target
|
||||
, lod
|
||||
, fmt
|
||||
, width
|
||||
, height
|
||||
, 0
|
||||
, fmt
|
||||
, GL_UNSIGNED_BYTE
|
||||
, bits
|
||||
) );
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
|
||||
g_free(bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t ii = 0, num = dds.m_numMips; ii < num; ++ii)
|
||||
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
uint32_t width = dds.m_width;
|
||||
uint32_t height = dds.m_height;
|
||||
uint32_t depth = dds.m_depth;
|
||||
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, ii, _mem, mip) )
|
||||
for (uint32_t ii = 0, num = dds.m_numMips; ii < num; ++ii)
|
||||
{
|
||||
GL_CHECK(glCompressedTexImage2D(m_target
|
||||
, ii
|
||||
, fmt
|
||||
, width
|
||||
, height
|
||||
, 0
|
||||
, mip.m_size
|
||||
, mip.m_data
|
||||
) );
|
||||
}
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
depth = uint32_max(1, depth);
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, 0, ii, _mem, mip) )
|
||||
{
|
||||
GL_CHECK(glCompressedTexImage2D(m_target
|
||||
, ii
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
, 0
|
||||
, mip.m_size
|
||||
, mip.m_data
|
||||
) );
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_target = GL_TEXTURE_2D;
|
||||
GL_CHECK(glGenTextures(1, &m_id) );
|
||||
BX_CHECK(0 != m_id, "Failed to generate texture id.");
|
||||
GL_CHECK(glBindTexture(m_target, m_id) );
|
||||
|
||||
StreamRead stream(_mem->data, _mem->size);
|
||||
|
||||
uint32_t magic;
|
||||
|
@ -1055,7 +1151,7 @@ namespace bgfx
|
|||
|
||||
stream.align(16);
|
||||
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, 1 < dds.m_numMips ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) );
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, 1 < numMips ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) );
|
||||
|
||||
for (uint8_t mip = 0; mip < numMips; ++mip)
|
||||
{
|
||||
|
@ -1086,6 +1182,19 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]) );
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]) );
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
if (m_target == GL_TEXTURE_3D)
|
||||
{
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_R, s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT]) );
|
||||
GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT]) );
|
||||
|
||||
GL_CHECK(glBindTexture(m_target, 0) );
|
||||
}
|
||||
|
||||
|
@ -1490,6 +1599,7 @@ namespace bgfx
|
|||
|
||||
void Context::rendererShutdown()
|
||||
{
|
||||
s_renderCtx.shutdown();
|
||||
}
|
||||
|
||||
void Context::rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem)
|
||||
|
@ -2015,30 +2125,29 @@ namespace bgfx
|
|||
const Sampler& sampler = state.m_sampler[stage];
|
||||
Sampler& current = currentState.m_sampler[stage];
|
||||
if (current.m_idx != sampler.m_idx
|
||||
|| current.m_flags != sampler.m_flags
|
||||
|| materialChanged)
|
||||
|| current.m_flags != sampler.m_flags
|
||||
|| materialChanged)
|
||||
{
|
||||
GL_CHECK(glActiveTexture(GL_TEXTURE0+stage) );
|
||||
if (bgfx::invalidHandle != sampler.m_idx)
|
||||
{
|
||||
GLuint id = 0;
|
||||
switch (sampler.m_flags&BGFX_SAMPLER_TYPE_MASK)
|
||||
{
|
||||
case 0:
|
||||
id = s_renderCtx.m_textures[sampler.m_idx].m_id;
|
||||
case BGFX_SAMPLER_TEXTURE:
|
||||
{
|
||||
const Texture& texture = s_renderCtx.m_textures[sampler.m_idx];
|
||||
GL_CHECK(glBindTexture(texture.m_target, texture.m_id) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
id = s_renderCtx.m_renderTargets[sampler.m_idx].m_color.m_id;
|
||||
case BGFX_SAMPLER_RENDERTARGET_COLOR:
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_2D, s_renderCtx.m_renderTargets[sampler.m_idx].m_color.m_id) );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
id = s_renderCtx.m_renderTargets[sampler.m_idx].m_depth.m_id;
|
||||
case BGFX_SAMPLER_RENDERTARGET_DEPTH:
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_2D, s_renderCtx.m_renderTargets[sampler.m_idx].m_depth.m_id) );
|
||||
break;
|
||||
}
|
||||
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) );
|
||||
// GL_CHECK(glUniform1i(material.m_sampler[stage], stage) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,38 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
|
|||
# include <gl/GRemedyGLExtensions.h>
|
||||
#endif // BGFX_CONFIG_DEBUG_GREMEDY && (BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX)
|
||||
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
typedef PROC (APIENTRYP PFNWGLGETPROCADDRESSPROC) (LPCSTR lpszProc);
|
||||
typedef BOOL (APIENTRYP PFNWGLMAKECURRENTPROC) (HDC hDc, HGLRC newContext);
|
||||
typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTPROC) (HDC hDc);
|
||||
//
|
||||
typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
|
||||
typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
|
||||
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
|
||||
typedef void (APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
typedef void (APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
|
||||
typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
|
||||
typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params);
|
||||
typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
|
||||
typedef void (APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
|
||||
typedef void (APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
|
||||
typedef void (APIENTRYP PFNGLPOINTSIZEPROC) (GLfloat size);
|
||||
typedef void (APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
|
||||
typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
|
||||
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);
|
||||
typedef void (APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
|
||||
typedef void (APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
|
||||
typedef void (APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble depth);
|
||||
typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
# define _GL_CHECK(_call) \
|
||||
|
@ -104,6 +136,12 @@ namespace bgfx
|
|||
#define GREMEDY_SETMARKER(_string) _GREMEDY_SETMARKER(_string)
|
||||
#define GREMEDY_FRAMETERMINATOR() _GREMEDY_FRAMETERMINATOR()
|
||||
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
extern PFNWGLGETPROCADDRESSPROC wglGetProcAddress;
|
||||
extern PFNWGLMAKECURRENTPROC wglMakeCurrent;
|
||||
extern PFNWGLCREATECONTEXTPROC wglCreateContext;
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
||||
#define GL_IMPORT(_optional, _proto, _func) extern _proto _func
|
||||
#include "glimports.h"
|
||||
#undef GL_IMPORT
|
||||
|
|
|
@ -49,56 +49,59 @@ int main(int _argc, const char* _argv[])
|
|||
if (decompress
|
||||
|| 0 == dds.m_type)
|
||||
{
|
||||
uint32_t width = dds.m_width;
|
||||
uint32_t height = dds.m_height;
|
||||
|
||||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
uint32_t width = dds.m_width;
|
||||
uint32_t height = dds.m_height;
|
||||
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, lod, mem, mip) )
|
||||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
uint32_t dstpitch = width*4;
|
||||
uint8_t* bits = (uint8_t*)malloc(dstpitch*height);
|
||||
width = uint32_max(1, width);
|
||||
height = uint32_max(1, height);
|
||||
|
||||
if (width != mip.m_width
|
||||
|| height != mip.m_height)
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, side, lod, mem, mip) )
|
||||
{
|
||||
uint8_t* temp = (uint8_t*)realloc(NULL, mip.m_width*mip.m_height*4);
|
||||
mip.decode(temp);
|
||||
uint32_t srcpitch = mip.m_width*4;
|
||||
uint32_t dstpitch = width*4;
|
||||
uint8_t* bits = (uint8_t*)malloc(dstpitch*height);
|
||||
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
if (width != mip.m_width
|
||||
|| height != mip.m_height)
|
||||
{
|
||||
uint8_t* src = &temp[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
uint8_t* temp = (uint8_t*)realloc(NULL, mip.m_width*mip.m_height*4);
|
||||
mip.decode(temp);
|
||||
uint32_t srcpitch = mip.m_width*4;
|
||||
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
memcpy(dst, src, 4);
|
||||
dst += 4;
|
||||
src += 4;
|
||||
uint8_t* src = &temp[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
memcpy(dst, src, 4);
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
free(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mip.decode(bits);
|
||||
}
|
||||
|
||||
free(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mip.decode(bits);
|
||||
char filePath[256];
|
||||
_snprintf(filePath, sizeof(filePath), "mip%d_%d.tga", side, lod);
|
||||
|
||||
bgfx::saveTga(filePath, width, height, dstpitch, bits);
|
||||
free(bits);
|
||||
}
|
||||
|
||||
char filePath[256];
|
||||
_snprintf(filePath, sizeof(filePath), "mip%d.tga", lod);
|
||||
|
||||
bgfx::saveTga(filePath, width, height, dstpitch, bits);
|
||||
free(bits);
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -106,7 +109,7 @@ int main(int _argc, const char* _argv[])
|
|||
for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
Mip mip;
|
||||
if (getRawImageData(dds, lod, mem, mip) )
|
||||
if (getRawImageData(dds, 0, lod, mem, mip) )
|
||||
{
|
||||
char filePath[256];
|
||||
_snprintf(filePath, sizeof(filePath), "mip%d.bin", lod);
|
||||
|
|
Loading…
Reference in a new issue