OpenGL3.3中的代码无法在正交投影中呈现纹理

时间:2018-11-29 19:49:16

标签: c++ opengl glsl glm-math orthographic

我正在开发一个图形项目,以使用 OpenGL 3.3 渲染纹理。使用 Perspective 投影时,代码将按预期方式渲染,但在 Orthoographic 投影中,不会渲染纹理。

我已经检查了由 glm :: ortho()生成的4x4矩阵的值,并且所有值都是正确的。欢迎任何暗示可能发生的事情!

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <STBI/stb_image.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "shader_m.h"

#include <iostream>

void framebuffer_size_callback( GLFWwindow* window, int width, int height );
void processInput( GLFWwindow *window );

const unsigned int SCR_WIDTH  = 1920;  // 1280; 800;
const unsigned int SCR_HEIGHT = 1080;  // 720;  600;

int main()
{
    glfwInit();        
    glfwWindowHint(     GLFW_CONTEXT_VERSION_MAJOR, 3                           );
    glfwWindowHint(     GLFW_CONTEXT_VERSION_MINOR, 3                           );
    glfwWindowHint(     GLFW_OPENGL_PROFILE       , GLFW_OPENGL_CORE_PROFILE    );

    GLFWwindow* window = glfwCreateWindow(              SCR_WIDTH, 
                                                        SCR_HEIGHT, 
                                                        "LearnOpenGL", 
                                                        NULL, 
                                                        NULL                    );

    if ( window == NULL )
    {    
        std::cout << "Failed to create GLFW window" << std::endl;            
        glfwTerminate();            
        return -1;        
    }

    glfwMakeContextCurrent( window );
    glfwSetFramebufferSizeCallback( window, framebuffer_size_callback );

    if ( !gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress) )
    {    
        std::cout << "Failed to initialize GLAD" << std::endl;            
        return -1;        
    }

    glEnable( GL_DEPTH_TEST );

    Shader ourShader(           "Shaders/vertex.shader", 
                                "Shaders/fragment.shader"               );


    float vertices[] = 
    {
         100.0f,  100.0f,  0.0f,     1.0f, 1.0f,    
         200.0f,  100.0f,  0.0f,     1.0f, 0.0f,    
         200.0f,  200.0f,  0.0f,     0.0f, 0.0f,    
         100.0f,  200.0f,  0.0f,     0.0f, 1.0f     
    };

    unsigned int indices[] = 
    {
        0, 1, 3, // first triangle
        1, 2, 3  // second triangle
    };

    unsigned int VBO, VAO, EBO;

    glGenVertexArrays(              1, 
                                   &VAO 
                                                                            );
    glGenBuffers     (              1, 
                                   &VBO                                     );

    glGenBuffers     (              1, 
                                   &EBO                                     );

    glBindVertexArray(              VAO                                     );    
    glBindBuffer(                   GL_ARRAY_BUFFER, 
                                    VBO                                     );        
    glBufferData(                   GL_ARRAY_BUFFER, 
                                    sizeof( vertices ), 
                                    vertices, 
                                    GL_STATIC_DRAW                          );    
    glBindBuffer(                   GL_ELEMENT_ARRAY_BUFFER, 
                                    EBO                                     );        
    glBufferData(                   GL_ELEMENT_ARRAY_BUFFER, 
                                    sizeof( indices ), 
                                    indices,    
                                    GL_STATIC_DRAW                          );    
    glVertexAttribPointer(          0, 
                                    3, 
                                    GL_FLOAT, 
                                    GL_FALSE, 
                                    5 * sizeof( float ), 
                                    (void*)0                                );    
    glEnableVertexAttribArray(      0                                       );

    glVertexAttribPointer(          1, 
                                    2, 
                                    GL_FLOAT, 
                                    GL_FALSE, 
                                    5 * sizeof( float ), 
                                    (void*)( 3 * sizeof( float ) )          );        
    glEnableVertexAttribArray(      1                                       );

    unsigned int texture1, texture2;

    glGenTextures(                  1, 
                                   &texture1                                );        
    glBindTexture(                  GL_TEXTURE_2D, 
                                    texture1                                );        
    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;        
    stbi_set_flip_vertically_on_load( true );         
    std::string filepath  = "resources/container.jpg";    
    unsigned char *data = stbi_load(                filepath.c_str(), 
                                                   &width, 
                                                   &height, 
                                                   &nrChannels, 
                                                    0                       );

    if ( data )
    {           
        glTexImage2D(                   GL_TEXTURE_2D, 
                                        0, 
                                        GL_RGBA,    //internal format
                                        width, 
                                        height, 
                                        0,          
                                        GL_RGB,     //
                                        GL_UNSIGNED_BYTE, 
                                        data                                    );            
        glGenerateMipmap(               GL_TEXTURE_2D                           );    
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }

    stbi_image_free( data );

    ourShader.use();

    ourShader.setInt(               "texture1", 
                                     0                              );

    while ( !glfwWindowShouldClose( window ) )
    {    
        processInput( window );

        glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 

        glActiveTexture(                    GL_TEXTURE0                                     );            
        glBindTexture  (                    GL_TEXTURE_2D, 
                                            texture1                                        );    
        ourShader.use();

        //create transformations
        glm::mat4 model;
        glm::mat4 view;
        glm::mat4 projection;

        //model = glm::rotate( model, glm::radians( -55.0f ), glm::vec3( 1.0f, 0.0f, 0.0f ) );
        //model = glm::rotate( model, (float)glfwGetTime() * glm::radians( 50.0f ), glm::vec3( 0.5f, 1.0f, 0.0f ) );

        view       = glm::translate(            view, 
                                                glm::vec3( 0.0f, 0.0f, -3.0f )                  );

        //-----------------------------------------------------------------------------------------


        projection = glm::ortho(                  0.0f, 
                                                960.0f, 
                                                  0.0f, 
                                                540.0f,
                                                 -1.0f,
                                                  1.0f
                                                                                                );


        //-----------------------------------------------------------------------------------------

        /*

        projection = glm::perspective(          glm::radians( 45.0f ), 
                                                (float)SCR_WIDTH / (float)SCR_HEIGHT, 
                                                0.1f, 
                                                1000.0f                                         );

        */

        //-----------------------------------------------------------------------------------------


        unsigned int modelLoc = glGetUniformLocation(           ourShader.ID, 
                                                                "model"                     );

        unsigned int viewLoc  = glGetUniformLocation(           ourShader.ID, 
                                                                "view"                      );

        glUniformMatrix4fv(                 modelLoc, 
                                            1, 
                                            GL_FALSE, 
                                            glm::value_ptr( model )                         );

        glUniformMatrix4fv(                 viewLoc , 
                                            1, 
                                            GL_FALSE, 
                                           &view[ 0 ][ 0 ]                                  );

        ourShader.setMat4(                 "projection", 
                                            projection                                      );

        glBindVertexArray(                  VAO                                             );

        glDrawElements(                     GL_TRIANGLES, 
                                            6, 
                                            GL_UNSIGNED_INT, 
                                            0                                               );

        glfwSwapBuffers( window );            
        glfwPollEvents();    
    }

    glDeleteVertexArrays(   1,  &VAO    );
    glDeleteBuffers     (   1,  &VBO    );
    glDeleteBuffers     (   1,  &EBO    );

    glfwTerminate();

    return 0;    
}

以下是着色器:

#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;


void main()
{    
    gl_Position = projection * view * model * vec4( aPos.x/1920.0f, aPos.y/1080.0f, 0.0f, 1.0 );

    TexCoord = vec2( aTexCoord.x, aTexCoord.y );    
}

#version 330 core

out vec4 FragColor;

in vec2 TexCoord;

uniform sampler2D texture1;

void main()
{     
    FragColor = texture( texture1, TexCoord );    
}

1 个答案:

答案 0 :(得分:1)

您必须初始化矩阵-另请参见Why is the sprite not rendering in OpenGL?

glm::mat4 model(1.0f);
glm::mat4 view(1.0f);
glm::mat4 projection(1.0f);

由于设置了视图矩阵:

view = glm::translate(view, glm::vec3( 0.0f, 0.0f, -3.0f ) );

您必须增加到远端平面的距离:

例如10.0

projection = glm::ortho( 0.0f, 960.0f, 0.0f, 540.0f, -1.0f, 10.0f );

由于使用正交投影矩阵,因此无需缩放顶点着色器中的x和y坐标:

gl_Position = projection * view * model * vec4( aPos.x/1920.0f, aPos.y/1080.0f, 0.0f, 1.0 );

gl_Position = projection * view * model * vec4( aPos.xy, 0.0f, 1.0 );