我使用来自cglm的矩阵来修改相机,我应该在屏幕上看到的是一个小正方形,但什么也没有显示。我有这样的代码:
#define GLEW_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include<stdio.h>
#include<stdlib.h>
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<stdbool.h>
#include<string.h>
#include<stb/stb_image.h>
#include<cglm/cglm.h>
const unsigned int width = 1054;
const unsigned int height = 1057;
GLint uniColor;
GLint xploc;
GLint yploc;
void key_callback();
int main(){
if(!glfwInit()){
printf("Failed to initialize glfw!n");
return 1;
}else{
printf("Successfully initialized glfw!n");
}
//Set up GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(width, height, "Title", NULL, NULL);
glfwSetKeyCallback(window, key_callback);
if(!window){
printf("Window creation failed!n");
return 1;
}else{
printf("Window created successfully!n");
}
glfwMakeContextCurrent(window);
//Initialize GLEW
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK){
printf("Failed to initialize glew!n");
return 1;
}else{
printf("Successfully initialized glew!n");
}
//Set the swap interval to 1 millisecond
glfwSwapInterval(1);
//Set the vertices of the square
float Vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f
};
//Set indices to make the square work
GLuint indices[] = {
0, 2, 1,
0, 3, 2
};
//Ignore this - it was the original square, but then I realized how I actually needed to make it work
float VerticesSquare[] = {
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
printf("GLfloat variable called successfullyn");
//Create, compile and link the shaders to the shader program
GLuint ShaderProgram = glCreateProgram();
GLuint ShaderObjv = glCreateShader(GL_VERTEX_SHADER);
GLuint ShaderObjf = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* pvs[1];
const GLchar* pfs[1];
//Set the shader code
const char* pVertexShaderText = "#version 330 coren"
"layout(location = 0) in vec3 Position;n"
"layout(location = 1) in vec3 incolor;n"
"layout(location = 2) in vec2 Tex;n"
"out vec3 outcolor;n"
"out vec2 texcoords;n"
"uniform uint xp;n"
"uniform uint yp;n"
"uniform mat4 model;n"
"uniform mat4 view;n"
"uniform mat4 proj;n"
"void main(){n"
" gl_Position = proj * view * model * vec4(Position, 1.0f);n"
"outcolor = incolor;n"
"texcoords = Tex;n"
"}";
const char* pFragmentShaderText = "#version 330 coren"
"uniform vec3 color;n"
"uniform sampler2D tex0;n"
"in vec3 outcolor;n"
"in vec2 texcoords;n"
"out vec4 FragColor;n"
"void main(){n"
" FragColor = vec4(outcolor, 1.0f);n"
"}";
pvs[0] = pVertexShaderText;
pfs[0] = pFragmentShaderText;
GLint LenghtsVertex[1];
GLint LenghtsFragment[1];
LenghtsVertex[0] = strlen(pVertexShaderText);
LenghtsFragment[0] = strlen(pFragmentShaderText);
glShaderSource(ShaderObjv, 1, pvs, LenghtsVertex);
glShaderSource(ShaderObjf, 1, pfs, LenghtsFragment);
glCompileShader(ShaderObjv);
glCompileShader(ShaderObjf);
//Shader error handling
GLint successvs;
glGetShaderiv(ShaderObjv, GL_COMPILE_STATUS, &successvs);
if(!successvs){
GLchar InfoLog1[1024];
glGetShaderInfoLog(ShaderObjv, sizeof(InfoLog1), NULL, InfoLog1);
fprintf(stderr, "Error compiling shader type %d: '%s'n", GL_VERTEX_SHADER, InfoLog1);
return 1;
}
GLint successfs;
glGetShaderiv(ShaderObjf, GL_COMPILE_STATUS, &successfs);
if(!successfs){
GLchar InfoLog2[1024];
glGetShaderInfoLog(ShaderObjf, sizeof(InfoLog2), NULL, InfoLog2);
fprintf(stderr, "Error compiling shader type %d: '%s'n", GL_FRAGMENT_SHADER, InfoLog2);
return 1;
}
glAttachShader(ShaderProgram, ShaderObjv);
glAttachShader(ShaderProgram, ShaderObjf);
glLinkProgram(ShaderProgram);
GLint success;
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &success);
if(!success){
GLchar InfoLog3[1024];
glGetProgramInfoLog(ShaderProgram, sizeof(InfoLog3), NULL, InfoLog3);
fprintf(stderr, "Error linking shader program: '%s'n", InfoLog3);
return 1;
}
glValidateProgram(ShaderProgram);
GLint successl;
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &successl);
if(!successl){
GLchar InfoLog4[1024];
glGetProgramInfoLog(ShaderProgram, sizeof(InfoLog4), NULL, InfoLog4);
fprintf(stderr, "Error validating shader program: '%s'n", InfoLog4);
return 1;
}
glUseProgram(ShaderProgram);
//Set the vectors for the camera location
vec3 camerapos = {0.0f, 0.0f, -4.0f};
vec3 center = {0.0f, 0.0f, 0.0f};
vec3 yup = {0.0f, 1.0f, 0.0f};
//Create the matrices and make them be identity matrices
mat4 model;
mat4 view;
mat4 proj;
glm_mat4_identity(model);
glm_mat4_identity(view);
glm_mat4_identity(proj);
//Create the camera
glm_lookat(camerapos, center, yup, view);
glm_perspective(glm_rad(45.0f), (float)(width/height), 0.1f, 100.0f, proj);
//Set the uniform locations
GLint uniColor = glGetUniformLocation(ShaderProgram, "color");
GLint tex0uni = glGetUniformLocation(ShaderProgram, "tex0");
GLint xploc = glGetUniformLocation(ShaderProgram, "xp");
GLint yploc = glGetUniformLocation(ShaderProgram, "yp");
GLint modelloc = glGetUniformLocation(ShaderProgram, "model");
GLint viewloc = glGetUniformLocation(ShaderProgram, "view");
GLint projloc = glGetUniformLocation(ShaderProgram, "proj");
//Set the uniforms
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
glUniform1i(tex0uni, 0);
glUniform1ui(xploc, 1);
glUniform1ui(yploc, 1);
glUniformMatrix4fv(modelloc, 1, GL_FALSE, (float*)model);
glUniformMatrix4fv(viewloc, 1, GL_FALSE, (float*)view);
glUniformMatrix4fv(projloc, 1, GL_FALSE, (float*)proj);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//Create the buffers
GLuint VBO;
GLuint VAO = 0;
GLuint EBO;
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
printf("Buffer created successfullyn");
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
printf("Buffer data set up successfullyn");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
printf("Enabling buffer successfulln");
//Set the texture (I won't be using it for now)
int texwidth, texheight, texnum;
stbi_set_flip_vertically_on_load(true);
unsigned char* bytes = stbi_load("image.png", &texwidth, &texheight, &texnum, 0);
GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float flatcolor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, flatcolor);
printf("Set parameters successfullyn");
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texwidth, texheight, 0, GL_RGB, GL_UNSIGNED_BYTE, bytes);
glGenerateMipmap(GL_TEXTURE_2D);
printf("Texture set successfullyn");
//Set the VertexAttribPointers at locations 0, 1 and 2
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
printf("First pointer succeededn");
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
printf("Second pointer succeededn");
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
printf("Third pointer succeededn");
printf("Setting up VectexAttribPointer successfulln");
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//glDrawArrays(GL_TRIANGLES, 0, 3);
//Draw the elements
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
GLenum err;
if((err = glGetError()) != GL_NO_ERROR){
printf("OpenGL error: %dn", err);
}
glfwSwapBuffers(window);
}
return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if(key == GLFW_KEY_R && action == GLFW_PRESS){
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
}else if(key == GLFW_KEY_G && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 1.0f, 0.0f);
}else if(key == GLFW_KEY_B && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 0.0f, 1.0f);
}else if(key == GLFW_KEY_D && action == GLFW_PRESS){
glUniform1ui(xploc, 2);
}else if(key == GLFW_KEY_A && action == GLFW_PRESS){
glUniform1ui(xploc, 1);
}
}
我搜索了cglm的文档,但没有找到修复。有一些关于类似主题的旧stackoverflow问题,但没有一个真正解决我的问题。我认为这与我如何向cglm的函数提供信息有关。我添加了注释,这样更容易阅读。
事实证明,(float)(width/height)
应该是(float)width/(float)height
,因为第一个例子实际上输出的是0或1,而不是0.99716177861。