简体   繁体   English

在 OpenGL 中映射纹理

[英]Mapping a texture in OpenGL

I am trying to map a texture to a simple quad for the first time, but all it won't render.我第一次尝试将纹理映射到一个简单的四边形,但它不会渲染。 I am using freeglut for the implementation, and the stb_image.h header to load the texture.我正在使用 freeglut 进行实现,并使用 stb_image.h 标头来加载纹理。 The code:编码:

#include <GL/glut.h>   
#include <stb_image.h>
#include <iostream>
int ww = 500, wh = 500;

void display()
{
    glClearColor(1.0, 1.0, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_QUADS);
    glEnable(GL_TEXTURE_2D);
    glTexCoord2f(0.0, 0.0); glVertex3f(10,10,0);
    glTexCoord2f(0.0, 1.0); glVertex3f(10,wh-10,0);
    glTexCoord2f(1.0, 1.0); glVertex3f(ww-10,wh,0);
    glTexCoord2f(1.0, 0.0); glVertex3f(ww-10,10,0);
    glDisable(GL_TEXTURE_2D);
    glEnd();
    glFlush();
}


void myinit()
{   
    glViewport(0, 0, ww, wh);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)ww, 0.0, (GLdouble)wh);
    glMatrixMode(GL_MODELVIEW);

    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    int width, height, nrChannels;
    unsigned char* data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);
}
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowSize(ww, wh);
    glutCreateWindow("texture-try");
    glutDisplayFunc(display);
    myinit();
    glutMainLoop();
    return 0;
}

It successfully loads the texture, but the quad appears just white.它成功加载了纹理,但四边形显示为白色。 What am I missing?我错过了什么?

Edit:编辑:

I moved the glBegin(GL_QUADS);我移动了glBegin(GL_QUADS); and glEnd();glEnd(); inside the glEnable(GL_TEXTURE_2D);glEnable(GL_TEXTURE_2D); and glDisable(GL_TEXTURE_2D);glDisable(GL_TEXTURE_2D); commands as was suggested, but it still won't render the texture.建议的命令,但它仍然不会渲染纹理。

I also checked the glGetError command, but it returns GL_NO_ERROR .我还检查了glGetError命令,但它返回GL_NO_ERROR

From the OpenGL documentation for glBegin:从 glBegin 的 OpenGL 文档:

Only a subset of GL commands can be used between glBegin and glEnd.在 glBegin 和 glEnd 之间只能使用 GL 命令的子集。 The commands are glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, and glEdgeFlag.这些命令是 glVertex、glColor、glSecondaryColor、glIndex、glNormal、glFogCoord、glTexCoord、glMultiTexCoord、glVertexAttrib、glEvalCoord、glEvalPoint、glArrayElement、glMaterial 和 glEdgeFlag。 Also, it is acceptable to use glCallList or glCallLists to execute display lists that include only the preceding commands.此外,可以使用 glCallList 或 glCallLists 来执行仅包含上述命令的显示列表。 If any other GL command is executed between glBegin and glEnd, the error flag is set and the command is ignored.如果在 glBegin 和 glEnd 之间执行了任何其他 GL 命令,则设置错误标志并忽略该命令。

In other words, you can't enable/disable texturing within a glBegin/glEnd block.换句话说,您不能在 glBegin/glEnd 块中启用/禁用纹理。

void display()
{
    glClearColor(1.0, 1.0, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    
    // move to before glBegin
    glEnable(GL_TEXTURE_2D);
    
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(10,10,0);
    glTexCoord2f(0.0, 1.0); glVertex3f(10,wh-10,0);
    glTexCoord2f(1.0, 1.0); glVertex3f(ww-10,wh,0);
    glTexCoord2f(1.0, 0.0); glVertex3f(ww-10,10,0);
    glEnd();

    // move to after glEnd
    glDisable(GL_TEXTURE_2D);

    glFlush();
}

Several things:几件事:

  • The aforementioned "don't use prohibited functions within a glBegin() / glEnd() pair" issue;前面提到的“不要在glBegin() / glEnd()对中使用禁止的函数”问题; as of posting this hasn't been fixed in the question code.截至发布时,问题代码中尚未修复此问题。
  • GL_LINEAR_MIPMAP_LINEAR is being used without providing any mipmaps.正在使用GL_LINEAR_MIPMAP_LINEAR而不提供任何 mipmap。 Drop to GL_LINEAR or provide some mipmaps.拖放到GL_LINEAR或提供一些 mipmap。
  • Pass 3 to stbi_load() 's desired_channels parameter (instead of the current 0 ) to guarantee you get 3-channel image data instead of just assuming nrChannels is 3 for all input images.3传递给stbi_load()desired_channels参数(而不是当前的0 )以保证您获得 3 通道图像数据,而不是仅仅假设所有输入图像的nrChannels3
  • Using GL_RGB with the default GL_UNPACK_ALIGNMENT of 4 can result in wonky display if your image width isn't a nice multiple of 4 so drop that down to 1 via glPixelStorei(GL_UNPACK_ALIGNMENT, 1) before calling glTexImage2D() .如果您的图像宽度不是 4 的倍数,则使用默认GL_RGB4GL_UNPACK_ALIGNMENT可能会导致显示不稳定,因此请在调用glTexImage2D()之前通过glPixelStorei(GL_UNPACK_ALIGNMENT, 1)将其降至1
  • Switch to GLUT_DOUBLE & glutSwapBuffers() instead of using GLUT_SINGLE and glFlush() .切换到GLUT_DOUBLEglutSwapBuffers()而不是使用GLUT_SINGLEglFlush()

All together:全部一起:

#include <GL/glut.h>   
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <iostream>
int ww = 500, wh = 500;

void display()
{
    glClearColor(1.0, 1.0, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(10,10,0);
    glTexCoord2f(0.0, 1.0); glVertex3f(10,wh-10,0);
    glTexCoord2f(1.0, 1.0); glVertex3f(ww-10,wh,0);
    glTexCoord2f(1.0, 0.0); glVertex3f(ww-10,10,0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glutSwapBuffers();
}


void myinit()
{   
    glViewport(0, 0, ww, wh);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)ww, 0.0, (GLdouble)wh);
    glMatrixMode(GL_MODELVIEW);

    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    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_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    int width, height, nrChannels;
    // https://commons.wikimedia.org/wiki/File:Container.JPG
    unsigned char* data = stbi_load("container.jpg", &width, &height, &nrChannels, 3);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);
}
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(ww, wh);
    glutCreateWindow("texture-try");
    glutDisplayFunc(display);
    myinit();
    glutMainLoop();
    return 0;
}

截屏

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM