【发布时间】:2016-03-02 08:39:36
【问题描述】:
我正在学习来自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;
}
碎片整理器:
#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 函数移到了循环之外。不知何故,在顶点位置之前是可以的,但不是顶点颜色......
我阅读并了解了更多内容并更改了一些代码,现在它正在运行,我现在很满意:)
【问题讨论】:
-
查看complete GL+VAO/VBO+GLSL+shaders example in C++ 并尝试它是否适用于您的设置。如果没有,gfx 驱动程序或您的某些库可能有问题。如果可行,请尝试找出差异(抱歉,懒得比较这么多代码……)