/// \brief creats a blannk Cube texture and returns the pointer to the object DWORD CTextureManager::OnCreateCubeTexture( DWORD size, void * params ) { //get the param structure CREATECUBETEXTUREPARAMS *texObjParams; ICubeTextureObject * currentTexture; bool bResult; TEXTURENAMEMAP::iterator cur; texObjParams = (CREATECUBETEXTUREPARAMS *)params; VERIFY_MESSAGE_SIZE(sizeof(CREATECUBETEXTUREPARAMS), size); texObjParams->CubeTextureObjectInterface = NULL; //look for it if( texObjParams->Name != NULL ) { static CHashString DXCubeTexObj(_T("CDX9CubeTextureObject")); currentTexture = dynamic_cast< ICubeTextureObject* >(CreateTextureObject( texObjParams->Name, &DXCubeTexObj)); assert( currentTexture ); currentTexture->SetTextureName( texObjParams->Name ); bResult = currentTexture->InitializeCubemap( texObjParams->size, texObjParams->bitDepth ); //add to internal list if( bResult ) { currentTexture->SetTextureName( texObjParams->Name ); m_TextureNameMap[texObjParams->Name->GetUniqueID()] = currentTexture; //set the return value texObjParams->CubeTextureObjectInterface = currentTexture; }else { DeleteTextureObject( currentTexture ); } } return MSG_HANDLED_PROCEED; }
void CDXTexture::LoadToGPU() { if (!m_pixels) { // nothing to load - probably same image (no change) return; } if (m_texture.Get() == NULL) { CreateTextureObject(); if (m_texture.Get() == NULL) { CLog::Log(LOGDEBUG, "CDXTexture::CDXTexture: Error creating new texture for size %d x %d", m_textureWidth, m_textureHeight); return; } } D3DLOCKED_RECT lr; if (m_texture.LockRect( 0, &lr, NULL, D3DLOCK_DISCARD )) { unsigned char *dst = (unsigned char *)lr.pBits; unsigned char *src = m_pixels; unsigned int dstPitch = lr.Pitch; unsigned int srcPitch = GetPitch(); unsigned int minPitch = std::min(srcPitch, dstPitch); unsigned int rows = GetRows(); if (srcPitch == dstPitch) { memcpy(dst, src, srcPitch * rows); } else { for (unsigned int y = 0; y < rows; y++) { memcpy(dst, src, minPitch); src += srcPitch; dst += dstPitch; } } } else { CLog::Log(LOGERROR, __FUNCTION__" - failed to lock texture"); } m_texture.UnlockRect(0); delete [] m_pixels; m_pixels = NULL; m_loadedToGPU = true; }
/// \brief creates a blank texture and returns a pointer to the object. DWORD CTextureManager::OnCreateTexture(DWORD size, void *params) { //get the param structure CREATETEXTUREPARAMS *texObjParams; ITextureObject * currentTexture; bool bResult; TEXTURENAMEMAP::iterator cur; texObjParams = (CREATETEXTUREPARAMS *)params; VERIFY_MESSAGE_SIZE(sizeof(CREATETEXTUREPARAMS), size); texObjParams->TextureObjectInterface = NULL; //look for it if( texObjParams->Name != NULL ) { currentTexture = dynamic_cast< ITextureObject* >(GetTexture( texObjParams->Name )); if (!currentTexture) { //new texture CHashString hszComponentType("CDX9TextureObject"); currentTexture = dynamic_cast< ITextureObject* >(CreateTextureObject( texObjParams->Name, &hszComponentType )); // add to internal list m_TextureNameMap[texObjParams->Name->GetUniqueID()] = currentTexture; } if( texObjParams->bRenderTargetTexture == RENDER_TARGET_NONE ) { bResult = currentTexture->MakeBlankTexture( texObjParams->sizeX, texObjParams->sizeY, texObjParams->bitDepth, texObjParams->Format, texObjParams->numMips ); } else { bResult = currentTexture->MakeRenderTarget( texObjParams->sizeX, texObjParams->sizeY, texObjParams->bitDepth, texObjParams->bRenderTargetTexture, texObjParams->bAutoGenMipMaps ); } if (bResult) { currentTexture->SetTextureName( texObjParams->Name ); // success, set the return value texObjParams->TextureObjectInterface = currentTexture; } else { m_TextureNameMap.erase( texObjParams->Name->GetUniqueID() ); // creation failure DeleteTextureObject( currentTexture ); } } return MSG_HANDLED_PROCEED; }
IBaseTextureObject * CTextureManager::LoadCubeDDSTexture( IHashString* name ) { //Open the data stream DWORD result; IArchive *FileArchive; CHashString streamType(_T("File")); CREATEARCHIVE ca; ca.mode = STREAM_MODE_READ | STREAM_MODE_BINARY; ca.streamData = (void*)name->GetString(); ca.streamType = &streamType; static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID(); result = m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &ca); IBaseTextureObject *pTexture = NULL; if( result == MSG_HANDLED ) { FileArchive = dynamic_cast<IArchive *>(ca.archive); //Check DDS UINT fourcc; FileArchive->Read( fourcc ); if( EE_ENDIANSWAP32(fourcc) != MAKEFOURCC( 'D', 'D', 'S', ' ' ) ) { return NULL; } DDSHeader header; char * pheader = (char*)&header; //DDS, start loading header for( int i = 0; i < sizeof( header ); i++ ) { FileArchive->Read( (*pheader) ); pheader++; } //close the file, no longer needed FileArchive->Close(); if( IsDDSCubeMap( header ) ) { static CHashString DX9CubeTexObj(_T("CDX9CubeTextureObject")); pTexture = CreateTextureObject( name, &DX9CubeTexObj); pTexture->LoadFromFile( name->GetString() ); } } return pTexture; }
void CPiTexture::LoadToGPU() { if (m_egl_image) { if (m_loadedToGPU) { // nothing to load - probably same image (no change) return; } if (m_texture == 0) { // Have OpenGL generate a texture object handle for us // this happens only one time - the first time the texture is loaded CreateTextureObject(); } // Bind the texture object glBindTexture(GL_TEXTURE_2D, m_texture); m_loadedToGPU = true; return; } CGLTexture::LoadToGPU(); }
/// \brief Adds a texture to the manager and returns a pointer to the object. If object already /// exists, increments its internal reference count and returns the object. Takes /// a structure of type TEXTUREOBJECTPARAMS DWORD CTextureManager::OnAddTexture(DWORD size, void *params) { //maybe change this to a loader? But texture objects should not exist in the hierarchy. //get the param structure TEXTUREOBJECTPARAMS *texObjParams; IBaseTextureObject * currentTexture = NULL; TEXTURENAMEMAP::iterator cur; texObjParams = (TEXTUREOBJECTPARAMS *)params; VERIFY_MESSAGE_SIZE(sizeof(TEXTUREOBJECTPARAMS), size); //look for it if( texObjParams->Name != NULL ) { // convert to safe file name StdString szFileName = texObjParams->Name->GetString(); szFileName.MakeSafeFileName(); CHashString hashFile(szFileName); //do we have it in the mapping already? TEXTURENAMEMAP::iterator itr = m_TextureNameMap.find( hashFile.GetUniqueID() ); if (itr != m_TextureNameMap.end()) currentTexture = itr->second; if( currentTexture != NULL ) { currentTexture->IncrementRefCount(); } else { if (texObjParams->bLoad) { if (m_currentTexMemArea == TEX_MEM_VIDEO) { //new texture //check extension if( _tcsstr( hashFile.GetString(), ".hdr" )!= NULL ) { static CHashString texName(_T("CDX9TextureObject")); currentTexture = (ITextureObject*)CreateTextureObject( &hashFile, &texName); assert( currentTexture ); currentTexture->SetTextureName( &hashFile ); currentTexture->LoadFromFile(hashFile.GetString() ); }else if( _tcsstr( hashFile.GetString(), ".ant" )!= NULL ) { static CHashString aniTexObj(_T("CAnimatedTextureObject") ); currentTexture = CreateTextureObject( &hashFile, &aniTexObj); currentTexture->LoadFromFile(hashFile.GetString() ); }else if( _tcsstr( hashFile.GetString(), _T(".dds") ) != NULL ) { //we can automatically load cubemap textures if it is a cubemap texture currentTexture = LoadCubeDDSTexture( &hashFile ); } } // use the internal loader as it deals with a lot of issues // (ie. linear vs. tiled texture alignments/restrictions) for us. // and gets around the bug in DevIL on small mip levels of textures if( !currentTexture ) { static CHashString DX9TexObj(_T("CDX9TextureObject")); currentTexture = CreateTextureObject( &hashFile, &DX9TexObj); currentTexture->SetTextureName( &hashFile ); if (!currentTexture->LoadFromFile( hashFile.GetString() )) { DeleteTextureObject( currentTexture ); currentTexture = NULL; } } //try loading file by extension if( !currentTexture ) { currentTexture = LoadTextureByExtension( &hashFile ); } if( !currentTexture ) { // log message about creating or allocating memory m_ToolBox->Log( LOGERROR, _T("Could not create texture %s\n"), hashFile.GetString() ); return MSG_ERROR; } } else { currentTexture = texObjParams->TextureObjectInterface; currentTexture->IncrementRefCount(); } //add to internal list m_TextureNameMap[hashFile.GetUniqueID()] = currentTexture; } //set the return value texObjParams->TextureObjectInterface = currentTexture; } else //No name/filename specified, return nothing { texObjParams->TextureObjectInterface = NULL; } return MSG_HANDLED_PROCEED; }
void CGLTexture::LoadToGPU() { if (!m_pixels) { // nothing to load - probably same image (no change) return; } if (m_texture == 0) { // Have OpenGL generate a texture object handle for us // this happens only one time - the first time the texture is loaded CreateTextureObject(); } // Bind the texture object glBindTexture(GL_TEXTURE_2D, m_texture); GLenum filter = (m_scalingMethod == TEXTURE_SCALING::NEAREST ? GL_NEAREST : GL_LINEAR); // Set the texture's stretching properties if (IsMipmapped()) { GLenum mipmapFilter = (m_scalingMethod == TEXTURE_SCALING::NEAREST ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmapFilter); #ifndef HAS_GLES // Lower LOD bias equals more sharpness, but less smooth animation glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.5f); if (!m_isOglVersion3orNewer) glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); #endif } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); unsigned int maxSize = CServiceBroker::GetRenderSystem()->GetMaxTextureSize(); if (m_textureHeight > maxSize) { CLog::Log(LOGERROR, "GL: Image height %d too big to fit into single texture unit, truncating to %u", m_textureHeight, maxSize); m_textureHeight = maxSize; } if (m_textureWidth > maxSize) { CLog::Log(LOGERROR, "GL: Image width %d too big to fit into single texture unit, truncating to %u", m_textureWidth, maxSize); #ifndef HAS_GLES glPixelStorei(GL_UNPACK_ROW_LENGTH, m_textureWidth); #endif m_textureWidth = maxSize; } #ifndef HAS_GLES GLenum format = GL_BGRA; GLint numcomponents = GL_RGBA; switch (m_format) { case XB_FMT_DXT1: format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; case XB_FMT_DXT3: format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; case XB_FMT_DXT5: case XB_FMT_DXT5_YCoCg: format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; case XB_FMT_RGB8: format = GL_RGB; numcomponents = GL_RGB; break; case XB_FMT_A8R8G8B8: default: break; } if ((m_format & XB_FMT_DXT_MASK) == 0) { glTexImage2D(GL_TEXTURE_2D, 0, numcomponents, m_textureWidth, m_textureHeight, 0, format, GL_UNSIGNED_BYTE, m_pixels); } else { glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, m_textureWidth, m_textureHeight, 0, GetPitch() * GetRows(), m_pixels); } if (IsMipmapped() && m_isOglVersion3orNewer) { glGenerateMipmap(GL_TEXTURE_2D); } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); #else // GLES version // All incoming textures are BGRA, which GLES does not necessarily support. // Some (most?) hardware supports BGRA textures via an extension. // If not, we convert to RGBA first to avoid having to swizzle in shaders. // Explicitly define GL_BGRA_EXT here in the case that it's not defined by // system headers, and trust the extension list instead. #ifndef GL_BGRA_EXT #define GL_BGRA_EXT 0x80E1 #endif GLint internalformat; GLenum pixelformat; switch (m_format) { default: case XB_FMT_RGBA8: internalformat = pixelformat = GL_RGBA; break; case XB_FMT_RGB8: internalformat = pixelformat = GL_RGB; break; case XB_FMT_A8R8G8B8: if (CServiceBroker::GetRenderSystem()->IsExtSupported("GL_EXT_texture_format_BGRA8888") || CServiceBroker::GetRenderSystem()->IsExtSupported("GL_IMG_texture_format_BGRA8888")) { internalformat = pixelformat = GL_BGRA_EXT; } else if (CServiceBroker::GetRenderSystem()->IsExtSupported("GL_APPLE_texture_format_BGRA8888")) { // Apple's implementation does not conform to spec. Instead, they require // differing format/internalformat, more like GL. internalformat = GL_RGBA; pixelformat = GL_BGRA_EXT; } else { SwapBlueRed(m_pixels, m_textureHeight, GetPitch()); internalformat = pixelformat = GL_RGBA; } break; } glTexImage2D(GL_TEXTURE_2D, 0, internalformat, m_textureWidth, m_textureHeight, 0, pixelformat, GL_UNSIGNED_BYTE, m_pixels); if (IsMipmapped()) { glGenerateMipmap(GL_TEXTURE_2D); } #endif VerifyGLState(); if (!m_bCacheMemory) { _aligned_free(m_pixels); m_pixels = NULL; } m_loadedToGPU = true; }
void CGLTexture::LoadToGPU() { if (!m_pixels) { // nothing to load - probably same image (no change) return; } if (m_texture == 0) { // Have OpenGL generate a texture object handle for us // this happens only one time - the first time the texture is loaded CreateTextureObject(); } // Bind the texture object glBindTexture(GL_TEXTURE_2D, m_texture); // Set the texture's stretching properties if (IsMipmapped()) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); #ifndef HAS_GLES // Lower LOD bias equals more sharpness, but less smooth animation glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.5f); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); #endif } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); unsigned int maxSize = g_Windowing.GetMaxTextureSize(); if (m_textureHeight > maxSize) { CLog::Log(LOGERROR, "GL: Image height %d too big to fit into single texture unit, truncating to %u", m_textureHeight, maxSize); m_textureHeight = maxSize; } if (m_textureWidth > maxSize) { CLog::Log(LOGERROR, "GL: Image width %d too big to fit into single texture unit, truncating to %u", m_textureWidth, maxSize); #ifndef HAS_GLES glPixelStorei(GL_UNPACK_ROW_LENGTH, m_textureWidth); m_textureWidth = maxSize; } GLenum format = GL_BGRA; GLint numcomponents = GL_RGBA; switch (m_format) { case XB_FMT_DXT1: format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; case XB_FMT_DXT3: format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; case XB_FMT_DXT5: case XB_FMT_DXT5_YCoCg: format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; case XB_FMT_RGB8: format = GL_RGB; numcomponents = GL_RGB; break; case XB_FMT_A8R8G8B8: default: break; } if ((m_format & XB_FMT_DXT_MASK) == 0) { glTexImage2D(GL_TEXTURE_2D, 0, numcomponents, m_textureWidth, m_textureHeight, 0, format, GL_UNSIGNED_BYTE, m_pixels); } else { // changed from glCompressedTexImage2D to support GL < 1.3 glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, format, m_textureWidth, m_textureHeight, 0, GetPitch() * GetRows(), m_pixels); } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); #else // GLES version m_textureWidth = maxSize; }