我的 opengl 代码应该显示多个立方体,但只显示一个正方形

Posted

技术标签:

【中文标题】我的 opengl 代码应该显示多个立方体,但只显示一个正方形【英文标题】:My opengl code should display multiple cubes but only displays a single square 【发布时间】:2019-01-07 22:36:47 【问题描述】:

我正在尝试运行一些代码,该代码应该使用矩阵变换来渲染多个立方体,以将一个立方体坐标转换到其他位置。但是我很确定矩阵不起作用,因为所有渲染的是原始立方体而没有被转换。

我在网上查看了问题可能是什么,发现我应该将我的矩阵初始化为我已经完成的身份矩阵,但我仍然看不到任何影响。这是我的代码:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "GLCALL.h"
#include <stb_image.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <shader.h>
#include <iostream>

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

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 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, "CurrentProject1", 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 (glewInit() != GLEW_OK)
        std::cout << "error not goeerrd\n";

    GLCall(glEnable(GL_DEPTH_TEST));


    float vertices[] =  -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
                          0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
                          0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                          0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                         -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
                         -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

                         -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                          0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
                          0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
                          0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
                         -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
                         -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

                         -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                         -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                         -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                         -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                         -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                         -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

                          0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                          0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                          0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                          0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                          0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                          0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

                         -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                          0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
                          0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
                          0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
                         -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                         -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

                         -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
                          0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                          0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                          0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                         -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
                         -0.5f,  0.5f, -0.5f,  0.0f, 1.0f ;

    glm::vec3 cubePositions[] =  glm::vec3(0.0f,  0.0f,  0.0f),
                                  glm::vec3(2.0f,  5.0f, -15.0f),
                                  glm::vec3(-1.5f, -2.2f, -2.5f),
                                  glm::vec3(-3.8f, -2.0f, -12.3f),
                                  glm::vec3(2.4f, -0.4f, -3.5f),
                                  glm::vec3(-1.7f,  3.0f, -7.5f),
                                  glm::vec3(1.3f, -2.0f, -2.5f),
                                  glm::vec3(1.5f,  2.0f, -2.5f),
                                  glm::vec3(1.5f,  0.2f, -1.5f),
                                  glm::vec3(-1.3f,  1.0f, -1.5f) ;

    unsigned int VBO, VAO;
    GLCall(glGenVertexArrays(1, &VAO));
    GLCall(glGenBuffers(1, &VBO));

    GLCall(glBindVertexArray(VAO));

    GLCall(glBindBuffer(GL_ARRAY_BUFFER, VBO));
    GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));

    GLCall(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0));
    GLCall(glEnableVertexAttribArray(0));

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

    GLCall(unsigned int s_ID = glCreateProgram());
    GLCall(unsigned int vs_ID = glCreateShader(GL_VERTEX_SHADER));
    GLCall(unsigned int fs_ID = glCreateShader(GL_FRAGMENT_SHADER));

    const std::string vs_string = "#version 330 core\n"
                                  "layout (location = 0) in vec3 position;\n"
                                  "uniform mat4 model;\n"
                                  "uniform mat4 view;\n"
                                  "uniform mat4 projection;\n"
                                  "\n"
                                  "void main()\n"
                                  "\n"
                                  "gl_Position = projection * view * model * vec4(position, 1.0f);\n"
                                  "\n";

    const std::string fs_string = "#version 330 core\n"
                                  "out vec4 color;\n"
                                  "void main()\n"
                                  "\n"
                                  "color  = vec4(1.0f, 0.5f, 0.2f, 1.0f)\n;"
                                  "\n";

    const char* vs_char = vs_string.c_str();
    const char* fs_char = fs_string.c_str();
    std::cout << *vs_char;
    GLCall(glShaderSource(vs_ID, 1, &vs_char, NULL));
    GLCall(glShaderSource(fs_ID, 1, &fs_char, NULL));
    GLCall(glCompileShader(vs_ID));

    int result;
    GLCall(glGetShaderiv(vs_ID, GL_COMPILE_STATUS, &result));
    if (result == GL_FALSE)
    
        int length;
        GLCall(glGetShaderiv(vs_ID, GL_INFO_LOG_LENGTH, &length));
        char * message = (char*)alloca(length * sizeof(char));
        GLCall(glGetShaderInfoLog(vs_ID, length, &length, message));
        std::cout << "failed to compile vertexing shader" << std::endl;
        std::cout << message << std::endl;
        GLCall(glDeleteShader(vs_ID));
    

    GLCall(glCompileShader(fs_ID));

    int result1;
    GLCall(glGetShaderiv(fs_ID, GL_COMPILE_STATUS, &result1));
    if (result1 == GL_FALSE)
     
        int length1;
        GLCall(glGetShaderiv(fs_ID, GL_INFO_LOG_LENGTH, &length1));
        char * message = (char*)alloca(length1 * sizeof(char));
        GLCall(glGetShaderInfoLog(fs_ID, length1, &length1, message));
        std::cout << "failed to compile fragmenting shader" << std::endl;
        std::cout << message << std::endl;
        GLCall(glDeleteShader(fs_ID));
    

    GLCall((s_ID, vs_ID));
    GLCall(glAttachShader(s_ID, fs_ID));
    GLCall(glLinkProgram(s_ID));
    GLCall(glDeleteShader(vs_ID));
    GLCall(glDeleteShader(fs_ID));
    GLCall(glUseProgram(s_ID));

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

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

        glm::mat4 view = glm::mat4(1.0f);
        glm::mat4 projection = glm::mat4(1.0f);
        projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

        const std::string temp1 = "projection";
        const std::string temp2 = "view";
        const std::string temp3 = "model";
        GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp1.c_str()), 1, GL_FALSE, &projection[0][0]));
        GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp2.c_str()), 1, GL_FALSE, &view[0][0]));
        GLCall(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));

        GLCall(glBindVertexArray(VAO));
        for (unsigned int i = 0; i < 10; i++)
        
            glm::mat4 model = glm::mat4(1.0f);
            model = glm::translate(model, cubePositions[i]);
            float angle = 20.0f * i;
            model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
            GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp3.c_str()), 1, GL_FALSE, &model[0][0]));
            GLCall(glDrawArrays(GL_TRIANGLES, 0, 36));
        

        glfwSwapBuffers(window);
        glfwPollEvents();
    

    GLCall(glDeleteVertexArrays(1, &VAO));
    GLCall(glDeleteBuffers(1, &VBO));
    glfwTerminate();
    return 0;


void processInput(GLFWwindow *window)

    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);


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

    GLCall(glViewport(0, 0, width, height));

我希望多个立方体在透视投影中呈现在不同的位置,但是我看到如果根本不包含矩阵会看到什么,只是一个带有原始立方体坐标的立方体。是什么阻止了矩阵的工作?

【问题讨论】:

【参考方案1】:

有点奇怪,你只有一个 glAttachShader() 电话。

我可以看到多个带有 GLM 0.9.9.2 和已知良好着色器加载器的立方体:

代码:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include <cstdarg>

struct Program

    static GLuint Load( const char* shader, ... )
    
        GLuint prog = glCreateProgram();
        va_list args;
        va_start( args, shader );
        while( shader )
        
            const GLenum type = va_arg( args, GLenum );
            AttachShader( prog, type, shader );
            shader = va_arg( args, const char* );
        
        va_end( args );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    

private:
    static void CheckStatus( GLuint obj )
    
        GLint status = GL_FALSE;
        if( glIsShader( obj ) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram( obj ) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        GLchar log[ 1 << 15 ] =  0 ;
        if( glIsShader( obj ) ) glGetShaderInfoLog( obj, sizeof( log ), NULL, log );
        if( glIsProgram( obj ) ) glGetProgramInfoLog( obj, sizeof( log ), NULL, log );
        std::cerr << log << std::endl;
        std::exit( EXIT_FAILURE );
    

    static void AttachShader( GLuint program, GLenum type, const char* src )
    
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    
;

const char* vert = 1 + R"GLSL(
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()

gl_Position = projection * view * model * vec4(position, 1.0f);
;
)GLSL";

const char* frag = 1 + R"GLSL(
#version 330 core
out vec4 color;
void main()

color  = vec4(1.0f, 0.5f, 0.2f, 1.0f);
;
)GLSL";

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

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 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, "CurrentProject1", 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( glewInit() != GLEW_OK )
        std::cout << "error not goeerrd\n";

    glEnable( GL_DEPTH_TEST );

    float vertices[] =
    
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
    ;

    glm::vec3 cubePositions[] =
    
        glm::vec3( 0.0f,  0.0f,  0.0f ),
        glm::vec3( 2.0f,  5.0f, -15.0f ),
        glm::vec3( -1.5f, -2.2f, -2.5f ),
        glm::vec3( -3.8f, -2.0f, -12.3f ),
        glm::vec3( 2.4f, -0.4f, -3.5f ),
        glm::vec3( -1.7f,  3.0f, -7.5f ),
        glm::vec3( 1.3f, -2.0f, -2.5f ),
        glm::vec3( 1.5f,  2.0f, -2.5f ),
        glm::vec3( 1.5f,  0.2f, -1.5f ),
        glm::vec3( -1.3f,  1.0f, -1.5f ),
    ;

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

    glBindVertexArray( VAO );

    glBindBuffer( GL_ARRAY_BUFFER, VBO );
    glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, 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 );

    GLuint s_ID = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
    glUseProgram( s_ID );

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

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

        glm::mat4 view = glm::mat4( 1.0f );
        glm::mat4 projection = glm::mat4( 1.0f );
        projection = glm::perspective( glm::radians( 45.0f ), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f );
        view = glm::translate( view, glm::vec3( 0.0f, 0.0f, -3.0f ) );

        const std::string temp1 = "projection";
        const std::string temp2 = "view";
        const std::string temp3 = "model";
        glUniformMatrix4fv( glGetUniformLocation( s_ID, temp1.c_str() ), 1, GL_FALSE, &projection[ 0 ][ 0 ] );
        glUniformMatrix4fv( glGetUniformLocation( s_ID, temp2.c_str() ), 1, GL_FALSE, &view[ 0 ][ 0 ] );
        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

        glBindVertexArray( VAO );
        for( unsigned int i = 0; i < 10; i++ )
        
            glm::mat4 model = glm::mat4( 1.0f );
            model = glm::translate( model, cubePositions[ i ] );
            float angle = 20.0f * i;
            model = glm::rotate( model, glm::radians( angle ), glm::vec3( 1.0f, 0.3f, 0.5f ) );
            glUniformMatrix4fv( glGetUniformLocation( s_ID, temp3.c_str() ), 1, GL_FALSE, &model[ 0 ][ 0 ] );
            glDrawArrays( GL_TRIANGLES, 0, 36 );
        

        glfwSwapBuffers( window );
        glfwPollEvents();
    

    glDeleteVertexArrays( 1, &VAO );
    glDeleteBuffers( 1, &VBO );
    glfwTerminate();
    return 0;


void processInput( GLFWwindow *window )

    if( glfwGetKey( window, GLFW_KEY_ESCAPE ) == GLFW_PRESS )
        glfwSetWindowShouldClose( window, true );


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

    glViewport( 0, 0, width, height );

【讨论】:

以上是关于我的 opengl 代码应该显示多个立方体,但只显示一个正方形的主要内容,如果未能解决你的问题,请参考以下文章

纹理不适用于我在 C++ 和 OpenGL 中的立方体

OpenGL - 纹理一个基本的立方体

在 OpenGL 中显示立方体的问题

无法在opengl中绘制多个对象

OpenGL 显示一个正方形而不是一个立方体

如何使用 OpenGL 创建一个或多个球体?