2015-11-28 171 views
0

我正在关注以下教程:http://www.opengl-tutorial.org并尝试了一些我自己的东西。OpenGL向着色器发送颜色

目前我的程序可以创建三角形作为类对象,改变它们的大小和位置,并为它们设置动画(我只是简单地玩一下简单的代码)。但是,当我试图将颜色值与缓冲区数组一起传递给着色器时,我的三角形不会呈现。

我会在这里通过相关的代码,并试图使其可以理解,希望有人能帮助我在这里!

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:

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

SOLUTION

我有点掉通过查看本教程https://www.opengl.org/wiki/Tutorial2%3a_VAOs,_VBOs,_Vertex_and_Fragment_Shaders_%28C_/_SDL%29解决我的问题。

基本上我只是将bufferBinding和bufferData函数移到循环外部。不知怎的,这是确定与顶点位置之前,而不是顶点颜色...

我阅读和了解了更多,改变了一些代码,它的工作了,我现在很高兴吧:)

+0

看看[在C++中完整的GL + VAO/VBO + GLSL +着色器示例](http://stackoverflow.com/a/31913542/2521214)并尝试它是否适用于您的设置。如果没有,gfx驱动程序或一些库文件可能有问题。如果它的工作,然后尝试找到差异(对不起,懒得比较这么多的代码...) – Spektre

回答

2

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

您的代码发送没有,没有任何数据发送到顶点位置缓冲。

Ps。为了提高效率,您应该生成缓冲区,并在循环之前提交数据。

+0

好的,谢谢,让我检查一下。 所以,即使在循环(动画)过程中顶点位置正在改变,我不需要在循环中调用glBufferData(..)让着色器知道我改变了什么?(如果这样做的话) – remi000

+0

如果您确实需要单独更改顶点,则需要在循环中调用glbufferdata()。但在大多数情况下,简单的统一转换就足够了。 – crazyxiazi

+0

即使对于动画网格,典型的方法是做顶点蒙皮,使用矩阵数组来生成动画。但是,还是取决于你,只要记住将数据从CPU传输到GPU的成本是非常重要的 – crazyxiazi