- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
知道我的代码有什么问题吗?当我执行 glCompressedTexImage2D() 时,程序就崩溃了(出现 Windows XP 崩溃消息……)
我正在尝试加载不带 mipmap 的 DDS 图像,图像格式为 DDS DXT1
我是否遗漏了一些包含文件,或者我做错了什么?我从以下位置下载了包含的文件: http://sourceforge.net/projects/glew/files/glew/1.5.1/glew-1.5.1-win32.zip/download
我的 glew32.dll 与我的 .exe 位于同一文件夹中。
下面的代码只有我更改的部分才能加载 DDS 图像:
#pragma comment(lib, "glew32.lib")
#include <GL\glew.h>
#include <GL\gl.h>
...
typedef struct {
GLuint dwSize;
GLuint dwFlags;
GLuint dwFourCC;
GLuint dwRGBBitCount;
GLuint dwRBitMask;
GLuint dwGBitMask;
GLuint dwBBitMask;
GLuint dwABitMask;
} DDS_PIXELFORMAT;
typedef struct {
GLuint dwMagic;
GLuint dwSize;
GLuint dwFlags;
GLuint dwHeight;
GLuint dwWidth;
GLuint dwLinearSize;
GLuint dwDepth;
GLuint dwMipMapCount;
GLuint dwReserved1[11];
DDS_PIXELFORMAT ddpf;
GLuint dwCaps;
GLuint dwCaps2;
GLuint dwCaps3;
GLuint dwCaps4;
GLuint dwReserved2;
} DDS_HEADER;
DDS_HEADER DDS_headers;
...
FILE *fp = fopen("test.dds", "rb");
fread(&DDS_headers, 1, sizeof(DDS_headers), fp);
img_width = DDS_headers.dwWidth;
img_height = DDS_headers.dwHeight;
maxsize = (img_width*img_height)/2;
unsigned char *imgdata = (unsigned char *)malloc(maxsize);
fread(imgdata, 1, maxsize, fp);
fclose(fp);
GLuint texID;
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_PALETTE4_R5_G6_B5_OES, img_width, img_height, 0, maxsize, imgdata);
// NOTICE:
// Ive also tried with function:
// glCompressedTexImage2DARB();
// and internalformats: GL_COMPRESSED_RGB_S3TC_DXT1_EXT and all of the possible formats... its not a format error.
最佳答案
我记得在 glew 中弄乱了 DDS 加载器,我认为那里的 header 信息不正确。我一直无法让它正常工作。
最好的方法是使用 DDraw.h 中的 header 结构,这是我能够用于 DXT1、3 和 5 的结构,如果我没记错的话,它们是唯一可以在 OpenGL 中工作的结构。
struct DDS_IMAGE_DATA
{
GLsizei width;
GLsizei height;
GLint components;
GLenum format;
int numMipMaps;
GLubyte *pixels;
};
DDS_IMAGE_DATA* CImage::loadDDSTextureFile( const char *filename )
{
DDS_IMAGE_DATA *pDDSImageData;
DDSURFACEDESC2 ddsd;
char filecode[4];
FILE *pFile;
int factor;
int bufferSize;
// Open the file
pFile = fopen( filename, "rb" );
if( pFile == NULL )
{
#if DEBUG
char str[255];
printf( str, "loadDDSTextureFile couldn't find, or failed to load \"%s\"", filename );
#endif
return NULL;
}
// Verify the file is a true .dds file
fread( filecode, 1, 4, pFile );
if( strncmp( filecode, "DDS ", 4 ) != 0 )
{
#if DEBUG
char str[255];
printf( str, "The file \"%s\" doesn't appear to be a valid .dds file!", filename );
#endif
fclose( pFile );
return NULL;
}
// Get the surface descriptor
fread( &ddsd, sizeof(ddsd), 1, pFile );
pDDSImageData = (DDS_IMAGE_DATA*) malloc(sizeof(DDS_IMAGE_DATA));
memset( pDDSImageData, 0, sizeof(DDS_IMAGE_DATA) );
//
// This .dds loader supports the loading of compressed formats DXT1, DXT3
// and DXT5.
//
switch( ddsd.ddpfPixelFormat.dwFourCC )
{
case FOURCC_DXT1:
// DXT1's compression ratio is 8:1
pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
factor = 2;
break;
case FOURCC_DXT3:
// DXT3's compression ratio is 4:1
pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
factor = 4;
break;
case FOURCC_DXT5:
// DXT5's compression ratio is 4:1
pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
factor = 4;
break;
default:
#if DEBUG
char str[255];
printf( str, "The file \"%s\" doesn't appear to be compressed "
"using DXT1, DXT3, or DXT5!", filename );
#endif
return NULL;
}
//
// How big will the buffer need to be to load all of the pixel data
// including mip-maps?
//
if( ddsd.dwLinearSize == 0 )
{
#if DEBUG
printf("dwLinearSize is 0!");
#endif
}
if( ddsd.dwMipMapCount > 1 )
bufferSize = ddsd.dwLinearSize * factor;
else
bufferSize = ddsd.dwLinearSize;
pDDSImageData->pixels = (unsigned char*)malloc(bufferSize * sizeof(unsigned char));
fread( pDDSImageData->pixels, 1, bufferSize, pFile );
// Close the file
fclose( pFile );
pDDSImageData->width = ddsd.dwWidth;
pDDSImageData->height = ddsd.dwHeight;
pDDSImageData->numMipMaps = ddsd.dwMipMapCount;
if( ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1 )
pDDSImageData->components = 3;
else
pDDSImageData->components = 4;
return pDDSImageData;
}
void CImage::loadDDS(const char * szFilename, tTexture & texData)
{
DDS_IMAGE_DATA *pDDSImageData = loadDDSTextureFile(szFilename);
if( pDDSImageData != NULL )
{
texData.m_nHeight = pDDSImageData->height;
texData.m_nWidth = pDDSImageData->width;
texData.m_nHeight = pDDSImageData->height;
texData.m_eFormat = pDDSImageData->format;
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 );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
int nSize;
int nOffset = 0;
// Load the mip-map levels
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);
}
}
if( pDDSImageData != NULL )
{
if( pDDSImageData->pixels != NULL )
free( pDDSImageData->pixels );
free( pDDSImageData );
}
}
这段特定的代码对我们尝试加载的 DDS 文件做了一些假设,首先是一个压缩文件,DXT1、3 或 5,并且 DDS 文件具有预先生成的 mipmaps 保存在它,因此我们不必自己生成它们。
我希望这能够帮助你,我花了一些时间才让它正常工作。如果此代码片段中有任何不清楚的地方,请告诉我,我会进一步帮助您。
关于c++ - 在 OpenGL 中加载 DDS DXT1,崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1715027/
我正在开发一个需要能够平均三个数字的 Facebook 应用程序。但是,它总是返回 0 作为答案。这是我的代码: $y = 100; $n = 250; $m = 300; $number = ($y
我只是无法弄清楚这一点,也找不到任何对我来说有意义的类似问题。我的问题:我从数据库中提取记录,并在我的网页上以每个面板 12 条的倍数显示它们。因此,我需要知道有多少个面板可以使用 JavaScrip
我是一名优秀的程序员,十分优秀!