【问题标题】:I am having a problem displaying a image in OpenGL我在 OpenGL 中显示图像时遇到问题
【发布时间】:2020-06-07 00:50:03
【问题描述】:

我不完全理解 OpenGL 中绑定纹理的概念,我无法用它来为我的项目渲染 jpg 图像,知道我可能做错了什么吗?

// Shader sources
const GLchar* vertexShaderSource = R"glsl(
#version 150 core
in vec2 position;
in vec3 color;
in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
    Color = color;
    Texcoord = texcoord;
    gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";

const GLchar* fragmentShaderSource = R"glsl(
#version 150 core
in vec3 Color;
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D tex;
void main()
{
    outColor = texture(tex, Texcoord) * vec4(Color, 1.0);
}
)glsl";
    //creating the window
    GLFWwindow *window= glfwCreateWindow(1200, 700, "NEX_Tests", NULL, NULL);

    if(nullptr== window){
        std::cout<<"ERROR HAS OCCURED WHILE LOADING THE WINDOW\n"<<"\n";
        glfwTerminate();
        return -1;
    }

    else{
         int screenWidth,screenHeight;
           glfwGetFramebufferSize(window, &screenWidth, &screenHeight);

           glfwMakeContextCurrent(window);

        glewExperimental=true;
        if(GLEW_OK==!glewInit()){
            std::cout<<"ERROR HAS OCCURED WHILE INITILIZING THE GLEW LIBRARY\n"<<"\n";
            return EXIT_FAILURE;
        }

        //set the viewing port
        glViewport(0, 0, screenWidth, screenHeight);

        //creating the vetex array object;
        GLuint vao,vbo;
        glGenVertexArrays(1,&vao);
        glGenBuffers(1,&vbo);

        glBindVertexArray(vao);
        glBindBuffer(GL_ARRAY_BUFFER,vbo);
        glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);

        //creating the element buffer
        GLuint ebo;
        glGenBuffers(1,&ebo);
        GLuint elements[]={
            0,1,2,
            2,3,0
        };

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(elements),elements,GL_STATIC_DRAW);
        std::cout<<vbo<<"\n";

        //   glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,(3* sizeof(GLfloat)),(GLvoid*)0);
        // glEnableVertexAttribArray(0);
        //glBindBuffer(GL_VERTEX_ARRAY,0);
        // glBindVertexArray(0);



        //creating and linking the shaders
        GLuint vertexShader= glCreateShader(GL_VERTEX_SHADER);

        glShaderSource(vertexShader,1,&vertexShaderSource,NULL );
        glCompileShader(vertexShader);
        GLint success;
        GLchar infoLog[512];

        glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success);
        if(!success){
            glGetShaderInfoLog(vertexShader, 512,NULL,infoLog);
            std::cout<<"ERROR HAS OCCURED WHILE COMPILING THE SHADERS\n"<<infoLog<<std::endl;
        }
        GLuint fragmentShader= glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
        glCompileShader(fragmentShader);

        glGetShaderiv(fragmentShader,GL_COMPILE_STATUS,&success);
        if(!success){
            glGetShaderInfoLog(fragmentShader,512,NULL,infoLog);
            std::cout<<"ERROR HAS OCCURED WHILE COMPILING THE SHADERS\n"<<infoLog<<std::endl;
        }
        GLuint shaderProgram= glCreateProgram();
        glAttachShader(shaderProgram,vertexShader);
        glAttachShader(shaderProgram,fragmentShader);
        glLinkProgram(shaderProgram);
        glUseProgram(shaderProgram);

        glGetProgramiv(shaderProgram,GL_LINK_STATUS,&success);
        if(!success){
            glGetProgramInfoLog(shaderProgram,512,NULL,infoLog);
            std::cout<<"ERROR HAS OCCURED WHILE LINKING THE SHADERS\n"<<infoLog<<std::endl;
        }
         //delete the shaders
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);

        //layout of the vertex shader
        GLint posAttrib = glGetAttribLocation(shaderProgram,"position");
        glEnableVertexAttribArray(posAttrib);
        glVertexAttribPointer(posAttrib,0,GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),0);

        GLint colAttrib = glGetAttribLocation(shaderProgram,"color");
        glEnableVertexAttribArray(colAttrib);
        glVertexAttribPointer(colAttrib,2,GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),((void*)(2*sizeof(GLfloat))));

        GLint TexAttrib= glGetAttribLocation(shaderProgram,"texcoord");
        glEnableVertexAttribArray(TexAttrib);
        glVertexAttribPointer(TexAttrib,2,GL_FLOAT,GL_FALSE,7*sizeof(GLfloat),((void*)(5*sizeof(GLfloat))));

        //loading the textures
        GLuint tex;
        glGenTextures(2, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);
        std::cout<<tex<<"\n";
        glActiveTexture(GL_TEXTURE0+ 1);

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


        //loading the image
        int me=200,me2=300;
        int *width=&me,*height=&me2;

        unsigned char* Image= SOIL_load_image("IceKarl.png", width, height, 0, SOIL_LOAD_RGB);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, *width, *height, 0, GL_RGB, GL_UNSIGNED_BYTE, Image);

        SOIL_free_image_data(Image);


        if(!Image){

            std::cout<<"ERROR HAS OCCURED WHILE LOADING IN IMAGE\n";
        }

        //running loop
        while(!glfwWindowShouldClose(window)){
            glfwPollEvents();

            glClearColor(0.0f, 0.00f, 0.00f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            glBindTexture(GL_TEXTURE_2D, 0);

            //glDrawArrays(GL_TRIANGLES, 0, 6);
            // glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
            // glBindTexture(GL_TEXTURE_2D,0);
            glfwSwapBuffers(window);
        }
        glDeleteTextures(1,&tex);
        glDeleteProgram(shaderProgram);
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);

        glDeleteBuffers(1,&vbo);
        glDeleteBuffers(1,&ebo);
        glDeleteVertexArrays(1,&vao);
    }

    glfwTerminate();

    return 0;
}

【问题讨论】:

    标签: c++ opengl glfw


    【解决方案1】:

    glVertexAttribPointer 的第二个参数是属性的元组大小。在您的情况下,这是位置 (x, y) 的 2,颜色 (r, g, b) 的 3 和纹理坐标 ( u, v):

    GLint posAttrib = glGetAttribLocation(shaderProgram,"position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib,  2,  GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),0);
    
    GLint colAttrib = glGetAttribLocation(shaderProgram,"color");
    glEnableVertexAttribArray(colAttrib);
    glVertexAttribPointer(colAttrib,  3,  GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),((void*)(2*sizeof(GLfloat))));
    
    GLint TexAttrib= glGetAttribLocation(shaderProgram,"texcoord");
    glEnableVertexAttribArray(TexAttrib);
    glVertexAttribPointer(TexAttrib,  2,  GL_FLOAT,GL_FALSE,7*sizeof(GLfloat),((void*)(5*sizeof(GLfloat))));
    

    绘制网格时,必须绑定纹理和顶点数组对象。

    在绑定纹理(glBindTexture)之前必须设置纹理单元(glActiveTexture):

    glActiveTexture(GL_TEXTURE0 + 1);
    glBindTexture(GL_TEXTURE_2D, tex);
    

    您必须将纹理单元索引分配给纹理采样器制服 (glUniform):

    glUniform1i(tex_loc, 1);
    

    获取纹理采样器制服的位置索引(glGetUniformLocation):

    GLuint tex_loc = glGetUniformLocation(shaderProgram, "tex");
    

    在绘制调用之前绑定对象:

    int texture_unit = 1;
    glActiveTexture(GL_TEXTURE0 + texture_unit);
    glBindTexture(GL_TEXTURE_2D, tex);
    glUniform1i(tex_loc, texture_unit);
    
    glBindVertexArray(vao);
    
    glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
    

    生成纹理名称时还有一个问题。生成 1 个纹理名称而不是 2 个:

    glGenTextures(2, &amp;tex);

    GLuint tex;
    glGenTextures(1, &tex);
    

    【讨论】:

    • 感谢您的帮助,非常感谢。
    • 我试过了,但现在我只得到一个黑匣子,很抱歉再次询问。
    • @KrishPatel 所以你犯了一个错误。当然,我已经测试了该解决方案,它对我来说效果很好。您是否确保 glActiveTextureglBindTexture 之前完成(无处不在)?
    • 是的,我有,我只是在屏幕上看到一个黑色矩形
    • @KrishPatel 这是我的测试示例代码:pastebin.com/qQgWChi0。它对我来说很好。
    猜你喜欢
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 2020-06-04
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多