3

我正在尝试遵循 OpenGL 教程,但该教程使用 SOIL(这对我不起作用)并且我使用 FreeImage。

你能告诉我为什么我的代码不起作用吗?

教程代码:

// Load texture
GLuint tex;
glGenTextures(1, &tex);

int width, height;
unsigned char* image = SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);

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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

我的代码:

// Load textures
GLuint tex;
glGenTextures(1, &tex);

int width, height;

FREE_IMAGE_FORMAT formato = FreeImage_GetFileType("sample.png",0);
FIBITMAP* imagen = FreeImage_Load(formato, "sample.png");
FIBITMAP* temp = imagen;  
imagen = FreeImage_ConvertTo32Bits(imagen);
FreeImage_Unload(temp);

width = FreeImage_GetWidth(imagen);
height = FreeImage_GetHeight(imagen);

GLubyte* textura = new GLubyte[4*width*height];
char* pixeles = (char*)FreeImage_GetBits(imagen);

for(int j= 0; j<width*height; j++)
{
    textura[j*4+0]= pixeles[j*4+2];
    textura[j*4+1]= pixeles[j*4+1];
    textura[j*4+2]= pixeles[j*4+0];
    textura[j*4+3]= pixeles[j*4+3];
}

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, width, height, 0, GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid*)textura );

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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

我的“解决方案”只是导致一个黑色窗口(没有错误)。

4

3 回答 3

5

用 C 编写代码很有趣

你是程序员。你最好调试你的程序,因为 OpenGL 应用程序中的“黑屏”可能是由无数不同的原因引起的。从我们的角度来看,我们只能猜测。我们不喜欢它。

我猜

(好吧,有时我们喜欢猜测)

这:

FIBITMAP* temp = imagen;  
imagen = FreeImage_ConvertTo32Bits(imagen);
FreeImage_Unload(temp);

你的tempandimagen指向同一个地方,所以在FreeImage_Unload(temp);两个指向之后......我们不知道在哪里。然后你从中得到像素:

char* pixeles = (char*)FreeImage_GetBits(imagen);

它返回什么?我们不知道。之后你不检查是否pixels存在。未定义的行为等。它甚至不会崩溃。另外,AFAIR,你不能同时读写dib

而是这样做:

FREE_IMAGE_FORMAT formato = FreeImage_GetFileType("sample.png",0);
if(formato  == FIF_UNKNOWN) { /* go angry here */ } 
FIBITMAP* imagen = FreeImage_Load(formato, "sample.png");
if(!imagen ) { /* go very angry here */ } 
FIBITMAP* temp = FreeImage_ConvertTo32Bits(imagen);
if(!imagen) { /* go mad here */ } 
FreeImage_Unload(imagen);
imagen = temp;

(或者只是注释掉所有转换的东西)

如何调试:

  • 加载和处理图像后检查错误。图像是否加载?
  • 检查 OpenGL 错误。一切都顺利吗?
  • 在像素着色器中,将输出颜色设置为白色,这样你就可以确定你的几何体是好的(什么?你不使用着色器?=()
  • 纹理加载后,将其直接写入.raw文件(或以其他格式)并使用位图编辑器进行检查

如何检查错误:

仔细阅读 FreeImage 文档和教程示例。查看错误检查实现。基本上,您将需要设置回调函数。实施它。设置它。(或至少复制粘贴)。对 OpenGL执行相同的 + glGetError()

快乐编码!=)

编辑: FreeImage 有SwapRedBlue32()辅助功能,所以你不需要那些 for 循环。

于 2013-10-26T17:09:37.603 回答
0

您似乎从未绑定过您创建的纹理对象。

在尝试使用纹理进行渲染之前,一次又一次地添加glBindTexture( GL_TEXTURE_2D, tex )调用。glGenTextures()

于 2013-10-26T16:34:19.203 回答
0

好的,我找到了我的问题的答案。:P

我必须在“调试”文件夹中启动应用程序,而不是使用 VC++ 调试它。

唯一的问题是现在加载的图片是颠倒的,但我想我可以在更改 for 循环时修复它。

感谢所有答案!

于 2013-10-27T13:43:22.020 回答