我的简单 OpenGL 应用程序无法在我女朋友的机器上运行,我遇到了一个非常奇怪的问题。起初我想到了我的代码的各种问题,但我终于可以将其分解为这段代码不起作用(不起作用意味着:三角形绘制正确,但是黑色,即没有正确的颜色):
#include <stdio.h>
#include <stdlib.h>
#include <string>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
#include "../common/shader.h"
const GLfloat reticle_vertices[] =
{
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
glm::mat4 MVP;
glm::mat4 vp;
const char *vertexSource =
"#version 150\n"
"layout(location = 0) in vec3 position;"
"layout(location = 1) in vec3 color;"
"out vec3 fragColor;"
"uniform mat4 MVP;"
"void main() {"
"gl_Position = MVP * vec4(position, 1.0);"
"fragColor = color;"
"}";
const char *fragmentSource =
"#version 150\n"
"in vec3 fragColor;"
"out vec4 outColor;"
"void main() {"
"outColor = vec4(fragColor, 1.0);"
"}";
// Key callback: exit on ESCAPE
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
// Initialize and return a window with GLFW
GLFWwindow *initGLWindow(int width, int height, int samples, const char *title, GLFWkeyfun keycb)
{
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
return NULL;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_SAMPLES, samples);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *w = glfwCreateWindow(width, height, title, NULL, NULL);
if (!w)
{
glfwTerminate();
return NULL;
}
glfwMakeContextCurrent(w);
glfwSetKeyCallback(w, keycb);
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
return NULL;
}
return w;
}
int main()
{
// Initialize the OpenGL window
GLFWwindow *window = initGLWindow(1024, 768, 2, "Schnuff", key_callback);
// Load and use the shaders
GLuint programID = LoadShaders(vertexSource, fragmentSource);
glUseProgram(programID);
// Get the attribute locations
GLuint posAttrib = glGetAttribLocation(programID, "position");
printf("posAttrib = %d\n", posAttrib);
GLuint colAttrib = glGetAttribLocation(programID, "color");
printf("colAttrib = %d\n", colAttrib);
//GLint normAttrib = glGetAttribLocation(programID, "normal");
//printf("normAttrib = %d\n", normAttrib);
GLuint mvpID = glGetUniformLocation(programID, "MVP");
// Vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Vertex buffer object
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(reticle_vertices), reticle_vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
// Hide the cursor
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glClearColor(0.0f, 0.0f, 0.2f, 1.0f);
glm::mat4 m = glm::mat4(1.0f);
// Main loop
do
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(mvpID, 1, GL_FALSE, &m[0][0]);
glVertexAttrib3f(colAttrib, 1.0f, 0.0f, 0.0f);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
while (!glfwWindowShouldClose(window));
glDeleteProgram(programID);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
据我所知,问题的发生仅是由于以下原因:在她的机器上posAttrib = 1, colAttrib = 0
,而在我的机器上却是相反的。我尝试使用
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;
然后它工作正常!虽然一旦我交换了这些数字(我还没有用其他值和 测试它#version 330 core\n
,但她的笔记本电脑目前处于离线状态),它再次停止工作......
我什至在 SO 上发现了以下未回答的问题,这似乎非常密切相关。
你们中是否有人遇到过类似的行为,或者知道如何在不必使用的情况下解决整个情况layout(location = x)
?因为我认为在一个更大的项目中,手动设置每个位置可能是乏味或不需要的(如果我错了,请纠正我,这实际上是首选的方法!)。
尚未测试:0 或 1 以外的其他值,以及其他值#version
,因为在我的机器上我什至无法使用layout(location = x)
(#version 330 core
这又很奇怪,因为它显然在她的机器上做了一些使它工作的东西)。
我是 OpenGL 的新手,因此在这里完全感到困惑!:-)