| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- // Portions of this file have been written by using the "Compress YCOCgDXT" sample as a reference.
- // Please refer to http://developer.download.nvidia.com/SDK/10/opengl/samples.html#compress_YCoCgDXT for more information.
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- // Includes
- #include <windows.h>
- #include <assert.h>
- #include "DXTCompressor.h"
- #include "FrameBufferRenderBuffer.hpp"
- #include "ShaderSource.h"
- #include "OpenGLWindow.hpp"
- #include <map>
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- // Enable performance timing
- // #define DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- // Link with these libraries
- #pragma comment(lib, "glutstatic")
- #pragma comment(lib, "glew32")
- #pragma comment(lib, "cg")
- #pragma comment(lib, "cgGL")
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- // Defines
- #define DXTCOMPRESSOR_WINDOW_WIDTH 640
- #define DXTCOMPRESSOR_WINDOW_HEIGHT 480
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- // Static class data
- int DXTCompressor::m_initRefCount = 0;
- CGcontext DXTCompressor::m_cgContext;
- CGprofile DXTCompressor::m_cgVProfile;
- CGprofile DXTCompressor::m_cgFProfile;
- CGprogram DXTCompressor::m_compressVProg;
- CGprogram DXTCompressor::m_compressDXT1RGBAFProg;
- CGprogram DXTCompressor::m_compressDXT5RGBAFProg;
- CGprogram DXTCompressor::m_compressDXT1BGRAFProg;
- CGprogram DXTCompressor::m_compressDXT5BGRAFProg;
- int DXTCompressor::m_numIterations = 0;
- int DXTCompressor::m_currentImageWidth = 0;
- int DXTCompressor::m_currentImageHeight = 0;
- float DXTCompressor::m_lastCompressionTime = 0;
- float DXTCompressor::m_accumulatedTime = 0;
- float DXTCompressor::m_timeRunningCompressionShader = 0;
- float DXTCompressor::m_timeCopyingPixelDataToCPU = 0;
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- // Hash table to store framebuffer objects
- struct FramebufferObjectKeyCompare
- {
- bool operator()(int s1, int s2) const
- {
- return s1 < s2;
- }
- };
- typedef int FramebufferObjectKey;
- typedef class map< FramebufferObjectKey, FramebufferObject*, FramebufferObjectKeyCompare > FramebufferObjectHashtable;
- // The hashtable
- FramebufferObjectHashtable s_frameBuffersHash;
- // Hashkey generation
- FramebufferObjectKey GetHashKey( CompressionType compressionType, int width, int height )
- {
- return (int(compressionType) + width + (width*height));
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- // Typedef ticks
- typedef __int64 Ticks;
- inline Ticks GetTicks()
- {
- Ticks ticks;
- QueryPerformanceCounter( (LARGE_INTEGER*) &ticks);
- return ticks;
- }
- inline float TicksToMilliseconds( Ticks ticks )
- {
- LARGE_INTEGER freq;
- QueryPerformanceFrequency(&freq);
- return float(float(ticks) * 1000.0f / float(freq.QuadPart));
- }
- const int TIMER_STACK_SIZE = 256;
- static int g_currentStackId = 0;
- static Ticks g_startTrack[ TIMER_STACK_SIZE ];
- static Ticks g_endTrack[ TIMER_STACK_SIZE ];
- // Used for tracking time
- inline void StartTracking()
- {
- g_startTrack[ g_currentStackId++ ] = GetTicks();
- }
- inline void EndTracking()
- {
- g_endTrack[ --g_currentStackId ] = GetTicks();
- }
- inline float GetDeltaTimeInSeconds()
- {
- Ticks delta = g_endTrack[ g_currentStackId ] - g_startTrack[ g_currentStackId ];
- return TicksToMilliseconds( delta ) / 1000.0f;
- }
- inline float GetDeltaTimeInMilliseconds()
- {
- Ticks delta = g_endTrack[ g_currentStackId ] - g_startTrack[ g_currentStackId ];
- return TicksToMilliseconds( delta );
- }
- #endif // #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- DXTCompressor::DXTCompressor()
- {
- m_imageWidth = 0;
- m_imageHeight = 0;
- m_compressionType = DXT1;
- m_pCompressFbo = 0;
- m_compressFboTex = 0;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::cgErrorCallback()
- {
- CGerror lastError = cgGetError();
- if( lastError )
- {
- printf( "%s\n", cgGetErrorString( lastError ) );
- printf( "%s\n", cgGetLastListing( m_cgContext ) );
- assert( false );
- }
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- bool DXTCompressor::Initialize()
- {
- if( m_initRefCount == 0 )
- {
- if( !InitOpenGL() )
- return false;
- if( !InitCG() )
- return false;
- }
- m_initRefCount++;
- return true;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::Shutdown()
- {
- if( m_initRefCount > 0 )
- m_initRefCount--;
- if( m_initRefCount == 0 )
- {
- // Deallocate buffers
- DeallocateBuffers();
- // Shutdown cg stuff
- cgGLDisableProfile(m_cgVProfile);
- cgGLDisableProfile(m_cgFProfile);
- cgGLUnloadProgram( m_compressVProg );
- cgGLUnloadProgram( m_compressDXT1RGBAFProg );
- cgGLUnloadProgram( m_compressDXT5RGBAFProg );
- cgGLUnloadProgram( m_compressDXT1BGRAFProg );
- cgGLUnloadProgram( m_compressDXT5BGRAFProg );
- cgDestroyContext(m_cgContext);
- // Kill the OpenGL window
- KillGLWindow();
- }
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- bool DXTCompressor::InitOpenGL()
- {
- bool bFullscreen = false;
- #if 1
- // Compute desktop window width and height
- HWND desktopHwnd = GetDesktopWindow();
- RECT windowRect;
- GetWindowRect( desktopHwnd, &windowRect );
- int windowWidth = windowRect.right - windowRect.left;
- int windowHeight = windowRect.bottom - windowRect.top;
- bFullscreen = true;
- #else
- int windowWidth = 640;
- int windowHeight = 480;
- #endif
- // Create the window; this is needed in order to invoke OpenGL commands
- BOOL windowCreateSuccess = CreateGLWindow( "Testing", windowWidth, windowHeight, 32, bFullscreen, true );
- if( !windowCreateSuccess )
- return false;
- // Int GLEW
- glewInit();
- // Make sure these extensions are supported
- if (!glewIsSupported(
- "GL_VERSION_2_0 "
- "GL_ARB_vertex_program "
- "GL_ARB_fragment_program "
- "GL_NV_gpu_program4 "
- "GL_ARB_pixel_buffer_object "
- "GL_EXT_framebuffer_object "
- "GL_ARB_texture_compression "
- "GL_EXT_texture_compression_s3tc "
- "GL_EXT_texture_integer "
- ))
- {
- printf("Unable to load required OpenGL extension!\n");
- return false;
- }
- // Enable depth testing
- glEnable(GL_DEPTH_TEST);
- glClearColor(0.2, 0.2, 0.2, 1.0);
- // Report any errors to the console screen
- glutReportErrors();
- // Success
- return true;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- bool DXTCompressor::InitCG()
- {
- // Create Cg Context
- m_cgContext = cgCreateContext();
- cgSetErrorCallback( cgErrorCallback );
- // Load Cg programs
- m_cgVProfile = cgGLGetLatestProfile( CG_GL_VERTEX );
- m_cgFProfile = cgGLGetLatestProfile( CG_GL_FRAGMENT );
- // Shader compile options...
- const char *args[] =
- {
- "-unroll", "all",
- 0,
- };
- m_compressVProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgVProfile, "compress_vp", args );
- cgGLLoadProgram( m_compressVProg );
- m_compressDXT1RGBAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_DXT1_RGBA_fp", args );
- cgGLLoadProgram( m_compressDXT1RGBAFProg );
- m_compressDXT1BGRAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_DXT1_BGRA_fp", args );
- cgGLLoadProgram( m_compressDXT1BGRAFProg );
- m_compressDXT5RGBAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_YCoCgDXT5_RGBA_fp", args );
- cgGLLoadProgram( m_compressDXT5RGBAFProg );
- m_compressDXT5BGRAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_YCoCgDXT5_BGRA_fp", args );
- cgGLLoadProgram( m_compressDXT5BGRAFProg );
- return true;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- bool DXTCompressor::IsInitialized()
- {
- return (m_initRefCount != 0);
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- static GLuint CreateTexture( GLenum target, GLint internalformat, GLenum format, GLenum type, int w, int h )
- {
- GLuint tex;
- glGenTextures(1, &tex);
- glBindTexture(target, tex);
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(target, 0, internalformat, w, h, 0, format, type, 0);
- return tex;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- FramebufferObject* DXTCompressor::RequestFBO( CompressionType compressionType, int width, int height )
- {
- // Get hash key
- FramebufferObjectKey hashKey = GetHashKey( compressionType, width, height );
- // See if we have it in the hash
- if( s_frameBuffersHash.find( hashKey ) != s_frameBuffersHash.end() )
- {
- return s_frameBuffersHash[ hashKey ];
- }
- // Create the texture
- GLuint newTextureID = 0;
- FramebufferObject* pNewFrameBufferObject = new FramebufferObject();
- if( compressionType == DXT1 )
- {
- newTextureID = CreateTexture(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_INT, width/4, height/4);
- }
- else if( compressionType == DXT5_YCOCG )
- {
- newTextureID = CreateTexture(GL_TEXTURE_2D, GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_INT, width/4, height/4);
- }
- // Attach texture to framebuffer object
- pNewFrameBufferObject->Bind();
- pNewFrameBufferObject->AttachTexture(GL_TEXTURE_2D, newTextureID, GL_COLOR_ATTACHMENT0_EXT);
- pNewFrameBufferObject->IsValid();
- FramebufferObject::Disable();
- // Add to hash
- s_frameBuffersHash[ hashKey ] = pNewFrameBufferObject;
- // Return
- return pNewFrameBufferObject;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::DeallocateBuffers()
- {
- FramebufferObjectHashtable::iterator iter = s_frameBuffersHash.begin();
- while( iter != s_frameBuffersHash.end() )
- {
- // Delete object
- FramebufferObject* pFrameBufferObject = iter->second;
- GLuint textureID = pFrameBufferObject->GetAttachedTextureID();
- glDeleteTextures(1, &textureID);
- delete pFrameBufferObject;
- // Bump
- ++iter;
- }
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- static inline void SetParameter( CGprogram prog, char *name, float x, float y=0.0, float z=0.0, float w=0.0 )
- {
- CGparameter param = cgGetNamedParameter( prog, name );
- if( param )
- {
- cgGLSetParameter4f( param, x, y, z, w );
- }
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::SetShaderConstants()
- {
- SetParameter( m_compressDXT1RGBAFProg, "imageSize", m_imageWidth, m_imageHeight );
- SetParameter( m_compressDXT5RGBAFProg, "imageSize", m_imageWidth, m_imageHeight );
- SetParameter( m_compressDXT1BGRAFProg, "imageSize", m_imageWidth, m_imageHeight );
- SetParameter( m_compressDXT5BGRAFProg, "imageSize", m_imageWidth, m_imageHeight );
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- static inline void DrawQuad()
- {
- 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();
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::CompressInternal(bool sourceFormatIsBGRA)
- {
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- StartTracking();
- #endif
- glViewport(0, 0, m_imageWidth/4, m_imageHeight/4);
- glDisable(GL_DEPTH_TEST);
- cgGLBindProgram(m_compressVProg);
- cgGLEnableProfile(m_cgVProfile);
- if( m_compressionType == DXT5_YCOCG )
- {
- if (sourceFormatIsBGRA==false)
- cgGLBindProgram(m_compressDXT5RGBAFProg);
- else
- cgGLBindProgram(m_compressDXT5BGRAFProg);
- }
- else if( m_compressionType == DXT1 )
- {
- if (sourceFormatIsBGRA==false)
- cgGLBindProgram(m_compressDXT1RGBAFProg);
- else
- cgGLBindProgram(m_compressDXT1BGRAFProg);
- }
- else
- {
- assert(false );
- }
- cgGLEnableProfile(m_cgFProfile);
- glBindTexture(GL_TEXTURE_2D, m_imageTexId);
- SetShaderConstants();
- DrawQuad();
- cgGLDisableProfile(m_cgVProfile);
- cgGLDisableProfile(m_cgFProfile);
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- glFinish();
- EndTracking();
- m_timeRunningCompressionShader += GetDeltaTimeInMilliseconds();
- #endif
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- int DXTCompressor::GetBufferSize( CompressionType compressionType, int inputWidth, int inputHeight )
- {
- if( compressionType == DXT5_YCOCG )
- {
- int size = (inputWidth/4)*(inputHeight/4)*8;
- return sizeof(GLushort)*size;
- }
- else
- {
- int size = (inputWidth/4)*(inputHeight/4)*4;
- return sizeof(GLushort)*size;
- }
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::DoCompression( void* ppOutputData, bool sourceFormatIsBGRA )
- {
- if( m_compressionType == DXT5_YCOCG )
- {
- // Render to integer fbo
- m_pCompressFbo->Bind();
- CompressInternal(sourceFormatIsBGRA);
- // Readback data to host
- int size = (m_imageWidth/4)*(m_imageHeight/4)*8;
- GLushort *data = (GLushort *) ppOutputData;
- // Copy pixel data
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- StartTracking();
- #endif
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
- glReadPixels(0, 0, m_imageWidth/4, m_imageHeight/4, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, data);
- FramebufferObject::Disable();
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- EndTracking();
- m_timeCopyingPixelDataToCPU += GetDeltaTimeInMilliseconds();
- #endif
- }
- else if( m_compressionType == DXT1 )
- {
- // Render to integer fbo
- m_pCompressFbo->Bind();
- CompressInternal(sourceFormatIsBGRA);
- // Readback data to host
- int size = (m_imageWidth/4)*(m_imageHeight/4)*4;
- GLushort *data = (GLushort *) ppOutputData;
- // Copy pixel data
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- StartTracking();
- #endif
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
- glReadPixels(0, 0, m_imageWidth/4, m_imageHeight/4, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, data);
- FramebufferObject::Disable();
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- EndTracking();
- m_timeCopyingPixelDataToCPU += GetDeltaTimeInMilliseconds();
- #endif
- }
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- bool DXTCompressor::CompressImageData( CompressionType compressionType, const void *inputRGBA, int inputWidth, int inputHeight, void *outputData, bool bDisplayResults, bool sourceFormatIsBGRA )
- {
- // Make sure we're initialized
- if( !IsInitialized() )
- {
- printf( "You need to initialize DXTCompressor before calling compress!\n " );
- return false;
- }
- // Make sure the source width and height are divisible by 4
- // This is a requirement by the DXT compression algorithm
- if( !( (inputWidth%4)==0 && (inputHeight%4)==0 ) )
- {
- printf( "Error! Input image width and height must be multiple of 4, as required by DXT compression rules. You have passed in an image of %dx%d", inputWidth, inputHeight );
- return false;
- }
- // Accumulate width and heights
- m_numIterations++;
- m_currentImageWidth = inputWidth;
- m_currentImageHeight = inputHeight;
- // Instantiate the compressor
- DXTCompressor compressor;
- compressor.m_imageWidth = inputWidth;
- compressor.m_imageHeight = inputHeight;
- compressor.m_compressionType = compressionType;
- // Make a copy of the source data and flip the Y. OpenGL rendering has Y going down
- /*
- char* pFlippedData = new char[ inputWidth*inputHeight*4 ];
- {
- const int rowSize = inputWidth*4;
- char* pRunnerDest = pFlippedData + (rowSize*(inputHeight-1));
- const char* pRunnerSrc = (const char*)inputRGBA;
- for( int row = inputHeight-1; row >=0; row-- )
- {
- memcpy( pRunnerDest, pRunnerSrc, rowSize );
- pRunnerSrc += rowSize;
- pRunnerDest -= rowSize;
- }
- }
- */
-
- // Generate a texture and bind it to the input source data
- glGenTextures(1, &compressor.m_imageTexId);
- glBindTexture(GL_TEXTURE_2D, compressor.m_imageTexId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, inputWidth, inputHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)pFlippedData );
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, inputWidth, inputHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)inputRGBA );
- // Request FBO
- compressor.m_pCompressFbo = RequestFBO( compressionType, inputWidth, inputHeight );
- compressor.m_compressFboTex = compressor.m_pCompressFbo->GetAttachedTextureID();
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- // Start the clock
- StartTracking();
- #endif
- // Do the compression
- compressor.DoCompression( outputData, sourceFormatIsBGRA );
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- // Stop the clock
- EndTracking();
- m_lastCompressionTime = GetDeltaTimeInMilliseconds();
- m_accumulatedTime += m_lastCompressionTime;
- printf( "Compression time: %f ms\n", m_lastCompressionTime );
- #endif
- // Display texture? Only DXT1 supported here.
- if( bDisplayResults && compressionType == DXT1 )
- {
- // Create empty dxt1 compressed texture
- GLuint tempDisplayTexture;
- int dxt1Size = (inputWidth/4)*(inputHeight/4)*8;
- GLubyte * tempPadData = new GLubyte [dxt1Size];
- memset(tempPadData, 0, dxt1Size);
- glGenTextures(1, &tempDisplayTexture);
- glBindTexture(GL_TEXTURE_2D, tempDisplayTexture);
- 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);
- glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, inputWidth, inputHeight, 0, dxt1Size, tempPadData);
- delete [] tempPadData;
- // Re-upload the texture to VRAM for display
- int size = (inputWidth/4)*(inputHeight/4);
- glBindTexture(GL_TEXTURE_2D, tempDisplayTexture);
- glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, inputWidth, inputHeight, 0, size*8, outputData);
- // Display the texture
- DisplayTexture( tempDisplayTexture, inputWidth, inputHeight );
- // Get rid of the texture
- glDeleteTextures(1, &tempDisplayTexture);
- }
- // Clean up
- // delete [] pFlippedData;
- // pFlippedData = NULL;
- glDeleteTextures( 1, &compressor.m_imageTexId );
- // Done
- return true;
- }
- #include <stdlib.h>
- #include "DDSHeader.h"
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- int DXTCompressor::GetDDSHeaderSize(void)
- {
- return sizeof(DDS_header);
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::WriteDDSHeader( CompressionType compressionType, int width, int height, int compresedDataLength, void *outputData )
- {
- DDS_header* pHdr = (DDS_header*)outputData;
- memset( pHdr, 0, sizeof(DDS_header) );
- pHdr->dwMagic = DDS_MAGIC;
- pHdr->dwSize = 124;
- pHdr->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
- pHdr->dwWidth = width;
- pHdr->dwHeight = height;
- pHdr->sCaps.dwCaps1 = DDSCAPS_TEXTURE | DDSD_CAPS;
- pHdr->sPixelFormat.dwSize = 32;
- pHdr->sPixelFormat.dwFlags = DDPF_FOURCC;
- if( compressionType == DXT1 )
- pHdr->sPixelFormat.dwFourCC = D3DFMT_DXT1;
- else if( compressionType == DXT5_YCOCG )
- pHdr->sPixelFormat.dwFourCC = D3DFMT_DXT5;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::WriteDDSMemoryFile( CompressionType compressionType, int width, int height, const void* pCompressedData, int compresedDataLength, void **outputData, int *outputLength )
- {
- // Allocate the header + data
- int totalSize = sizeof(DDS_header) + compresedDataLength;
- void* pMemFile = new char[ totalSize ];
- // Write the header
- WriteDDSHeader(compressionType, width, height, compresedDataLength, pMemFile );
-
- // Write the data
- void* pData = ((char*)pMemFile + sizeof(DDS_header));
- memcpy( pData, pCompressedData, compresedDataLength );
- // Return data to user
- *outputData = pMemFile;
- *outputLength = totalSize;
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- void DXTCompressor::PrintPerformanceLog()
- {
- #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
- // Compute
- float mPixelsPerSec = (m_currentImageWidth*m_currentImageHeight*m_numIterations) / (m_accumulatedTime*1e6/1000.0f);
- printf( "For %dx%d image, compression took %f ms, Average of %f mPixelsPerSec (mPixels/sec)\n", m_currentImageWidth, m_currentImageHeight, m_accumulatedTime/m_numIterations, mPixelsPerSec );
- printf( "%f ms was spent in running compression shader, %f ms was spent copying pixel data to main memory for the cpu\n", m_timeRunningCompressionShader/m_numIterations, m_timeCopyingPixelDataToCPU/m_numIterations );
- // Reset stats
- m_currentImageWidth = 0;
- m_currentImageHeight = 0;
- m_numIterations = 0;
- m_accumulatedTime = 0;
- m_timeCopyingPixelDataToCPU = 0;
- m_timeRunningCompressionShader = 0;
- #endif
- }
- /* ------------------------------------------------------------------------------------------------------------------------------------ */
- static void glutPrint(float x, float y, const char *s, void *font)
- {
- int i, len;
- glRasterPos2f(x, y);
- len = (int) strlen(s);
- for (i = 0; i < len; i++) {
- glutBitmapCharacter(font, s[i]);
- }
- }
- static bool DrawTexture( GLuint textureID )
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glViewport(0,0,windowWidth,windowHeight);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureID);
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
- glColor3f(1.0, 1.0, 1.0);
- DrawQuad();
- glDisable(GL_TEXTURE_2D);
- glLoadIdentity();
- glutPrint(-0.95, -0.95, "DXT1 compressed (push ESC to close)", GLUT_BITMAP_9_BY_15);
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- return true;
- }
- void ClientResize(HWND hWnd, int nWidth, int nHeight)
- {
- RECT rcClient, rcWindow;
- POINT ptDiff;
- GetClientRect(hWnd, &rcClient);
- GetWindowRect(hWnd, &rcWindow);
- ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
- ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
- MoveWindow(hWnd,rcWindow.left, rcWindow.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
- }
- void DXTCompressor::DisplayTexture( GLuint textureID, int texW, int texH )
- {
- // Show the window
- ShowWindow(hWnd,SW_SHOW);
- // Resize the window to match the size of the texture
- ClientResize( hWnd, texW, texH );
- // Windows message pump
- MSG msg;
- BOOL done=FALSE;
- while(!done)
- {
- if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
- {
- if (msg.message==WM_QUIT)
- {
- done=TRUE;
- }
- else
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- else
- {
- if ((active && !DrawTexture( textureID )) || keys[VK_ESCAPE])
- {
- keys[VK_ESCAPE] = FALSE;
- done=TRUE;
- }
- else
- {
- SwapBuffers(hDC);
- }
- }
- }
- // Hide the window
- ShowWindow(hWnd,SW_HIDE);
- }
|