如果删除uniform
变量和以下几行:
//in CompileShaders function:
uniformModel = glGetUniformLocation(shader,"model");
...
//defined in the main draw loop after glfwPollEvents():
//and the shader has compiled, linked and activated at this point
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, glm::vec3(triOffset, 0.0f, 0.0f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE,glm::value_ptr(modelMatrix));
程序显示正常,但是一旦我添加了统一变量并使用矩阵转换三角形,就找不到红色屏幕的原因了,为便于参考,着色器是:
static const char* vShader =
"#version 330\n"
"layout (location = 0) in vec3 pos;\n"
"uniform mat4 model;\n"
"void main(){\n"
" gl_Position = model * vec4(pos, 1.0);\n"
"}\n";
// fragment shader
static const char* fShader = ""
"#version 330\n"
"out vec4 color;\n"
"void main(){\n"
" color = vec4(1.0, 1.0, 0.0, 1.0);\n"
"}\n";
整个源代码是:
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cmath>
#include <string.h>
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
// Window Dimensions
const GLint WIDTH=800, HEIGHT=600;
GLuint VAO, VBO, shader;
GLint uniformModel {};
GLfloat triOffset {};
GLfloat triMaxOffset {5.0f};
bool direction = true;
// vertex shader
static const char* vShader =
"#version 330\n"
"layout (location = 0) in vec3 pos;\n"
"uniform mat4 model;\n"
"void main(){\n"
" gl_Position = model * vec4(pos, 1.0);\n"
"}\n";
// fragment shader
static const char* fShader = ""
"#version 330\n"
"out vec4 color;\n"
"void main(){\n"
" color = vec4(1.0, 1.0, 0.0, 1.0);\n"
"}\n";
void AddShader(GLuint theProgram, const char* ShaderCode, GLenum shaderType, std::string info){
std::cerr <<"DEBUG: Adding "<<info<<" Shader"<<std::endl;
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = ShaderCode;
GLint codeLength[1];
codeLength[0] = strlen(ShaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
GLint result =0;
GLchar eLog[1024] ={0};
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if(!result){
glGetShaderInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cerr<<"Error compiling program"<<std::endl;
return;
}
glAttachShader(theProgram, theShader);
}
void CompileShader(){
shader = glCreateProgram();
if(!shader){
std::cerr<<"Error creating shader"<<std::endl;
return;
}
AddShader(shader, vShader, GL_VERTEX_SHADER, "vertex");
AddShader(shader, fShader, GL_FRAGMENT_SHADER, "fragment");
GLint result =0;
GLchar eLog[1024] ={0};
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if(!result){
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cerr<<"Error linking program"<<std::endl;
return;
}
glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
if(!result){
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cerr<<"Error Validating program"<<std::endl;
return;
}
uniformModel = glGetUniformLocation(shader,"model");
}
void CreateTriangles(){
GLfloat vertices[]={
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9,vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
int main(){
//initialize GLFW
if(!glfwInit()){
std::cerr << "GLFW initialization failed!" << std::endl;
glfwTerminate();
return 1;
}
//Setup GLFW window properties
//openGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// core profile = no backward compatibility
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//allow forward compatibility
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
GLFWwindow *mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "TEST WINDOW", NULL, NULL);
if(!mainWindow){
std::cerr << "GLFW Window creation failed" << std::endl;
glfwTerminate();
return 1;
}
// get Buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);
// set context for GLEW to use
glfwMakeContextCurrent(mainWindow);
// allow modern extension features
if(glewInit()!=GLEW_OK){
std::cerr << "GLEW initialization failed" << std::endl;
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
// setup viewport size
glViewport(0, 0, bufferWidth, bufferHeight);
CreateTriangles();
CompileShader();
while(!glfwWindowShouldClose(mainWindow)){
// get and handle user input events
glfwPollEvents();
glClearColor(1.0f, 0.0f, 0.0f, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
if(direction){
triOffset += 0.0005f;
}else{
triOffset -= 0.0005f;
triOffset = abs(triOffset);
}
if(direction<=0.0 || direction> triMaxOffset){
direction = !direction;
}
glUseProgram(shader);
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, glm::vec3(triOffset, 0.0f, 0.0f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE,glm::value_ptr(modelMatrix));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES,0,3);
glBindVertexArray(0);
glUseProgram(0);
// swap buffers
glfwSwapBuffers(mainWindow);
}
return 0;
}
如果我指出问题所在或暗示问题可能是什么,我将非常感激。预先感谢。
[模型矩阵变量glm::mat4 modelMatrix
必须由Identity matrix初始化。
glm API documentation指The OpenGL Shading Language specification。
5.4.2向量和矩阵构造器
如果向量构造器只有一个标量参数,它将用于将构造的向量的所有分量初始化为该标量的值。如果矩阵构造函数只有一个标量参数,它将用于初始化矩阵对角线上的所有分量,其余组件初始化为0.0。
Identity matrix可以通过单个参数1.0初始化:
glm::mat4 modelMatrix(1.0f);