我正在使用 D 编程语言中的 SDL 和 OpenGL 编写 2D 游戏。目前它只是尝试将纹理映射的四边形渲染到屏幕上。问题是,整个纹理映射部分似乎不太有效。尽管纹理显然加载良好(分配了一个非零纹理编号,不会导致 glGetError 返回零以外的值),但使用 glColor 中设置的最后一个颜色渲染四边形,完全忽略纹理。
我一直在寻找纹理映射失败的常见原因,包括这个问题,但无济于事。正在加载的图像文件是 64x64,一个有效的 2 次方大小。
请不要害怕,因为这是在 D 中——它几乎完全是 C 风格的 SDL 和 OpenGL 调用。
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初始化代码:
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 绑定的库。
关于这里到底出了什么问题的任何想法?
编辑:供将来参考,这是我的问题的解决方案:
http://www.opengl.org/wiki/Common_Mistakes#Creating_a_Texture
我需要在调用之前设置几个参数,glTexImage2D
否则我的纹理在技术上是不完整的。在该调用之前添加以下四行就可以了:
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);