绑定纹理功能(glBindTexture)无效。

3
我正在尝试绘制一些简单的三维矩形棱柱,但是glBindTexture似乎无法正常工作。
我有N个“部件”,每个都有一个材料名称。
我正在循环遍历每个部件,根据其材料名称找到其纹理,调用glBindTexture,然后绘制该部件。
然而,如果我有多个具有相同材料名称的部件,则仅第一个带有纹理,其余部分则为白色。
非常感谢您的任何帮助。
以下是代码:
OpenGL初始化:
static PIXELFORMATDESCRIPTOR pfd =
{
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,
    32, // bit depth
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    16, // z-buffer depth
    0, 0, 0, 0, 0, 0, 0,
};

GLfloat light_pos1[] = {0.0f, 0.0f, 15.0f, 1.0f};
GLfloat light_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};

// Get device context only once.
hdc = GetDC()->m_hDC;

// Pixel format.
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);

// Create the OpenGL Rendering Context.
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);

//texture
glEnable(GL_TEXTURE_2D);

//Setup:
glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
glClearDepth(1.0f);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

//lighting
glLightfv(GL_LIGHT0, GL_POSITION, light_pos1);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);

// Send draw request
OnDraw(NULL);

纹理加载
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, t.texture);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

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

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, data);

接下来是绘图代码:

glPolygonMode(GL_FRONT_AND_BACK, GL_FLAT);

for(int i = 0; i < mPieces.GetCount(); i++)
{
    C3DPiece p = mPieces.GetAt(mPieces.FindIndex(i));

    if(p.visible)
    {
        //GetTextureForMaterial finds the texture id based on the "piece"'s material name
        //have checked this and it is always returning a valid id (>0)

        GLuint tex = GetTextureForMaterial(p.material);

        glBindTexture(GL_TEXTURE_2D, tex);

        glBegin(GL_QUADS);
        glNormal3f(..., ..., ...);
        glTextCoord2f(..., ...);
        glVertex3F(..., ..., ...);
        glTextCoord2f(..., ...);
        glVertex3F(..., ..., ...);
        glTextCoord2f(..., ...);
        glVertex3F(..., ..., ...);
        glTextCoord2f(..., ...);
        glVertex3F(..., ..., ...);
        glEnd();
    }
}

不知道 "..." 代表什么代码,我真的无法帮助你。 - Skyler Saleh
这些...只是参数,指定绘制图形的大小。glBegin() 和 glEnd() 之间的代码块实际上会重复执行6次,以绘制棱柱的6个不同面。为了简化代码,我省略了其中的另外5个面。 - user744621
你在每个循环中都检查了“tex”的值吗?现在我想不出任何其他可能的问题了。 - Mario
2个回答

1

除了设置上下文之外,没有OpenGL初始化这样的东西。在“初始化”代码中所做的所有事情都应该属于渲染函数或纹理加载代码:

下面的所有内容语义上都属于渲染路径。OpenGL是一个状态机,像所有状态机一样,在开始工作之前,你需要将它置于适当的起始状态。

//texture
glEnable(GL_TEXTURE_2D);

//Setup:
glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
glClearDepth(1.0f);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

//lighting
glLightfv(GL_LIGHT0, GL_POSITION, light_pos1);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);

在你的纹理加载器中,你有这个:

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, t.texture);

这可能是一个打字错误,或者生成的纹理名称没有传递到“t.”纹理中。


我认为设置着色模式、深度函数等操作不应该放在渲染路径中,而应该放在初始化程序中。虽然 OpenGL 是一个状态机,但你可以假定这些状态值在你自己没有改变它们的情况下保持不变。不要教新手每次绘制对象都要重新配置整个管线。 - Christian Rau
@Christian:在任何现代渲染路径中,深度函数都会经常更改。例如,如果执行早期Z传递,则首先仅将场景渲染到深度缓冲区中,使用glDepthFunc(GL_LESS);然后所有后续的渲染传递都将禁用深度写入并使用glDepthFunc(GL_EQUAL)。此外,不要忘记您的程序可能提供某种插件机制或对OpenGL进行脚本访问(只需查看Blender即可)。在这种情况下,插件/脚本可能会使OpenGL上下文处于您的程序未知的状态。解决这个问题的唯一方法是始终设置所需的状态! - datenwolf
@datenwolf这就是我说“如果你不改变它们”的原因,意思是你程序中的任何OpenGL访问函数。当然,你始终需要注意更改GL状态的程序部分(包括插件或类似部分),我假设他在应用程序中已经知道了这一点。 - Christian Rau
1
@Christian:是的,我确实会指导新手为每个渲染迭代配置整个管道。从长远来看,这是使用OpenGL的唯一正确方式。一旦引入HUD、渲染到纹理、多通道渲染技术等,你不可避免地必须这样做。在专门的初始化阶段设置某些状态几乎没有任何好处。 - datenwolf
@datenwolf 好的,我理解你的想法是从长远考虑,你可能是正确的。 - Christian Rau
是的,“t.texture”是这个问题中的一个打字错误(不是我的实际代码)。 - user744621

0

我想我已经修复了它。

似乎纹理文件(.RAW图像)确实存在问题,它显示为白色而不是应有的颜色/图案。

我再次测试了一下,使用较少的材料(3个而不是3663个),看起来可以正常工作。


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