简体   繁体   English

OpenGL将颜色发送到着色器

[英]OpenGL send color to shader

I'm following the tutorials from: http://www.opengl-tutorial.org and trying a few things by my self. 我正在关注http://www.opengl-tutorial.org上的教程,并亲自尝试一些尝试。

At the moment my program can create triangles as class objects, transform their size and positions, and animate them (very simple code I just play around with). 目前,我的程序可以将三角形创建为类对象,变换三角形的大小和位置,并为其设置动画(我刚刚玩过的非常简单的代码)。 But when I'm trying to pass color value with Buffer Array to the Shaders, my triangles are not rendering. 但是,当我尝试通过缓冲区数组将颜色值传递给着色器时,我的三角形没有渲染。

I'll pass the relevant code here and try to make it understandble, hope someone can help me out here! 我将在此处传递相关代码,并尝试使其变得可理解,希望有人可以在这里帮助我!

CODE: 码:

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

Vertexshader: 顶点着色器:

#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: Fragmentshder:

#version 330 core

in vec3 fragmentColor;
out vec3 color;


void main(){

    color = fragmentColor;
}

If I remove: 如果我删除:

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

and: 和:

        //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
            );

from the main function, the triangles renders. 从主函数开始,将渲染三角形。

EDIT Here is only the relevant code which is where I think there is a problem: 编辑这只是我认为存在问题的相关代码:

    //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;
}

SOLUTION

I sort off solved my problem by looking at this tutorial https://www.opengl.org/wiki/Tutorial2%3a_VAOs,_VBOs,_Vertex_and_Fragment_Shaders_%28C_/_SDL%29 . 我通过查看本教程https://www.opengl.org/wiki/Tutorial2%3a_VAOs,_VBOs,_Vertex_and_Fragment_Shaders_%28C_/_SDL%29来解决问题。

Basically I just moved the bufferBinding and bufferData functions outside the loop. 基本上,我只是将bufferBinding和bufferData函数移到了循环之外。 Somehow that was ok before with the vertex positions, but not the vertex colors... 以某种方式在顶点位置之前是可以的,但顶点颜色不是...

I read and learned more and changed some of the code and it's working now and I'm happy with it now:) 我阅读并了解了更多信息,并更改了一些代码,它现在可以正常工作,现在我很满意:)

Before you bufferdata, you should bind the buffer that you want send data in. 在缓冲数据之前,应绑定要在其中发送数据的缓冲区。

it should be 它应该是

 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);

Your code send did,not send any data to vertex position buffer. 您的代码发送了,没有发送任何数据到顶点位置缓冲区。

Ps. 附言 for efficiency you should generate buffer, and submit the data before the loop. 为了提高效率,您应该生成缓冲区,并在循环之前提交数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM