簡體   English   中英

OpenGL將顏色發送到着色器

[英]OpenGL send color to shader

我正在關注http://www.opengl-tutorial.org上的教程,並親自嘗試一些嘗試。

目前,我的程序可以將三角形創建為類對象,變換三角形的大小和位置,並為其設置動畫(我剛剛玩過的非常簡單的代碼)。 但是,當我嘗試通過緩沖區數組將顏色值傳遞給着色器時,我的三角形沒有渲染。

我將在此處傳遞相關代碼,並嘗試使其變得可理解,希望有人可以在這里幫助我!

碼:

#include <stdio.h>
#include <stdlib.h>
#include <iomanip>

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>

using namespace glm;

#include "loadShader.h"
#include "model.h"

int _screenWidth = 1024;
int _screenHeight = 768;



int main()
{

    //START GLFW
    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize GLFW\n");
        return -1;
    }

    //GLFW SETTINGS
    glfwWindowHint(GLFW_SAMPLES, 4); //4x antialiasing
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //OPENGL 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Mac compatible?
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

    //open window                                                              
    GLFWwindow* window;
    window = glfwCreateWindow(_screenWidth, _screenHeight, "Tutorial 01", NULL, NULL);
    if (window == NULL) {
        fprintf(stderr, "Failed to open GLFW window. Make sure your GPU is openGL 3.3 compatible!\n");
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);


    //INITIALIZE GLEW
    glewExperimental = true; //needed in core profile

    if (glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize GLEW.\n");
        return -1;
    }

    // Ensure we can capture the escape key being pressed below
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    glClearColor(0.125f, 0.0f, 0.3725f, 0.0f);

    //Enable Depth test
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);


    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // Create and compile GLSL program from the shaders
    GLuint programID = LoadShaders("Shaders/vertexShaders.vert", "Shaders/fragmentShaders.frag");
    //get handle for MVP uniform
    GLuint MatrixID = glGetUniformLocation(programID, "MVP");


    /////////////////////
    //MODEL//////////////
    /////////////////////
    //two triangles
    int nVertices = 6;
    //created through model class
    model object1, object2;
    object1.createTriangle();
    object2.createTriangle();

    //initialize buffer data arrays
    GLfloat g_vertex_buffer_data[12*3];    

    // One color for each vertex
    static const GLfloat g_color_buffer_data[] = {
        0.583f,  0.771f,  0.014f,
        0.609f,  0.115f,  0.436f,
        0.327f,  0.483f,  0.844f,
        0.822f,  0.569f,  0.201f,
        0.435f,  0.602f,  0.223f,
        0.310f,  0.747f,  0.185f };

    //////////////////////////
    //////////////////////////
    //////////////////////////

    //CREATE BUFFER
    //This will identify our vertex and color buffer
    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    GLuint colorbuffer;
    glGenBuffers(1, &colorbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);

    //counters
    float time          = 0.0f;
    int counter         = 0;
    int counterStep     = 100;


    do {

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        time        = time + 0.01;
        counter     = counter + 1;


        //TRANSFORM MY TRIANGLES (its working)
        glm::vec3 rotationAxis(0.0f, 0.0f, 1.0f);
        glm::vec3 translation(0.0f, 0.0f, 0.025f);
        float rotationAngle = 0.25f;

        object1.rotate(rotationAngle, rotationAxis);
        //object2.rotate(0.5*rotationAngle, rotationAxis);
        object1.translate(translation);

        //Update coordinates in vertex buffer (both triangles)
        for (int i = 0; i < 3; i++)
        {
            g_vertex_buffer_data[i * 3]         = object1.transformedPosition[i].x;
            g_vertex_buffer_data[i * 3 + 1]     = object1.transformedPosition[i].y;
            g_vertex_buffer_data[i * 3 + 2]     = object1.transformedPosition[i].z;
        }

        for (int i = 0; i < 3; i++)
        {
            g_vertex_buffer_data[i * 3 + 9]     = object2.transformedPosition[i].x;
            g_vertex_buffer_data[i * 3 + 10]    = object2.transformedPosition[i].y;
            g_vertex_buffer_data[i * 3 + 11]    = object2.transformedPosition[i].z;
        }


        //Model matrix
        glm::mat4 modelM = glm::mat4(1.0f);

        //Projection matrix:
        glm::mat4 projectionM = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
        //Camera matrix:
        glm::mat4 viewM = lookAt(
            glm::vec3(8, 2, 2+10*time),
            glm::vec3(0, 0, 0),
            glm::vec3(0, 1, 0));

        //MODEL VIEW PROJECTION MATRIX:
        glm::mat4 mvpM = projectionM * viewM * modelM;

        //Give our vertices and colors to OpenGL
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);

        /////////////////////////////////////////////

        //USE SHADERS
        glUseProgram(programID);

        //Send our transformation to the currently bound shader, MVP uniform
        glUniformMatrix4fv(MatrixID, 1, 0, &mvpM[0][0]);

        //1rst attribute buffer: vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
            0,          //attribute 0, no particular reason, but must match the layout in the shader
            3,          //size
            GL_FLOAT,   //type
            GL_FALSE,   //normalized?
            0,          //stride
            (void*)0    //array buffer offset
            );

        //2nd attribute buffer: colors
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
        glVertexAttribPointer(
            1,          //attribute number
            3,          //size
            GL_FLOAT,   //type
            GL_FALSE,   //normalized?
            0,          //stride
            (void*)0    //array buffer offset
            );


        //Draw the triangle
        glDrawArrays(GL_TRIANGLES, 0, nVertices); //Starting from vertex 0; 3 vertices total
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);


        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();

    }


    // Check if the ESC key was pressed or the window was closed
    while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0);




    // Cleanup VBO
    glDeleteBuffers(1, &vertexbuffer);
    glDeleteBuffers(1, &colorbuffer);
    glDeleteProgram(programID);
    glDeleteVertexArrays(1, &VertexArrayID);

    // Close OpenGL window and terminate GLFW
    glfwTerminate();



    return 0;
}

頂點着色器:

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;

uniform mat4 MVP;

out vec3 fragmentColor;

void main(){
    gl_Position = MVP * vec4(vertexPosition_modelspace,1.0);
    fragmentColor = vertexColor;
}   

Fragmentshder:

#version 330 core

in vec3 fragmentColor;
out vec3 color;


void main(){

    color = fragmentColor;
}

如果我刪除:

glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);

和:

        //2nd attribute buffer: colors
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
        glVertexAttribPointer(
            1,          //attribute number
            3,          //size
            GL_FLOAT,   //type
            GL_FALSE,   //normalized?
            0,          //stride
            (void*)0    //array buffer offset
            );

從主函數開始,將渲染三角形。

編輯這只是我認為存在問題的相關代碼:

    //FIRST DO THIS: (but not sure why..)
    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    //initialize buffer data arrays
    GLfloat g_vertex_buffer_data[]  = { something };
    GLfloat g_color_buffer_data[]   = { something };

    //CREATE BUFFER
    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    GLuint colorbuffer;
    glGenBuffers(1, &colorbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);

    //LOOP
    do {

        //UPDATE BUFFER DATA
        GLfloat g_vertex_buffer_data[]  = { something new };
        GLfloat g_color_buffer_data[]   = { something new };

        //SEND NEW BUFFER DATA TO SHADERS
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);

        //USE SHADERS
        glUseProgram(programID);

        //1rst attribute buffer: vertices positions
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
            0,          //attribute 0, no particular reason, but must match the layout in the shader
            3,          //size
            GL_FLOAT,   //type
            GL_FALSE,   //normalized?
            0,          //stride
            (void*)0    //array buffer offset
            );

            //2nd attribute buffer: colors
            glEnableVertexAttribArray(1);
            glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
            glVertexAttribPointer(
                1,          //attribute number
                3,          //size
                GL_FLOAT,   //type
                GL_FALSE,   //normalized?
                0,          //stride
                (void*)0    //array buffer offset
                );

        //Draw the triangles
        glDrawArrays(GL_TRIANGLES, 0, nVertices); //Starting from vertex 0; 3 vertices total
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);

        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();

    }


    // Check if the ESC key was pressed or the window was closed
    while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0);




    // Cleanup VBO
    glDeleteBuffers(1, &vertexbuffer);
    glDeleteBuffers(1, &colorbuffer);
    glDeleteProgram(programID);
    glDeleteVertexArrays(1, &VertexArrayID);

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    return 0;
}

我通過查看本教程https://www.opengl.org/wiki/Tutorial2%3a_VAOs,_VBOs,_Vertex_and_Fragment_Shaders_%28C_/_SDL%29來解決問題。

基本上,我只是將bufferBinding和bufferData函數移到了循環之外。 以某種方式在頂點位置之前是可以的,但頂點顏色不是...

我閱讀並了解了更多信息,並更改了一些代碼,它現在可以正常工作,現在我很滿意:)

在緩沖數據之前,應綁定要在其中發送數據的緩沖區。

它應該是

 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
 glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
 glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
 glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);

您的代碼發送了,沒有發送任何數據到頂點位置緩沖區。

附言 為了提高效率,您應該生成緩沖區,並在循環之前提交數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM