void TextureGPU::createDrawableIntoColorTexture(PrimitiveTypes::UInt32 w, PrimitiveTypes::UInt32 h, ESamplerState sampler) { m_samplerState = sampler; StringOps::writeToString("DrawableIntoColorTexture", m_name, 256); # if APIABSTRACTION_D3D9 D3D9Renderer *pD3D9Renderer = static_cast<D3D9Renderer *>(m_pContext->getGPUScreen()); LPDIRECT3DDEVICE9 pDevice = pD3D9Renderer->m_pD3D9Device; m_viewport.X = 0; m_viewport.Y = 0; m_viewport.Width = w; m_viewport.Height = h; m_viewport.MinZ = 0.0f; m_viewport.MaxZ = 1.0f; IDirect3DTexture9 *pColorMap = 0; #if APIABSTRACTION_X360 HRESULT hr = D3DXCreateTexture( pDevice, w, h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &this->m_pTexture ); #else HRESULT hr = pDevice->CreateTexture( w, h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &this->m_pTexture, NULL); #endif D3DSURFACE_DESC desc; m_pTexture->GetSurfaceLevel( 0, &m_pSurface ); m_pSurface->GetDesc( &desc ); #ifdef _XBOX hr = pDevice->CreateRenderTarget(desc.Width, desc.Height, ( D3DFORMAT )MAKESRGBFMT( desc.Format ), D3DMULTISAMPLE_NONE, 0, 0, &m_pEDRamColorRenderTargetSurface, NULL ); #else #if D3D9_USE_RENDER_TO_SURFACE hr = D3DXCreateRenderToSurface(pDevice, desc.Width, desc.Height, desc.Format, false, D3DFMT_UNKNOWN, &m_pRenderToSurface ); #endif #endif assert(SUCCEEDED(hr)); #elif APIABSTRACTION_OGL glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_2D, m_texture); IRenderer::checkForErrors("glTexImage2D"); glTexImage2D( GL_TEXTURE_2D, // Target 0, // Mip-level #if defined(SN_TARGET_PS3) GL_ARGB_SCE, #else GL_RGBA, // InternalFormat, for ps3 use GL_ARGB_SCE, why? #endif w, // width size h, // height size 0, // border GL_RGBA, // input pixel format GL_UNSIGNED_BYTE, // input pixel type NULL); // input pixels IRenderer::checkForErrors("glTexImage2D"); SamplerState &ss = SamplerStateManager::getInstance()->getSamplerState(m_samplerState); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T); #if !APIABSTRACTION_IOS glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip #endif //depth related //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE_ARB,GL_COMPARE_R_TO_TEXTURE_ARB); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); glBindTexture(GL_TEXTURE_2D, 0); #if APIABSTRACTION_PS3 glGenFramebuffersOES(1, &m_frameBufferObject); #else glGenFramebuffers(1, &m_frameBufferObject); #endif #if APIABSTRACTION_PS3 glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. #else glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. #endif //glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, w); / no need for this, since it take size of the texture passed #if APIABSTRACTION_PS3 glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); #else glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0); #endif m_viewport.x = 0; m_viewport.y = 0; m_viewport.w = w; m_viewport.h = h; m_viewport.minDepth = 0; m_viewport.maxDepth = 1.0f; #if !APIABSTRACTION_IOS #if APIABSTRACTION_PS3 assert(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES); #else assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); #endif #endif #if APIABSTRACTION_PS3 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); // back to default #else glBindFramebuffer(GL_FRAMEBUFFER, 0); // back to default #endif #elif APIABSTRACTION_D3D11 m_viewport.TopLeftX = 0; m_viewport.TopLeftY = 0; m_viewport.Width = w; m_viewport.Height = h; m_viewport.MinDepth = 0.0f; m_viewport.MaxDepth = 1.0f; D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen()); ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice; ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext; //ID3D11Texture2D *pColorMap = 0; D3D11_TEXTURE2D_DESC texDesc; texDesc.Width = w; texDesc.Height = h; texDesc.MipLevels = 0; texDesc.ArraySize = 1; texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; texDesc.SampleDesc.Count = 1; texDesc.SampleDesc.Quality = 0; texDesc.Usage = D3D11_USAGE_DEFAULT; texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; HRESULT hr = pDevice->CreateTexture2D(&texDesc, 0, &m_pTexture); assert(SUCCEEDED(hr)); // Null description means to create a view to all mipmap levels // using the format the texture was created with hr = pDevice->CreateRenderTargetView(m_pTexture, 0, &m_pRenderTargetView); assert(SUCCEEDED(hr)); hr = pDevice->CreateShaderResourceView(m_pTexture, 0, &m_pShaderResourceView); assert(SUCCEEDED(hr)); #endif }
void TextureGPU::createDrawableIntoColorTextureWithDepth(PrimitiveTypes::UInt32 w, PrimitiveTypes::UInt32 h, ESamplerState sampler, bool use32BitRedForDepth /* = false*/) { StringOps::writeToString("createDrawableIntoColorTextureWithDepth", m_name, 256); m_samplerState = sampler; # if APIABSTRACTION_D3D9 D3D9Renderer *pD3D9Renderer = static_cast<D3D9Renderer *>(m_pContext->getGPUScreen()); LPDIRECT3DDEVICE9 pDevice = pD3D9Renderer->m_pD3D9Device; m_viewport.X = 0; m_viewport.Y = 0; m_viewport.Width = w; m_viewport.Height = h; m_viewport.MinZ = 0.0f; m_viewport.MaxZ = 1.0f; #if APIABSTRACTION_X360 HRESULT hr = D3DXCreateTexture(pDevice, w, h, 1, D3DUSAGE_RENDERTARGET, use32BitRedForDepth ? D3DFMT_R32F : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &this->m_pTexture ); #else HRESULT hr = pDevice->CreateTexture( w, h, 1, D3DUSAGE_RENDERTARGET, use32BitRedForDepth ? D3DFMT_R32F : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &this->m_pTexture, NULL); #endif D3DSURFACE_DESC desc; m_pTexture->GetSurfaceLevel( 0, &m_pSurface ); m_pSurface->GetDesc( &desc ); #ifdef _XBOX //create depth stencil surface to use with this texture hr = pDevice->CreateDepthStencilSurface( w, h, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, // multi sample quality TRUE, // Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise. //If this flag is set, the contents of the depth stencil buffer will be invalid // after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface. &m_pEDRamDSRenderTargetSurface, NULL); assert(SUCCEEDED(hr)); hr = pDevice->CreateRenderTarget( desc.Width, desc.Height, ( D3DFORMAT )MAKESRGBFMT( desc.Format ), D3DMULTISAMPLE_NONE, 0, 0, &m_pEDRamColorRenderTargetSurface, NULL ); #else #if D3D9_USE_RENDER_TO_SURFACE hr = D3DXCreateRenderToSurface(pDevice, desc.Width, desc.Height, desc.Format, TRUE, D3DFMT_D16, &m_pRenderToSurface ); #else //create depth stencil surface to use with this texture hr = pDevice->CreateDepthStencilSurface( w, h, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, // multi sample quality TRUE, // Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise. //If this flag is set, the contents of the depth stencil buffer will be invalid // after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface. &m_pDSSurface, NULL); #endif #endif assert(SUCCEEDED(hr)); #elif APIABSTRACTION_OGL SamplerState &ss = SamplerStateManager::getInstance()->getSamplerState(m_samplerState); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); IRenderer::checkForErrors("glTexImage2D"); #if PE_PLAT_IS_IOS PEWARN("We are creating depth texture as 32 bit, because I could not get 16 bit depth working. If you figure it out, change it to 16 bit for better perf (hopefully!)"); #endif glTexImage2D( GL_TEXTURE_2D, // Target 0, // Mip-level #if PE_PLAT_IS_IOS GL_DEPTH_COMPONENT, // InternalFormat #else GL_DEPTH_COMPONENT16, #endif w, // width size h, // height size 0, // border GL_DEPTH_COMPONENT, // input pixel format #if PE_PLAT_IS_IOS GL_UNSIGNED_INT, // input pixel type #else GL_UNSIGNED_SHORT, #endif NULL); // input pixels IRenderer::checkForErrors("glTexImage2D"); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T); #if !APIABSTRACTION_IOS glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip // depth related comparison functions glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); #endif glBindTexture(GL_TEXTURE_2D, 0); #if APIABSTRACTION_PS3 glGenFramebuffersOES(1, &m_frameBufferObject); #else glGenFramebuffers(1, &m_frameBufferObject); #endif #if APIABSTRACTION_PS3 glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. #else glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. #endif //glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, w); / no need for this, since it take size of the texture passed #if APIABSTRACTION_PS3 glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_TEXTURE_2D, texture, 0); #else glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0); #endif m_viewport.x = 0; m_viewport.y = 0; m_viewport.w = w; m_viewport.h = h; m_viewport.minDepth = 0; m_viewport.maxDepth = 1.0f; // had to comment out this assert becasue apparently with newest hardware it is actually complete too //assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE); // make sure API requires color texture too // need to cerate color texture too, otherwise framebuffer object is incomplete glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_2D, m_texture); IRenderer::checkForErrors("glTexImage2D"); #if PE_PLAT_IS_IOS if (use32BitRedForDepth) PEWARN("We are creating depth+color and storing dpeth in color. for ios we store it as rgba, since we cant store it as 32bit red.."); #endif glTexImage2D( GL_TEXTURE_2D, // Target 0, // Mip-level #if defined(SN_TARGET_PS3) use32BitRedForDepth ? GL_LUMINANCE32F_ARB : GL_ARGB_SCE, #else #if APIABSTRACTION_IOS use32BitRedForDepth ? GL_RGBA : GL_RGBA, // InternalFormat, for ps3 use GL_ARGB_SCE, why? #else use32BitRedForDepth ? GL_R32F : GL_RGBA, // InternalFormat, for ps3 use GL_ARGB_SCE, why? #endif #endif w, // width size h, // height size 0, // border GL_RGBA, // input pixel format GL_UNSIGNED_BYTE, // input pixel type NULL); // input pixels IRenderer::checkForErrors("glTexImage2D"); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T); #if !APIABSTRACTION_IOS glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip #endif //depth related //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE_ARB,GL_COMPARE_R_TO_TEXTURE_ARB); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); glBindTexture(GL_TEXTURE_2D, 0); #if APIABSTRACTION_PS3 glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); #else glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0); #endif #if !APIABSTRACTION_IOS #if APIABSTRACTION_PS3 assert(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES); #else assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); #endif #endif IRenderer::checkRenderBufferComplete(); #if APIABSTRACTION_PS3 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); // back to default #else glBindFramebuffer(GL_FRAMEBUFFER, 0); // back to default #endif #elif APIABSTRACTION_D3D11 m_viewport.TopLeftX = 0; m_viewport.TopLeftY = 0; m_viewport.Width = w; m_viewport.Height = h; m_viewport.MinDepth = 0.0f; m_viewport.MaxDepth = 1.0f; D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen()); ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice; ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext; //ID3D11Texture2D *pColorMap = 0; D3D11_TEXTURE2D_DESC texDesc; texDesc.Width = w; texDesc.Height = h; texDesc.MipLevels = 1; texDesc.ArraySize = 1; texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; texDesc.SampleDesc.Count = 1; texDesc.SampleDesc.Quality = 0; texDesc.Usage = D3D11_USAGE_DEFAULT; texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; HRESULT hr = pDevice->CreateTexture2D(&texDesc, 0, &m_pTexture); assert(SUCCEEDED(hr)); // Null description means to create a view to all mipmap levels // using the format the texture was created with hr = pDevice->CreateRenderTargetView(m_pTexture, 0, &m_pRenderTargetView); assert(SUCCEEDED(hr)); hr = pDevice->CreateShaderResourceView(m_pTexture, 0, &m_pShaderResourceView); assert(SUCCEEDED(hr)); // Now create depth part fo the texture ID3D11Texture2D *pDepthMap = 0; texDesc.Format = DXGI_FORMAT_R32_TYPELESS; texDesc.Usage = D3D11_USAGE_DEFAULT; texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = 0; hr = pDevice->CreateTexture2D(&texDesc, 0, &pDepthMap); assert(SUCCEEDED(hr)); // setting up view for rendering into depth buffer/and reading (stenciling) from it (z-buffer algorithm red/write) D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; dsvDesc.Format = DXGI_FORMAT_D32_FLOAT; dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = 0;//D3D11_DSV_READ_ONLY_DEPTH; hr = pDevice->CreateDepthStencilView(pDepthMap, &dsvDesc, &m_DepthStencilView); assert(SUCCEEDED(hr)); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = DXGI_FORMAT_R32_FLOAT; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srvDesc.Texture2D.MostDetailedMip = 0; hr = pDevice->CreateShaderResourceView(pDepthMap, &srvDesc, &m_pDepthShaderResourceView); assert(SUCCEEDED(hr)); pDepthMap->Release(); #endif }
ID3D11Texture2D * #endif TextureGPU::gfxLoadDDSTexture(char *filename, bool genMips /*= true*/) { DDS::DDSTextureInSystemMemory dds; uint32_t test = loadDDSIntoSystemMemory(filename,&dds); if(test==false) { printf("failed to load\n"); exit(0); } bool haveMips = dds.mips > 1; bool needToGenerateMips = !haveMips && genMips; bool willHaveMips = haveMips || genMips; if (false) { int32_t w = dds.width; int32_t h = dds.height; for (uint32_t i = 0; i < dds.mips; i++) { unsigned char r = i % 3 ? 0x00 : 0xFF; unsigned char g = (i+2) % 3 ? 0x00 : 0xFF; unsigned char b = (i+1) % 3 ? 0x00 : 0xFF; if (dds.uncompressedFormat && dds.components == 4) { unsigned char *data = dds.image[0].pixels[i]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { unsigned char solid = ((x % 8) > 3) ^ ((y % 8) > 3); *data++ = b * solid; *data++ = g * solid; *data++ = r * solid; *data++ = 0; } } // we use componets == 3 becasue on IOS we dont have GL_BGR flag at all. event to use is as temp variable for storing dds format if (dds.uncompressedFormat && dds.components == 3) { unsigned char *data = dds.image[0].pixels[i]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { *data++ = r; *data++ = g; *data++ = b; } } w/=2; h/=2; if (w == 0) w = 1; if (h == 0) h = 1; } } assert(m_samplerState != SamplerState_INVALID); SamplerState &ss = SamplerStateManager::getInstance()->getSamplerState(m_samplerState); if (willHaveMips) { //check that we want t use existing mips if (!ss.needsMipMaps()) { PEWARN("Mipmap filtering is disabled while mipams exist and are loaded. Texture: %s", filename); } } else { //check that we dont want a value that assumes mip map existance if (ss.needsMipMaps()) { PEWARN("Trying to enable mip map filtering when no mipmaps exist. Texture: %s", filename); } } int32_t w = dds.width; int32_t h = dds.height; #if APIABSTRACTION_D3D9 D3D9Renderer *pD3D9Renderer = static_cast<D3D9Renderer *>(m_pContext->getGPUScreen()); LPDIRECT3DDEVICE9 pDevice = pD3D9Renderer->m_pD3D9Device; //choose api format best suited for loaded texture D3DFORMAT destApiFormat = D3DFMT_UNKNOWN; if (dds.compressedFormat) { assert(!"Dont support compressed textures yet!"); } else { if (dds.components == 1) { if (dds.uncompressedFormat == DDSF_L) destApiFormat = D3DFMT_L8; else assert(!"Unknown format!"); } else if (dds.components == 3) { assert(!"Need to add support for this format!"); } else if (dds.components == 4) { if (dds.uncompressedFormat == DDSF_RGBA) destApiFormat = D3DFMT_A8R8G8B8; else if (dds.uncompressedFormat == DDSF_RGB) destApiFormat = D3DFMT_X8R8G8B8; } else { assert(!"Unknown texture format!"); } } if (!destApiFormat) return NULL; IDirect3DTexture9 * pTexture = NULL; pDevice->CreateTexture( dds.width, dds.height, /*Levels = 0 - generate space for all mips, otherwise use provided number*/ haveMips ? 0 : 1, // if we have source mipmaps set to 0 (will have mips) otherwise set to 1 becasue mips will be generated on gpu memory texture) 0, // potentially could use D3DUSAGE_AUTOGENMIPMAP on a gpu texture, not on SYSTEMMEM, destApiFormat, D3DPOOL_SYSTEMMEM, // set it to sys mem to be able to set pixels // D3DPOOL_DEFAULT, &pTexture, // result NULL); // set to null printf("file %s dds surfaces %d mips %d w %d h %d \n",filename,dds.surfaces,dds.mips,w,h); if(dds.surfaces!=1) //its a cube map { printf("ERROR: this is a cubemap\n"); exit(0); } if(dds.compressedFormat == FOURCC_DXT1) printf("FOURCC_DXT1\n"); if(dds.compressedFormat == FOURCC_DXT3) printf("FOURCC_DXT3\n"); if(dds.compressedFormat == FOURCC_DXT5) printf("FOURCC_DXT5\n"); D3DFORMAT destGpuFormatEnum = (D3DFORMAT)(DDS::getDestGPUFormatFromComponents(dds.components)); D3DFORMAT sourceCpuFormatEnum = (D3DFORMAT)(DDS::getSourceCPUFormatFromComponents(dds.components)); //load a compressed texture if(dds.compressedFormat) { assert(!"Compressed textures are not yet supported!"); } else // load a non compressed texture { for (uint32_t i = 0; i < dds.mips; i++) { IDirect3DSurface9 *pSurface = NULL; HRESULT hr = pTexture->GetSurfaceLevel(i, &pSurface); assert(SUCCEEDED(hr)); D3DLOCKED_RECT lockedRect; hr = pSurface->LockRect(&lockedRect, NULL, 0); assert(SUCCEEDED(hr)); unsigned char *data = dds.image[0].pixels[i]; char *destData = (char*)(lockedRect.pBits); for (int y = 0; y < h; y++) { memcpy(&destData[lockedRect.Pitch * y], &data[dds.components * w * y], dds.components * w); } hr = pSurface->UnlockRect(); assert(SUCCEEDED(hr)); w/=2; h/=2; if (w == 0) w = 1; if (h == 0) h = 1; } //restore to default } free(dds.buffer); // at this point the file buffer is no longer needed int d3dUsage = 0; #if PE_PLAT_IS_XBOX360 if (needToGenerateMips) PEWARN("On XBOX 360 we can't autogen mipmaps!\n"); #else d3dUsage = needToGenerateMips ? D3DUSAGE_AUTOGENMIPMAP: 0; // potentially could use D3DUSAGE_AUTOGENMIPMAP, but we do not want to support it now, since we only support mipmaps that are in dds already #endif //create GPU texture that wills tore the data IDirect3DTexture9 *pDestTexture = NULL; pDevice->CreateTexture( dds.width, dds.height, willHaveMips ? 0 : 1, // 0: will create mipmap surfaces too d3dUsage, destApiFormat, D3DPOOL_DEFAULT, &pDestTexture, // result NULL); // set to null #if PE_PLAT_IS_XBOX360 PEASSERT(false, "Right now we load textures on xbox360 trhough helper in d3dx. Need some reasearch to see how to load it ourselves from raw data and update the texture"); #else pDevice->UpdateTexture(pTexture, pDestTexture); #endif pTexture->Release(); // release sys memory texture return pDestTexture; // return the texture name #else //choose api format best suited for loaded texture DXGI_FORMAT destApiFormat = DXGI_FORMAT_UNKNOWN; if (dds.compressedFormat) { assert(!"Dont support compressed textures yet!"); } else { if (dds.components == 1) { if (dds.uncompressedFormat == DDSF_L) destApiFormat = DXGI_FORMAT_R8_UNORM; else assert(!"Unknown format!"); } else if (dds.components == 3) { assert(!"Need to add support for this format!"); } else if (dds.components == 4) { if (dds.uncompressedFormat == DDSF_RGBA) destApiFormat = DXGI_FORMAT_B8G8R8A8_UNORM; else if (dds.uncompressedFormat == DDSF_RGB) destApiFormat = DXGI_FORMAT_B8G8R8X8_UNORM; } else { assert(!"Unknown texture format!"); } } if (!destApiFormat) return NULL; ID3D11Texture2D* pTexture = NULL; D3D11_TEXTURE2D_DESC desc; desc.Width = dds.width; desc.Height = dds.height; desc.MipLevels = willHaveMips ? 0 : 1; desc.ArraySize = 1; desc.Format = destApiFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_IMMUTABLE; // immutable since data wont change desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; D3D11_SUBRESOURCE_DATA datas[32]; //in case mips are already loaded (and not generated) we need to pass in array of the datas for (uint32_t i = 0; i < dds.mips; i++) { D3D11_SUBRESOURCE_DATA &data = datas[i]; data.pSysMem = dds.image[0].pixels[/*mip=*/i]; data.SysMemPitch = dds.components * w; data.SysMemSlicePitch = 0; // unused since 2d texture w/=2; h/=2; if (w == 0) w = 1; if (h == 0) h = 1; } D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen()); ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice; ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext; pDevice->CreateTexture2D( &desc, datas, &pTexture); return pTexture; #endif }