Пример #1
0
void ofxTexture::SubmitChanges()
{
    if(m_Locked) return;
    ilBindImage(m_ImageId);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_TextureId);
    {
        ILinfo info;
        iluGetImageInfo(&info);
        m_BytePerPixel = info.Bpp;
        m_Width = info.Width;
        m_Height = info.Height;
        m_UnitWidth = m_Width>0?1.0f/m_Width:0.0f;
        m_UnitHeight = m_Height>0?1.0f/m_Height:0.0f;
    }
    {
        GLenum format = m_BytePerPixel==3?GL_RGB:GL_RGBA;
        ILubyte* pixel_data = ilGetData();
        if(m_Compressed)
        {
            ILuint compressed_size;
            ILubyte* compressed_data;
            compressed_size = ilGetDXTCData(NULL, 0, IL_DXT3);
            compressed_data = new ILubyte[compressed_size];
            ilGetDXTCData(compressed_data, compressed_size, IL_DXT3);
            glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
                                      m_Width, m_Height, 0, compressed_size, compressed_data);
            delete[] compressed_data;
#ifdef _DEBUG
            ILuint uncompressed_size = m_Width*m_Height*m_BytePerPixel;
            float ratio = (float)compressed_size/uncompressed_size*100;
            ofLogNotice() <<"compressed texture, m_TextureId = "<<m_TextureId
                          <<endl<<"before "<<uncompressed_size/1024.0<<" Kbytes, after "<<compressed_size/1024.0<<" Kbytes, ratio = "<<ratio<<"%";
#endif
        }
        else
        {
            glTexImage2D(GL_TEXTURE_2D, 0, format, m_Width, m_Height, 0, format, GL_UNSIGNED_BYTE, pixel_data);
        }
    }
    {
        GLint param = GL_CLAMP_TO_EDGE;
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,param);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,param);
    }
    {
        GLint param = GL_NEAREST;
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, param);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, param);
        if(param == GL_LINEAR_MIPMAP_LINEAR || GL_LINEAR_MIPMAP_NEAREST)
        {
            glGenerateMipmap(GL_TEXTURE_2D);
        }
    }
}
Пример #2
0
static GLuint init_texture(const char *filename, int w, int h)
{
    GLuint   tex = 0;
    GLubyte *buf;
    FILE    *fp;

    if ((buf = (GLubyte *) malloc(8 * (w / 4) * (h / 4))))
    {
        if ((fp = fopen(filename, "rb")))
        {
            size_t sz = 8 * (w / 4) * (h / 4);

            if (fread(buf, 1, sz, fp) < sz)
                error("'%s' load truncated", filename);

            fclose(fp);
        }

        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                        GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                        GL_LINEAR);

        glTexParameterf(GL_TEXTURE_1D, GL_GENERATE_MIPMAP, GL_TRUE);

        glCompressedTexImage2DARB(GL_TEXTURE_2D, 0,
                                  GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
                                  w, h, 0, 8 * (w / 4) * (h / 4), buf);

        free(buf);
    }

    return tex;
}
Пример #3
0
//-----------------------------------------------------------------------------
// Name: loadCompressedTexture()
// Desc: 
//-----------------------------------------------------------------------------
unsigned int CDDS::loadCompressedTexture( GLint TexParameter)
{
    // NOTE: Unlike "lena.bmp", "lena.dds" actually contains its own mip-map 
    // levels, which are also compressed.
	//g_compressedTextureID=0;
    //DDS_IMAGE_DATA *pDDSImageData = 
	//LoadFile( filename ); 
	if(g_compressedTextureID!=0)
		return g_compressedTextureID;

    if( pDDSImageData != NULL )
    {
        int nHeight     = pDDSImageData->height;
        int nWidth      = pDDSImageData->width;
        int nNumMipMaps = pDDSImageData->numMipMaps; 

        int nBlockSize; 

        if( pDDSImageData->format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
            nBlockSize = 8;
        else
            nBlockSize = 16; 

        glGenTextures( 1, &g_compressedTextureID );
        glBindTexture( GL_TEXTURE_2D, g_compressedTextureID ); 

		if(TexParameter!=0)
		{
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexParameter );
		}
		else
		{
			if(nNumMipMaps>1)
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
			else
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

		}
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 
		if(((TexParameter==GL_LINEAR_MIPMAP_LINEAR)||(TexParameter==0))&&(nNumMipMaps>1))
			if(CDDS::AFNum>1.0f)
				glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, CDDS::AFNum ); 

        int nSize;
        int nOffset = 0; 

        // Load the mip-map levels 
		nNumMipMaps=max(1,nNumMipMaps);
        for( int i = 0; i < nNumMipMaps; ++i )
        {
            if( nWidth  == 0 ) nWidth  = 1;
            if( nHeight == 0 ) nHeight = 1; 

            nSize = ((nWidth+3)/4) * ((nHeight+3)/4) * nBlockSize; 

            glCompressedTexImage2DARB( GL_TEXTURE_2D,
                                       i,
                                       pDDSImageData->format,
                                       nWidth,
                                       nHeight,
                                       0,
                                       nSize,
                                       pDDSImageData->pixels + nOffset ); 

            nOffset += nSize; 

            // Half the image size for the next mip-map level...
            nWidth  = (nWidth  / 2);
            nHeight = (nHeight / 2);
        }
		
		isVRAM=true;
    } 

	
	return g_compressedTextureID;
} 
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBTextureCompression_nglCompressedTexImage2DARBBO(JNIEnv *env, jclass clazz, jint target, jint level, jint internalformat, jint width, jint height, jint border, jint imageSize, jlong pData_buffer_offset, jlong function_pointer) {
	const GLvoid *pData_address = (const GLvoid *)(intptr_t)offsetToPointer(pData_buffer_offset);
	glCompressedTexImage2DARBPROC glCompressedTexImage2DARB = (glCompressedTexImage2DARBPROC)((intptr_t)function_pointer);
	glCompressedTexImage2DARB(target, level, internalformat, width, height, border, imageSize, pData_address);
}
Пример #5
0
	//* Creation / loading methods ********************************************
	void GLTexture::createInternalResourcesImpl(void)
    {
		if (!GLEW_VERSION_1_2 && mTextureType == TEX_TYPE_3D)
			OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
				"3D Textures not supported before OpenGL 1.2", 
				"GLTexture::createInternalResourcesImpl");

		// Convert to nearest power-of-two size if required
        mWidth = GLPixelUtil::optionalPO2(mWidth);      
        mHeight = GLPixelUtil::optionalPO2(mHeight);
        mDepth = GLPixelUtil::optionalPO2(mDepth);
		

		// Adjust format if required
		mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage);
		
		// Check requested number of mipmaps
		size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
		mNumMipmaps = mNumRequestedMipmaps;
		if(mNumMipmaps>maxMips)
			mNumMipmaps = maxMips;
		
		// Generate texture name
        glGenTextures( 1, &mTextureID );
		
		// Set texture type
		glBindTexture( getGLTextureTarget(), mTextureID );
        
		// This needs to be set otherwise the texture doesn't get rendered
		if (GLEW_VERSION_1_2)
			glTexParameteri( getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps );
        
        // Set some misc default parameters so NVidia won't complain, these can of course be changed later
        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		if (GLEW_VERSION_1_2)
		{
			glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		}
		
		// If we can do automip generation and the user desires this, do so
		mMipmapsHardwareGenerated = 
			Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP);
		// NVIDIA 175.16 drivers break hardware mip generation for non-compressed
		// textures - disable until fixed
		// Leave hardware gen on compressed textures since that's the only way we
		// can realistically do it since GLU doesn't support DXT
		// However DON'T do this on Apple, their drivers aren't subject to this
		// problem yet and in fact software generation appears to cause a crash 
		// in some cases which I've yet to track down
#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE
		if (Root::getSingleton().getRenderSystem()->getCapabilities()->getVendor() == GPU_NVIDIA
			&& !PixelUtil::isCompressed(mFormat))
		{
			mMipmapsHardwareGenerated = false;
		}
#endif
		if((mUsage & TU_AUTOMIPMAP) &&
		    mNumRequestedMipmaps && mMipmapsHardwareGenerated)
        {
            glTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE );
        }
		
		// Allocate internal buffer so that glTexSubImageXD can be used
		// Internal format
		GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma);
		size_t width = mWidth;
		size_t height = mHeight;
		size_t depth = mDepth;

		if(PixelUtil::isCompressed(mFormat))
		{
			// Compressed formats
			size_t size = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
			// Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
			// accept a 0 pointer like normal glTexImageXD
			// Run through this process for every mipmap to pregenerate mipmap piramid
			uint8 *tmpdata = new uint8[size];
			memset(tmpdata, 0, size);
			
			for(size_t mip=0; mip<=mNumMipmaps; mip++)
			{
				size = PixelUtil::getMemorySize(width, height, depth, mFormat);
				switch(mTextureType)
				{
					case TEX_TYPE_1D:
						glCompressedTexImage1DARB(GL_TEXTURE_1D, mip, format, 
							width, 0, 
							size, tmpdata);
						break;
					case TEX_TYPE_2D:
						glCompressedTexImage2DARB(GL_TEXTURE_2D, mip, format,
							width, height, 0, 
							size, tmpdata);
						break;
					case TEX_TYPE_3D:
						glCompressedTexImage3DARB(GL_TEXTURE_3D, mip, format,
							width, height, depth, 0, 
							size, tmpdata);
						break;
					case TEX_TYPE_CUBE_MAP:
						for(int face=0; face<6; face++) {
							glCompressedTexImage2DARB(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
								width, height, 0, 
								size, tmpdata);
						}
						break;
				};
				if(width>1)		width = width/2;
				if(height>1)	height = height/2;
				if(depth>1)		depth = depth/2;
			}
			delete [] tmpdata;
		}
		else
		{
			// Run through this process to pregenerate mipmap piramid
			for(size_t mip=0; mip<=mNumMipmaps; mip++)
			{
				// Normal formats
				switch(mTextureType)
				{
					case TEX_TYPE_1D:
						glTexImage1D(GL_TEXTURE_1D, mip, format,
							width, 0, 
							GL_RGBA, GL_UNSIGNED_BYTE, 0);
	
						break;
					case TEX_TYPE_2D:
						glTexImage2D(GL_TEXTURE_2D, mip, format,
							width, height, 0, 
							GL_RGBA, GL_UNSIGNED_BYTE, 0);
						break;
					case TEX_TYPE_3D:
						glTexImage3D(GL_TEXTURE_3D, mip, format,
							width, height, depth, 0, 
							GL_RGBA, GL_UNSIGNED_BYTE, 0);
						break;
					case TEX_TYPE_CUBE_MAP:
						for(int face=0; face<6; face++) {
							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
								width, height, 0, 
								GL_RGBA, GL_UNSIGNED_BYTE, 0);
						}
						break;
				};
				if(width>1)		width = width/2;
				if(height>1)	height = height/2;
				if(depth>1)		depth = depth/2;
			}
		}
		_createSurfaceList();
		// Get final internal format
		mFormat = getBuffer(0,0)->getFormat();
	}
Пример #6
0
    //* Creation / loading methods ********************************************
    void GLTexture::createInternalResourcesImpl(void)
    {
        if (!GLEW_VERSION_1_2 && mTextureType == TEX_TYPE_3D)
            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
                "3D Textures not supported before OpenGL 1.2", 
                "GLTexture::createInternalResourcesImpl");

        if (!GLEW_VERSION_2_0 && mTextureType == TEX_TYPE_2D_ARRAY)
            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
                "2D texture arrays not supported before OpenGL 2.0", 
                "GLTexture::createInternalResourcesImpl");

        // Convert to nearest power-of-two size if required
        mWidth = GLPixelUtil::optionalPO2(mWidth);      
        mHeight = GLPixelUtil::optionalPO2(mHeight);
        mDepth = GLPixelUtil::optionalPO2(mDepth);
        

        // Adjust format if required
        mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage);
        
        // Check requested number of mipmaps
        size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
        mNumMipmaps = mNumRequestedMipmaps;
        if(mNumMipmaps>maxMips)
            mNumMipmaps = maxMips;

        // Check if we can do HW mipmap generation
        mMipmapsHardwareGenerated =
            Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP);
        
        // Generate texture name
        glGenTextures( 1, &mTextureID );
        
        // Set texture type
        mGLSupport.getStateCacheManager()->bindGLTexture( getGLTextureTarget(), mTextureID );
        
        // This needs to be set otherwise the texture doesn't get rendered
        if (GLEW_VERSION_1_2)
            mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(),
                GL_TEXTURE_MAX_LEVEL, mNumMipmaps);
        
        // Set some misc default parameters so NVidia won't complain, these can of course be changed later
        mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        if (GLEW_VERSION_1_2)
        {
            mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        }

        if((mUsage & TU_AUTOMIPMAP) &&
            mNumRequestedMipmaps && mMipmapsHardwareGenerated)
        {
            mGLSupport.getStateCacheManager()->setTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE );
        }
        
        // Allocate internal buffer so that glTexSubImageXD can be used
        // Internal format
        GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma);
        uint32 width = mWidth;
        uint32 height = mHeight;
        uint32 depth = mDepth;

        if(PixelUtil::isCompressed(mFormat))
        {
            // Compressed formats
            GLsizei size = static_cast<GLsizei>(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat));
            // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
            // accept a 0 pointer like normal glTexImageXD
            // Run through this process for every mipmap to pregenerate mipmap piramid
            uint8 *tmpdata = new uint8[size];
            memset(tmpdata, 0, size);
            
            for(uint8 mip=0; mip<=mNumMipmaps; mip++)
            {
                size = static_cast<GLsizei>(PixelUtil::getMemorySize(width, height, depth, mFormat));
                switch(mTextureType)
                {
                    case TEX_TYPE_1D:
                        glCompressedTexImage1DARB(GL_TEXTURE_1D, mip, format, 
                            width, 0, 
                            size, tmpdata);
                        break;
                    case TEX_TYPE_2D:
                        glCompressedTexImage2DARB(GL_TEXTURE_2D, mip, format,
                            width, height, 0, 
                            size, tmpdata);
                        break;
                    case TEX_TYPE_2D_ARRAY:
                    case TEX_TYPE_3D:
                        glCompressedTexImage3DARB(getGLTextureTarget(), mip, format,
                            width, height, depth, 0, 
                            size, tmpdata);
                        break;
                    case TEX_TYPE_CUBE_MAP:
                        for(int face=0; face<6; face++) {
                            glCompressedTexImage2DARB(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
                                width, height, 0, 
                                size, tmpdata);
                        }
                        break;
                    case TEX_TYPE_2D_RECT:
                        break;
                };
                if(width>1)
                    width = width/2;
                if(height>1)
                    height = height/2;
                if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY)
                    depth = depth/2;
            }
            delete [] tmpdata;
        }
        else
        {
            // Run through this process to pregenerate mipmap pyramid
            for(uint8 mip=0; mip<=mNumMipmaps; mip++)
            {
                // Normal formats
                switch(mTextureType)
                {
                    case TEX_TYPE_1D:
                        glTexImage1D(GL_TEXTURE_1D, mip, format,
                            width, 0, 
                            GL_RGBA, GL_UNSIGNED_BYTE, 0);
    
                        break;
                    case TEX_TYPE_2D:
                        glTexImage2D(GL_TEXTURE_2D, mip, format,
                            width, height, 0, 
                            GL_RGBA, GL_UNSIGNED_BYTE, 0);
                        break;
                    case TEX_TYPE_2D_ARRAY:
                    case TEX_TYPE_3D:
                        glTexImage3D(getGLTextureTarget(), mip, format,
                            width, height, depth, 0, 
                            GL_RGBA, GL_UNSIGNED_BYTE, 0);
                        break;
                    case TEX_TYPE_CUBE_MAP:
                        for(int face=0; face<6; face++) {
                            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
                                width, height, 0, 
                                GL_RGBA, GL_UNSIGNED_BYTE, 0);
                        }
                        break;
                    case TEX_TYPE_2D_RECT:
                        break;
                };
                if(width>1)
                    width = width/2;
                if(height>1)
                    height = height/2;
                if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY)
                    depth = depth/2;
            }
        }
        _createSurfaceList();
        // Get final internal format
        mFormat = getBuffer(0,0)->getFormat();
    }
Пример #7
0
/////temp
void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, 
                                      GLint border, GLsizei imageSize, const GLvoid *data)
{
 glCompressedTexImage2DARB(target, level, internalformat,width,height,border,imageSize,data);
}
		bool ITextureManagerOpenGL::SetCompressedTextureData(ITexture *tex, IImageITX* itx)
		{
			if (tex && itx)
			{
				glBindTexture(GL_TEXTURE_2D, *(GLuint*)tex->GetTexture());
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

				SetTextureSize(tex,itx->GetWidth(),itx->GetHeight());

				int blockSize=16;
				if (itx->GetFormat()==IImageITX::ITXF_DXT1 || itx->GetFormat()==IImageITX::ITXF_DXT1a || itx->GetFormat()==IImageITX::ITXF_DXT1nm)
					blockSize=8;

				int Format;
				switch (itx->GetFormat())
				{
				/*case IImageITX::ITXF_RGBA:
					Format=GL_COMPRESSED_RGBA_ARB;
					break;*/
				case IImageITX::ITXF_DXT1:
					Format=GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
					break;
				case IImageITX::ITXF_DXT1a:
					Format=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
					break;
				case IImageITX::ITXF_DXT1nm:
					Format=GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
					break;
				case IImageITX::ITXF_DXT3:
					Format=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
					break;
				case IImageITX::ITXF_DXT5:
				case IImageITX::ITXF_DXT5nm:
					Format=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
					break;
				case IImageITX::ITXF_ATI1:
				case IImageITX::ITXF_ATI2_3Dc:
					Format=GL_ATI_texture_compression_3dc;
					break;
				}

				int nSize;
				int nOffset = 0;
				int Width=itx->GetWidth();
				int Height=itx->GetHeight();
				int NumMipMaps=itx->GetMipMapCount();

				for( int i = 0; i < NumMipMaps; ++i )
				{
					if( Width  == 0 ) Width  = 1;
					if( Height == 0 ) Height = 1;

					nSize = ((Width+3)/4) * ((Height+3)/4) * blockSize;

					if (itx->GetFormat()==IImageITX::ITXF_RGBA)
					{
						glTexImage2D(GL_TEXTURE_2D, 
							i, 
							GL_RGBA, 
							Width, 
							Height, 
							0, 
							GL_BGRA_EXT, 
							GL_UNSIGNED_BYTE, 
							(unsigned char*)itx->GetData() + nOffset);
					}else{
						glCompressedTexImage2DARB( GL_TEXTURE_2D,
							i,
							Format,
							Width,
							Height,
							0,
							nSize,
							(unsigned char*)itx->GetData() + nOffset );
					}

					nOffset += nSize;

					// Half the image size for the next mip-map level...
					Width  = (Width  / 2);
					Height = (Height / 2);
				}

				glBindTexture(GL_TEXTURE_2D, 0);

				return true;
			}
			return false;
		}
Пример #9
0
/** Documented at declaration */
struct dxt_decoder*
dxt_decoder_create(enum dxt_type type, int width, int height, enum dxt_format out_format, int legacy)
{
    struct dxt_decoder* decoder = (struct dxt_decoder*)malloc(sizeof(struct dxt_decoder));
    
    assert(out_format == DXT_FORMAT_RGBA || out_format == DXT_FORMAT_YUV422);
    assert(out_format == DXT_FORMAT_RGBA ||
        (out_format == DXT_FORMAT_YUV422 && width % 2 == 0)); /* width % 2 for YUV422 */

    if ( decoder == NULL )
        return NULL;
    decoder->type = type;
    decoder->width = width;
    decoder->height = height;
    decoder->out_format = out_format;
    decoder->legacy = legacy;
    //glutReshapeWindow(1, 1);
    
    // Create empty texture
    glGenTextures(1, &decoder->compressed_tex);
    glBindTexture(GL_TEXTURE_2D, decoder->compressed_tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    if ( decoder->type == DXT_TYPE_DXT5_YCOCG )
        glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, decoder->width, decoder->height, 0,
                        ((decoder->width + 3) / 4 * 4) * ((decoder->height + 3) / 4 * 4), 0);
    else
        glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, decoder->width, decoder->height, 0,
                        ((decoder->width + 3) / 4 * 4) * ((decoder->height + 3) / 4 * 4) / 2, 0);
    
    // Create fbo    
    glGenFramebuffers(1, &decoder->fbo_rgba);
    glBindFramebuffer(GL_FRAMEBUFFER, decoder->fbo_rgba);
    
    glGenTextures(1, &decoder->uncompressed_rgba_tex); 
    glBindTexture(GL_TEXTURE_2D, decoder->uncompressed_rgba_tex); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexImage2D(GL_TEXTURE_2D, 0 , DXT_IMAGE_GL_FORMAT, decoder->width, decoder->height, 0, GL_RGBA, DXT_IMAGE_GL_TYPE, 0); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, decoder->uncompressed_rgba_tex, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
    // Create program [display] and its shader
    decoder->program_display = glCreateProgram();  
    // Create shader from file
    decoder->shader_fragment_display = 0;
    switch(decoder->type) 
    {
        case DXT_TYPE_DXT5_YCOCG:
                if(legacy)
                    decoder->shader_fragment_display = dxt_shader_create_from_source(fp_display_dxt5ycocg_legacy, GL_FRAGMENT_SHADER);
                else
                    decoder->shader_fragment_display = dxt_shader_create_from_source(fp_display_dxt5ycocg, GL_FRAGMENT_SHADER);
                break;
        case DXT_TYPE_DXT1:
                if(legacy)
                    decoder->shader_fragment_display = dxt_shader_create_from_source(fp_display_legacy, GL_FRAGMENT_SHADER);
                else
                    decoder->shader_fragment_display = dxt_shader_create_from_source(fp_display, GL_FRAGMENT_SHADER);
                break;
        case DXT_TYPE_DXT1_YUV:
                if(legacy)
                    decoder->shader_fragment_display = dxt_shader_create_from_source(fp_display_dxt1_yuv_legacy, GL_FRAGMENT_SHADER);
                else
                    decoder->shader_fragment_display = dxt_shader_create_from_source(fp_display_dxt1_yuv, GL_FRAGMENT_SHADER);
                break;
    }
    if(legacy) {
        decoder->shader_vertex_display = dxt_shader_create_from_source(vp_compress_legacy, GL_VERTEX_SHADER);
    } else {
        decoder->shader_vertex_display = dxt_shader_create_from_source(vp_compress, GL_VERTEX_SHADER);
    }
    if ( decoder->shader_fragment_display == 0 || decoder->shader_vertex_display == 0 )
        return NULL;
    // Attach shader to program and link the program
    glAttachShader(decoder->program_display, decoder->shader_fragment_display);
    glAttachShader(decoder->program_display, decoder->shader_vertex_display);
    glLinkProgram(decoder->program_display);
    
    if(out_format == DXT_FORMAT_YUV422) {
            glGenTextures(1, &decoder->uncompressed_yuv422_tex);
            glBindTexture(GL_TEXTURE_2D, decoder->uncompressed_yuv422_tex); 
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
            glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, decoder->width / 2, decoder->height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); 
            
            glGenFramebuffers(1, &decoder->fbo_yuv422);
            
            if(legacy) {
                decoder->shader_fragment_rgba_to_yuv422 = dxt_shader_create_from_source(fp_display_rgba_to_yuv422_legacy, GL_FRAGMENT_SHADER);
                decoder->shader_vertex_rgba_to_yuv422 = dxt_shader_create_from_source(vp_compress_legacy, GL_VERTEX_SHADER);
            } else {
                decoder->shader_fragment_rgba_to_yuv422 = dxt_shader_create_from_source(fp_display_rgba_to_yuv422, GL_FRAGMENT_SHADER);
                decoder->shader_vertex_rgba_to_yuv422 = dxt_shader_create_from_source(vp_compress, GL_VERTEX_SHADER);
            }
            
            decoder->program_rgba_to_yuv422 = glCreateProgram();
            glAttachShader(decoder->program_rgba_to_yuv422, decoder->shader_fragment_rgba_to_yuv422);
            glAttachShader(decoder->program_rgba_to_yuv422, decoder->shader_vertex_rgba_to_yuv422);
            glLinkProgram(decoder->program_rgba_to_yuv422);
            
            glUseProgram(decoder->program_rgba_to_yuv422);
            glUniform1i(glGetUniformLocation(decoder->program_rgba_to_yuv422, "image"), 0);
            glUniform1f(glGetUniformLocation(decoder->program_rgba_to_yuv422, "imageWidth"),
                        (GLfloat) decoder->width);

            if(!decoder->legacy) {
#if ! defined HAVE_MACOSX || OS_VERSION_MAJOR >= 11
                GLint g_vertexLocation;
                GLuint g_vertices;

                // ToDo:
                glGenVertexArrays(1, &decoder->g_vao_422);

                // ToDo:
                glBindVertexArray(decoder->g_vao_422);

                // http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml
                g_vertexLocation = glGetAttribLocation(decoder->program_rgba_to_yuv422, "position");

                // http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml
                glGenBuffers(1, &g_vertices);

                // http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml
                glBindBuffer(GL_ARRAY_BUFFER, g_vertices);

                // http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml
                //glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);
                glBufferData(GL_ARRAY_BUFFER, 8 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);

                // http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml
                glUseProgram(decoder->program_rgba_to_yuv422);

                // http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml
                glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);

                // http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml
                glEnableVertexAttribArray(g_vertexLocation);

                glBindFragDataLocation(decoder->program_rgba_to_yuv422, 0, "colorOut");
#endif
            }
                        
            glUseProgram(0);
    }
    if(!decoder->legacy) {
#if ! defined HAVE_MACOSX || OS_VERSION_MAJOR >= 11
        GLint g_vertexLocation;
        GLuint g_vertices;

        // ToDo:
        glGenVertexArrays(1, &decoder->g_vao);

        // ToDo:
        glBindVertexArray(decoder->g_vao);

        // http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml
        g_vertexLocation = glGetAttribLocation(decoder->program_display, "position");

        // http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml
        glGenBuffers(1, &g_vertices);

        // http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml
        glBindBuffer(GL_ARRAY_BUFFER, g_vertices);

        // http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml
        //glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);
        glBufferData(GL_ARRAY_BUFFER, 8 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);

        // http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml
        glUseProgram(decoder->program_display);

        // http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml
        glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);

        // http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml
        glEnableVertexAttribArray(g_vertexLocation);

        glBindFragDataLocation(decoder->program_display, 0, "colorOut");

        glUseProgram(0);
#endif
    }
    
    return decoder;
}
Пример #10
0
/** Documented at declaration */
int
dxt_decoder_decompress(struct dxt_decoder* decoder, unsigned char* image_compressed, DXT_IMAGE_TYPE* image)
{    
#ifdef RTDXT_DEBUG
    TIMER_INIT();
    
    TIMER_START();
#endif
    glBindTexture(GL_TEXTURE_2D, decoder->compressed_tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    if ( decoder->type == DXT_TYPE_DXT5_YCOCG )
        glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
                        (decoder->width + 3) / 4 * 4, decoder->height, 0, ((decoder->width + 3) / 4 * 4) * ((decoder->height + 3) / 4 * 4), image_compressed);
    else
        glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
                        (decoder->width + 3) / 4 * 4, decoder->height, 0, ((decoder->width + 3) / 4 * 4) * ((decoder->height + 3) / 4 * 4) / 2, image_compressed);
#ifdef RTDXT_DEBUG
    glFinish();
    TIMER_STOP_PRINT("Texture Load:      ");
    
    TIMER_START();
#endif
    
    // Render to framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, decoder->fbo_rgba);
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, decoder->width, decoder->height);

    glUseProgram(decoder->program_display);
    
    glBindTexture(GL_TEXTURE_2D, decoder->compressed_tex);
    
    if(decoder->legacy) {
        glBegin(GL_QUADS);
        glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
        glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
        glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
        glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
        glEnd();
    } else {
#if ! defined HAVE_MACOSX || OS_VERSION_MAJOR >= 11
        glBindVertexArray(decoder->g_vao);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glBindVertexArray(0);
#endif
    }
    
    glUseProgram(0);
#ifdef RTDXT_DEBUG
    glFinish();
    TIMER_STOP_PRINT("Texture Decompress:");
    
    TIMER_START();
#endif
    if(decoder->out_format != DXT_FORMAT_YUV422) { /* so RGBA */
            // Disable framebuffer
            glReadPixels(0, 0, decoder->width, decoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, image);
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
    } else {

            glBindFramebuffer(GL_FRAMEBUFFER, decoder->fbo_yuv422);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, decoder->uncompressed_yuv422_tex, 0);
            
            glBindTexture(GL_TEXTURE_2D, decoder->uncompressed_rgba_tex); /* to texturing unit 0 */

            glPushAttrib(GL_VIEWPORT_BIT);
            glViewport( 0, 0, decoder->width / 2, decoder->height);

            glUseProgram(decoder->program_rgba_to_yuv422);
            
            if(decoder->legacy) {
                glBegin(GL_QUADS);
                glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
                glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
                glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
                glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
                glEnd();
            } else {
#if ! defined HAVE_MACOSX || OS_VERSION_MAJOR >= 11
                glBindVertexArray(decoder->g_vao_422);
                glDrawArrays(GL_TRIANGLES, 0, 6);
                glBindVertexArray(0);
#endif
            }
            
            glPopAttrib();

            glReadPixels(0, 0, decoder->width / 2, decoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, image);
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
            glUseProgram(0);
    }
    
#ifdef RTDXT_DEBUG    
    glFinish();
    TIMER_STOP_PRINT("Texture Save:      ");
#endif
    
    return 0;
}
Пример #11
0
void DiGLTextureDrv::Upload(const DiPixelBox &src, const DiBox &dst, uint32 level, uint32 surface)
{
    glBindTexture(mGLTextureType, mTextureID);

    DiPixelFormat fmt = mParent->GetFormat();
    bool isCompressed = DiPixelBox::IsCompressedFormat(fmt);

    unsigned dataType = DiGLTypeMappings::GetDataType(mGLFormat);

    GLenum faceType = GL_TEXTURE_2D;
    if (mGLTextureType == GL_TEXTURE_CUBE_MAP)
        faceType = GL_TEXTURE_CUBE_MAP_POSITIVE_X + surface;

    if (isCompressed)
    {
        if (!src.IsConsecutive())
        {
            DI_WARNING("Compressed images should be consective.");
            return;
        }

        size_t size = src.GetConsecutiveSize();
        switch (mGLTextureType)
        {
        case GL_TEXTURE_2D:
        case GL_TEXTURE_CUBE_MAP:
            if (dst.left == 0 && dst.top == 0)
            {
                glCompressedTexImage2DARB(faceType, level,
                                          mGLFormat,
                                          dst.GetWidth(),
                                          dst.GetHeight(),
                                          0,
                                          size,
                                          src.data);
            }
            else
            {
                glCompressedTexSubImage2DARB(faceType, level,
                                             dst.left, dst.top,
                                             dst.GetWidth(), dst.GetHeight(),
                                             mGLFormat, size,
                                             src.data);
            }
            break;
        }
    }
    else
    {
        if (src.GetWidth() != src.rowPitch)
            glPixelStorei(GL_UNPACK_ROW_LENGTH, src.rowPitch);

        if (src.GetWidth() > 0 && src.GetHeight()*src.GetWidth() != src.slicePitch)
            glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (src.slicePitch / src.GetWidth()));

        if (src.left > 0 || src.top > 0)
            glPixelStorei(GL_UNPACK_SKIP_PIXELS, src.left + src.rowPitch * src.top);

        if ((src.GetWidth() * DiPixelBox::GetNumElemBytes(src.format)) & 3)
        {
            // Standard alignment of 4 is not right
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        }

        glGetError();

        switch (mGLTextureType)
        {
        case GL_TEXTURE_2D:
        case GL_TEXTURE_CUBE_MAP:
            if (dst.left == 0 && dst.top == 0)
            {
                glTexImage2D(faceType, level, mGLFormat, dst.GetWidth(), dst.GetHeight(),
                             0, mGLOriginFormat, dataType, src.data);
            }
            else
            {
                glTexSubImage2D(faceType, level,
                                dst.left, dst.top,
                                dst.GetWidth(), dst.GetHeight(),
                                mGLOriginFormat, dataType, src.data);
            }
            break;
        }

        GLenum glErr = glGetError();
        if (glErr != GL_NO_ERROR)
            DI_WARNING("Uploading texture (surface %d, level %d): %s", surface, level, (const char*)gluErrorString(glErr));
    }

    // restore
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    if (GLEW_VERSION_1_2)
        glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
Пример #12
0
void TextureManager::LoadBLP(GLuint id, Texture *tex)
{
	// Vars
	int offsets[16], sizes[16], w=0, h=0, type=0;
	GLint format = 0;
	char attr[4];

	if (useLocalFiles) {
		wxString texName(tex->name.c_str(), wxConvUTF8);
		BYTE *buffer = NULL;
		CxImage *image = NULL;

		if ((TryLoadLocalTexture(texName, CXIMAGE_FORMAT_PNG, &image) || 
			 TryLoadLocalTexture(texName, CXIMAGE_FORMAT_TGA, &image)) 
			 && image) {
			long size = image->GetWidth() * image->GetHeight() * 4;
			if (image->Encode2RGBA(buffer, size, true)) {
				tex->w = image->GetWidth();
				tex->h = image->GetHeight();
				tex->compressed = true;

				GLuint texFormat = GL_TEXTURE_2D;
				glBindTexture(texFormat, id);

				glTexImage2D(texFormat, 0, GL_RGBA8, image->GetWidth(), image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

				glTexParameteri(texFormat, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	// Linear Filtering
				glTexParameteri(texFormat, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	// Linear Filtering

				wxDELETE(image);
				wxDELETE(buffer);
				return;
			}
		}

	}

	// bind the texture
	glBindTexture(GL_TEXTURE_2D, id);
	
	MPQFile f(tex->name);
	if (g_modelViewer) {
		g_modelViewer->modelOpened->Add(wxString(tex->name.c_str(), wxConvUTF8));
	}
	if (f.isEof()) {
		tex->id = 0;
		wxLogMessage(wxT("Error: Could not load the texture '%s'"), wxString(tex->name.c_str(), wxConvUTF8).c_str());
		f.close();
		return;
	} else {
		//tex->id = id; // I don't see the id being set anywhere,  should I set it now?
		wxLogMessage(wxT("Loading texture: %s"), wxString(tex->name.c_str(), wxConvUTF8).c_str());
	}

	f.seek(4);
	f.read(&type,4);
	f.read(attr,4);
	f.read(&w,4);
	f.read(&h,4);
	f.read(offsets,4*16);
	f.read(sizes,4*16);

	tex->w = w;
	tex->h = h;

	bool hasmipmaps = (attr[3]>0);
	int mipmax = hasmipmaps ? 16 : 1;

	/*
	reference: http://en.wikipedia.org/wiki/.BLP
	*/
	//wxLogMessage(wxT("[BLP]: type: %d, encoding: %d, alphadepth: %d, alphaencoding: %d, mipmap: %d, %d*%d"), type, attr[0], attr[1], attr[2], attr[3], w, h);
	if (type == 0) { // JPEG compression
		/*
		 * DWORD JpegHeaderSize;
		 * BYTE[JpegHeaderSize] JpegHeader;
		 * struct MipMap[16]
		 * {
		 *     BYTE[???] JpegData;
		 * }
		 */
		wxLogMessage(wxT("Error: %s:%s#%d type=%d"), __FILE__, __FUNCTION__, __LINE__, type);

		BYTE *buffer = NULL;
		CxImage *image = NULL;
		unsigned char *buf = new unsigned char[sizes[0]];

		f.seek(offsets[0]);
		f.read(buf,sizes[0]);
		image = new CxImage(buf, sizes[0], CXIMAGE_FORMAT_JPG);

		if (image == NULL)
			return;

		long size = image->GetWidth() * image->GetHeight() * 4;
		image->Encode2RGBA(buffer, size);

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image->GetWidth(), image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

		wxDELETE(image);
		wxDELETE(buffer);
		wxDELETE(buf);
	} else if (type == 1) {
		if (attr[0] == 2) {
			/*
			Type 1 Encoding 2 AlphaDepth 0 (DXT1 no alpha)
			The image data is formatted using DXT1 compression with no alpha channel.

			Type 1 Encoding 2 AlphaDepth 1 (DXT1 one bit alpha)
			The image data is formatted using DXT1 compression with a one-bit alpha channel.

			Type 1 Encoding 2 AlphaDepth 8 (DXT3)
			The image data is formatted using DXT3 compression.

			Type 1 Encoding 2 AlphaDepth 8 AlphaEncoding 7 (DXT5)
			The image data are formatted using DXT5 compression.
			*/
			// encoding 2, directx compressed
			unsigned char *ucbuf = NULL;
			if (!video.supportCompression) 
				ucbuf = new unsigned char[w*h*4];
		
			format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
			int blocksize = 8;
			
			// guesswork here :(
			// new alpha bit depth == 4 for DXT3, alfred 2008/10/11
			if (attr[1]==8 || attr[1]==4) {
				format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
				blocksize = 16;
			}

			// Fix to the BLP2 format required in WoW 2.0 thanks to Linghuye (creator of MyWarCraftStudio)
			if (attr[1]==8 && attr[2]==7) {
				format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
				blocksize = 16;
			}

			tex->compressed = true;

			unsigned char *buf = new unsigned char[sizes[0]];

			// do every mipmap level
			for (size_t i=0; i<mipmax; i++) {
				if (w==0) w = 1;
				if (h==0) h = 1;
				if (offsets[i] && sizes[i]) {
					f.seek(offsets[i]);
					f.read(buf,sizes[i]);

					int size = ((w+3)/4) * ((h+3)/4) * blocksize;

					if (video.supportCompression) {
						glCompressedTexImage2DARB(GL_TEXTURE_2D, (GLint)i, format, w, h, 0, size, buf);
					} else {
						decompressDXTC(format, w, h, size, buf, ucbuf);					
						glTexImage2D(GL_TEXTURE_2D, (GLint)i, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ucbuf);
					}
					
				} else break;
				w >>= 1;
				h >>= 1;
			}

			wxDELETEA(buf);
			if (!video.supportCompression) 
				wxDELETEA(ucbuf);

		} else if (attr[0]==1) {
Пример #13
0
	//* Creation / loading methods ********************************************
	void GLTexture::createInternalResourcesImpl(void)
    {
		// Convert to nearest power-of-two size if required
        mWidth = GLPixelUtil::optionalPO2(mWidth);      
        mHeight = GLPixelUtil::optionalPO2(mHeight);
        mDepth = GLPixelUtil::optionalPO2(mDepth);
		

		// Adjust format if required
		mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage);
		
		// Check requested number of mipmaps
		size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
		mNumMipmaps = mNumRequestedMipmaps;
		if(mNumMipmaps>maxMips)
			mNumMipmaps = maxMips;
		
		// Generate texture name
        glGenTextures( 1, &mTextureID );
		
		// Set texture type
		glBindTexture( getGLTextureTarget(), mTextureID );
        
		// This needs to be set otherwise the texture doesn't get rendered
        glTexParameteri( getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps );
        
        // Set some misc default parameters so NVidia won't complain, these can of course be changed later
        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		
		// If we can do automip generation and the user desires this, do so
		mMipmapsHardwareGenerated = 
			Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP);
		if((mUsage & TU_AUTOMIPMAP) &&
		    mNumRequestedMipmaps && mMipmapsHardwareGenerated)
        {
            glTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE );
        }
		
		// Allocate internal buffer so that glTexSubImageXD can be used
		// Internal format
		GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat);
		size_t width = mWidth;
		size_t height = mHeight;
		size_t depth = mDepth;

		if(PixelUtil::isCompressed(mFormat))
		{
			// Compressed formats
			size_t size = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
			// Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
			// accept a 0 pointer like normal glTexImageXD
			// Run through this process for every mipmap to pregenerate mipmap piramid
			uint8 *tmpdata = new uint8[size];
			memset(tmpdata, 0, size);
			
			for(size_t mip=0; mip<=mNumMipmaps; mip++)
			{
				size = PixelUtil::getMemorySize(width, height, depth, mFormat);
				switch(mTextureType)
				{
					case TEX_TYPE_1D:
						glCompressedTexImage1DARB(GL_TEXTURE_1D, mip, format, 
							width, 0, 
							size, tmpdata);
						break;
					case TEX_TYPE_2D:
						glCompressedTexImage2DARB(GL_TEXTURE_2D, mip, format,
							width, height, 0, 
							size, tmpdata);
						break;
					case TEX_TYPE_3D:
						glCompressedTexImage3DARB(GL_TEXTURE_3D, mip, format,
							width, height, depth, 0, 
							size, tmpdata);
						break;
					case TEX_TYPE_CUBE_MAP:
						for(int face=0; face<6; face++) {
							glCompressedTexImage2DARB(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
								width, height, 0, 
								size, tmpdata);
						}
						break;
				};
				if(width>1)		width = width/2;
				if(height>1)	height = height/2;
				if(depth>1)		depth = depth/2;
			}
			delete [] tmpdata;
		}
		else
		{
			// Run through this process to pregenerate mipmap piramid
			for(size_t mip=0; mip<=mNumMipmaps; mip++)
			{
				// Normal formats
				switch(mTextureType)
				{
					case TEX_TYPE_1D:
						glTexImage1D(GL_TEXTURE_1D, mip, format,
							width, 0, 
							GL_RGBA, GL_UNSIGNED_BYTE, 0);
	
						break;
					case TEX_TYPE_2D:
						glTexImage2D(GL_TEXTURE_2D, mip, format,
							width, height, 0, 
							GL_RGBA, GL_UNSIGNED_BYTE, 0);
						break;
					case TEX_TYPE_3D:
						glTexImage3D(GL_TEXTURE_3D, mip, format,
							width, height, depth, 0, 
							GL_RGBA, GL_UNSIGNED_BYTE, 0);
						break;
					case TEX_TYPE_CUBE_MAP:
						for(int face=0; face<6; face++) {
							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
								width, height, 0, 
								GL_RGBA, GL_UNSIGNED_BYTE, 0);
						}
						break;
				};
				if(width>1)		width = width/2;
				if(height>1)	height = height/2;
				if(depth>1)		depth = depth/2;
			}
		}
		_createSurfaceList();
		// Get final internal format
		mFormat = getBuffer(0,0)->getFormat();
	}
Пример #14
0
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;
  }
Пример #15
0
static void
LoadTextures(GLuint n, const char *files[])
{
   GLuint i;

   NumTextures = n < MAX_TEXTURES ? n : MAX_TEXTURES;

   glGenTextures(n, Textures);

   SetTexParams();

   for (i = 0; i < n; i++) {
      GLint w, h;
      glBindTexture(GL_TEXTURE_2D, Textures[i]);
#if TEST_MIPMAPS
      {
         static const GLubyte color[9][4] = {
            {255, 0, 0},
            {0, 255, 0},
            {0, 0, 255},
            {0, 255, 255},
            {255, 0, 255},
            {255, 255, 0},
            {255, 128, 255},
            {128, 128, 128},
            {64, 64, 64}
         };

         GLubyte image[256*256*4];
         int i, level;
         w = h = 256;
         for (level = 0; level <= 8; level++) {
            for (i = 0; i < w * h; i++) {
               image[i*4+0] = color[level][0];
               image[i*4+1] = color[level][1];
               image[i*4+2] = color[level][2];
               image[i*4+3] = color[level][3];
            }
            printf("Load level %d: %d x %d\n", level, w>>level, h>>level);
            glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w>>level, h>>level, 0,
                         GL_RGBA, GL_UNSIGNED_BYTE, image);
         }
      }
#elif TEST_GEN_COMPRESSED_MIPMAPS
      {
         GLenum intFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
         int f;
         GLenum format;
         GLubyte *img = LoadRGBImage(files[i], &w, &h, &format);
         GLboolean write_compressed = GL_FALSE;
         GLboolean read_compressed = GL_FALSE;

         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
         glTexImage2D(GL_TEXTURE_2D, 0, intFormat, w, h, 0,
                      format, GL_UNSIGNED_BYTE, img);
         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
         free(img);

         glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
                                  GL_TEXTURE_INTERNAL_FORMAT, &f);
         printf("actual internal format 0x%x\n", f);

         if (write_compressed) {
            GLint i, sz, w, h;
            int num_levels = 8;
            for (i = 0; i < num_levels; i++) {
               char name[20], *buf;
               FILE *f;
               glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
               glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
               glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
                                        GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &sz);
               printf("Writing level %d: %d x %d  bytes: %d\n", i, w, h, sz);
               buf = malloc(sz);
               glGetCompressedTexImageARB(GL_TEXTURE_2D, i, buf);
               sprintf(name, "comp%d", i);
               f = fopen(name, "w");
               fwrite(buf, 1, sz, f);
               fclose(f);
               free(buf);
            }
         }

         if (read_compressed) {
            GLint i, sz, w, h;
            int num_levels = 8;
            for (i = 01; i < num_levels; i++) {
               char name[20], *buf;
               FILE *f;
               glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
               glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
               glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
                                        GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &sz);
               buf = malloc(sz);
               sprintf(name, "comp%d", i);
               printf("Reading level %d: %d x %d  bytes: %d from %s\n",
                      i, w, h, sz, name);
               f = fopen(name, "r");
               fread(buf, 1, sz, f);
               fclose(f);
               glCompressedTexImage2DARB(GL_TEXTURE_2D, i, intFormat,
                                         w, h, 0, sz, buf);
               free(buf);
            }
         }
      }
#else
      if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) {
         printf("Error: couldn't load %s\n", files[i]);
         exit(1);
      }
#endif
      TexAspect[i] = (float) w / (float) h;
      printf("Loaded %s\n", files[i]);
   }
}