Мой код OpenGL должен отображать несколько кубов, но отображает только один квадрат - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь запустить некоторый код, который должен рендерить несколько кубов, используя матричные преобразования для перевода координат одного куба в другие местоположения. Однако я уверен, что матрицы не работают, потому что все, что рендерится, это оригинальный куб без преобразования.

Я посмотрел в Интернете, в чем может быть проблема, и обнаружил, что сначала я должен инициализировать свои матрицы как идентичные, что я уже сделал, но я до сих пор не вижу никаких последствий. Вот мой код:

#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 Ответ

0 голосов
/ 08 января 2019

Странно, у вас только один glAttachShader() звонок.

Я вижу несколько кубов с GLM 0.9.9.2 и загрузчиком с известным шейдером:

screenshot of multiple wireframe cubes

Код:

#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 );
}
...