OpenGL - 2D纹理映射

6
我正在尝试将一个简单的纹理(64x64)渲染到一个64x64的四边形上。四边形本身已经渲染出来了,但是纹理没有渲染出来。(它只渲染了一个空白的白色64x64的四边形。)
我正在使用SOIL来加载图像。
static GLuint LoadPNG(char* filename)
{
    GLuint texture = SOIL_load_OGL_texture
    (
        filename,
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
    );

    if (texture == 0)
        Log("Texture Load Error: " + string(filename));

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    return texture;
}

这是我的渲染代码,我可能没有正确映射它,所以可能就是问题所在。
// Draw Textured Quad
static void glDrawTexturedQuad(glRectF rect, GLuint tex)
{
    // Bind Texture
    glBindTexture (GL_TEXTURE_2D, tex);

    // Render Settings
    glEnable(GL_TEXTURE_2D);
    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glColor3ub(255,255,255);

    glBegin(GL_QUADS);

    // Top Left
    glTexCoord2f(0, 1);
    glVertex2f(rect.X, rect.Y);

    // Top Right
    glTexCoord2f(1, 1);
    glVertex2f(rect.X + rect.Width, rect.Y); 

    // Bottom Right
    glTexCoord2f(1, 0);
    glVertex2f(rect.X + rect.Width, rect.Y + rect.Height); 

    // Bottom Left
    glTexCoord2f(0, 0);
    glVertex2f(rect.X, rect.Y + rect.Height);

    glEnd();
}

这是其余相关代码。(这只是临时代码,为了测试把它们粘在一起,我会在让它正常工作后想出更好的解决方案。)

static GLuint Texture;

static void LoadTextures()
{
    Texture = LoadPNG("filename");
}

static void glRenderTest()
{   
    glRectF rect = {20, 20, 64, 64};
    glDrawTexturedQuad(rect, Texture);
}

我也按照这里找到的所有建议进行了操作,但我的纹理仍然没有显示出来。


我替换了LodePNG为SOIL(Simple OpenGL Image Library),使用起来更加简单,但仍然无法工作。
根据下面的答案建议,我添加了glTexEnv,但仍然只得到一个白色框,我会尝试一些其他设置,但我认为那不是问题所在。(编辑:尝试了各种标志,没有任何变化,仍然只有一个白色四边形。)

嗯...我已经与相应的nehe教程(http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06)进行了交叉检查,但在OpenGL调用中,我没有发现任何奇怪的地方。你确定图像加载函数工作正常吗? - Constantinius
我的四元组可能是反的吗?我正在破解一个游戏,所以我不知道它使用的是什么样的世界系统,也许可以把四元组翻过来? - TheMonster
如果你说你可以看到你的四边形,但是没有纹理,我想那不会改变什么。顺便说一句,你所说的是背面剔除,你可以通过输入 glDisable(GL_CULL_FACE); 来关闭它。 - Constantinius
我刚尝试了一张不同的PNG图像,它也无法工作,可能会尝试一些不同的纹理标志等等。因此,除非是标志或如我在上一篇帖子中所建议的渲染错误,否则我会感到困惑。 - TheMonster
四边形只是黑色的吗?这意味着您已经开启了照明并且没有设置正确的照明条件。然后,您会得到黑色乘以纹理颜色,这只是黑色。尝试使用glDisable(GL_LIGHTING);或使用glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);仅获取纹理的颜色(这可能是您想要的)。 - Christian Rau
显示剩余10条评论
4个回答

7

你尝试过打电话吗?

glEnable(GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, texture);

之前

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

我遇到了这个问题,谢谢你帮我解决。我在 glBegin() 附近调用了 BindTexture,我需要将 glTextParameterf() 的调用移动到 glBindTexture 后面。状态机的问题 :)。 - lb.
+1 我在跟着教程学习时,他们没有提到调用 glEnable(GL_TEXTURE_2D);。感谢您的答案,我的问题已经解决了。 - 2013Asker

1

尝试使用 gDEBugger gDEBugger。它可以让您查看已加载到OpenGL中的所有纹理,并提供其他调试工具。


1

这些都在同一个文件中吗?

static GLuint Texture;

static void LoadTextures()
{
    Texture = LoadPNG("filename");
}

static void glRenderTest()
{   
    glRectF rect = {20, 20, 64, 64};
    glDrawTexturedQuad(rect, Texture);
}

如果它们不在同一个文件中,那么static变量将在每个编译单元中拥有独立的副本,在程序启动时分别初始化为零。这就解释了为什么在加载器返回1后绑定纹理#0。

是的,所有代码都在同一个文件中,现在所有函数中的数字都是正确的。这是因为我正在修改的游戏引擎在启动时会卸载纹理(出于某种原因)。现在我使用按键来触发我的代码,等待游戏完全加载后再执行。 - TheMonster

0

我没有看到你设置纹理函数。在几何绘制函数中的glBindTexture之后尝试添加以下内容:

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); // texture function: GL_DECAL, GL_MODULATE, etc.

尝试不同的纹理函数以满足您的需求:GL_DECAL,GL_BLEND,GL_MODULATE等。

嗯,那可能有所帮助,但那不是问题所在。我尝试了各种标志,它们都给出了相同的结果,一个空白的白色四边形。 - TheMonster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接