From fe1252d260f04241cf986c2eada796d7c2a10c1d Mon Sep 17 00:00:00 2001 From: bkaradzic Date: Sat, 9 Jun 2012 18:25:50 -0700 Subject: [PATCH] Support for Cube and Volume textures. --- include/bgfx.h | 22 ++- src/bgfx_p.h | 13 +- src/dds.cpp | 130 +++++++++++------ src/dds.h | 22 ++- src/glimports.h | 31 ++++ src/renderer_d3d9.cpp | 326 +++++++++++++++++++++++++++++------------- src/renderer_d3d9.h | 18 ++- src/renderer_gl.cpp | 297 ++++++++++++++++++++++++++------------ src/renderer_gl.h | 38 +++++ tools/ddsdump.cpp | 75 +++++----- 10 files changed, 685 insertions(+), 287 deletions(-) diff --git a/include/bgfx.h b/include/bgfx.h index d5b8abff..4211f451 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -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, }; }; diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 9ab0ada9..d222e8a2 100644 --- a/src/bgfx_p.h +++ b/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) { diff --git a/src/dds.cpp b/src/dds.cpp index ef524c8f..f6c6f020 100644 --- a/src/dds.cpp +++ b/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; diff --git a/src/dds.h b/src/dds.h index 7b921f4f..adc9748f 100644 --- a/src/dds.h +++ b/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 diff --git a/src/glimports.h b/src/glimports.h index b9f395b8..2d85f355 100644 --- a/src/glimports.h +++ b/src/glimports.h @@ -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); diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 10318b9a..5319f608 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -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; } diff --git a/src/renderer_d3d9.h b/src/renderer_d3d9.h index ee1a1b3c..d8e4facf 100644 --- a/src/renderer_d3d9.h +++ b/src/renderer_d3d9.h @@ -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; }; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 2bee3f5a..646bd314 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -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) ); } } diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 7a2b5d45..32d236fc 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -63,6 +63,38 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b # include #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 diff --git a/tools/ddsdump.cpp b/tools/ddsdump.cpp index 72ceb358..f59138ea 100644 --- a/tools/ddsdump.cpp +++ b/tools/ddsdump.cpp @@ -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);