本文介绍了OpenGL纹理映射顽固地拒绝工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用D编程语言使用SDL和OpenGL编写2D游戏.此刻,它只是尝试在屏幕上渲染纹理映射的四边形.问题是,整个纹理映射部分似乎不太起作用.尽管纹理看起来可以很好地加载(为纹理分配了一个非零的纹理编号,不会使glGetError返回零以外的值),但四边形仍使用glColor中设置的最后一个颜色进行渲染,而完全忽略了纹理.

I'm writing a 2D game using SDL and OpenGL in the D programming language. At the moment it simply tries to render a texture-mapped quad to the screen. Problem is, the whole texture-mapping part doesn't quite seem to work. Despite the texture apparently loading fine (gets assigned a nonzero texture number, doesn't cause glGetError to return values other than zero), the quad is rendered with the last color set in glColor, entirely ignoring the texture.

我一直在寻找导致纹理映射失败的常见原因,包括这个问题,无济于事.正在加载的图片文件为64x64,有效为2的幂.

I've looked for common reasons for texture mapping to fail, including this question, to no avail. The image file being loaded is 64x64, a valid power-of-2 size.

请不要害怕,因为它在D中-几乎完全是C样式的SDL和OpenGL调用.

Please don't get scared off because this is in D—it's almost entirely C-style SDL and OpenGL calls.

SDL初始化代码:

if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) == -1 ||
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0) == -1)
    throw new Exception("An OpenGL attribute could not be set!");

uint videoFlags = SDL_OPENGL | SDL_HWSURFACE | SDL_ANYFORMAT;

if (threadsPerCPU() > 1)
    videoFlags |= SDL_ASYNCBLIT;

SDL_Surface* screen = SDL_SetVideoMode(800, 600, 32, videoFlags);

if (screen == null)
    throw new Exception("SDL_SetVideoMode failed!");

OpenGL初始化代码:

OpenGL initialization code:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0., 800, 600, 0., 0., 1.);
glMatrixMode(GL_MODELVIEW);

glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glEnable(GL_TEXTURE_2D);

glClearColor(0.f, 0.f, 0.f, 0.f);

纹理加载代码:

SDL_Surface* s = IMG_Load(toStringz("hello.png"));

if (s == null)
    throw new Exception("Image file could not be loaded!");

uint texFormat;

switch (s.format.BytesPerPixel)
{
case 4:
    texFormat = (s.format.Rmask == 0x000000ff ? GL_RGBA : GL_BGRA);
    break;
case 3:
    texFormat = (s.format.Rmask == 0x000000ff ? GL_RGB : GL_BGR);
    break;
default:
    throw new Exception("Bad pixel format!");
    break;
}

if ((s.w & (s.w - 1)) != 0)
    throw new Exception("Width must be a power of 2!");
if ((s.h & (s.h - 1)) != 0)
    throw new Exception("Height must be a power of 2!");

uint glName;

glGenTextures(1, &glName);

glBindTexture(GL_TEXTURE_2D, glName);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, s.format.BytesPerPixel, s.w, s.h, 0,
    texFormat, GL_UNSIGNED_BYTE, s.pixels);

SDL_FreeSurface(s);

渲染代码:

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_QUADS);
    glColor4ub(255, 255, 255, 255);
    glBindTexture(GL_TEXTURE_2D, glName);
    glTexCoord2i(0, 0); glVertex2i(0, 0);
    glTexCoord2i(1, 0); glVertex2i(64, 0);
    glTexCoord2i(1, 1); glVertex2i(64, 64);
    glTexCoord2i(0, 1); glVertex2i(0, 64);
glEnd();

SDL_GL_SwapBuffers();

我的程序使用Derelict2,该库为D提供SDL和OpenGL绑定.

My program uses Derelict2, a library that provides SDL and OpenGL bindings for D.

关于这里到底发生了什么的任何想法吗?

Any ideas on exactly what is going awry here?

供以后参考,这是我的问题的解决方案:

For future reference, here's the solution to my problem:

http://www.opengl.org/wiki/Common_Mistakes#Creating_a_Texture

在调用glTexImage2D之前,我需要设置几个参数,否则我的纹理在技术上是不完整的.在该调用之前添加以下四行即可达到目的:

I needed to set a couple parameters prior to calling glTexImage2D or else my texture was technically incomplete. Adding the following four lines just before that call did the trick:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

推荐答案

一个常见的错误是创建/使用不完整的纹理,请参见此处.

One common mistake is to create/use an incomplete texture, see here.

您的代码未显示对的任何调用:

Your code does not show any call to :

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR/*or GL_NEAREST*/);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*or GL_NEAREST*/);

,也不会显示任何mipmap创建.

and also does not show any mipmap creation.

您的问题可能与纹理不完整有关.

You problem may be related to your texture being incomplete.

这篇关于OpenGL纹理映射顽固地拒绝工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 15:30