總之請求明確的GL版本和配置文件(核心/兼容)(這是我的意思是通過發佈MCVE):
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cstdlib>
struct GlDebugOutput
{
static void Install()
{
if(!glewIsSupported("GL_ARB_debug_output"))
{
std::cerr << "GL_ARB_debug_output not supported" << std::endl;
return;
}
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(DebugCallback, 0);
glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
}
private:
static const char* Source(GLenum source)
{
switch(source)
{
case GL_DEBUG_SOURCE_API_ARB : return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB : return "WINDOW_SYSTEM";
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB : return "SHADER_COMPILER";
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB : return "THIRD_PARTY";
case GL_DEBUG_SOURCE_APPLICATION_ARB : return "APPLICATION";
case GL_DEBUG_SOURCE_OTHER_ARB : return "OTHER";
default : return "Unknown source";
}
}
static const char* Type(GLenum type)
{
switch(type)
{
case GL_DEBUG_TYPE_ERROR_ARB : return "ERROR";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB : return "DEPRECATED_BEHAVIOR";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB : return "UNDEFINED_BEHAVIOR";
case GL_DEBUG_TYPE_PORTABILITY_ARB : return "PORTABILITY";
case GL_DEBUG_TYPE_PERFORMANCE_ARB : return "PERFORMANCE";
case GL_DEBUG_TYPE_OTHER_ARB : return "OTHER";
default : return "Unknown type";
}
}
static const char* Severity(GLenum severity)
{
switch(severity)
{
case GL_DEBUG_SEVERITY_HIGH_ARB : return "HIGH";
case GL_DEBUG_SEVERITY_MEDIUM_ARB : return "MEDIUM";
case GL_DEBUG_SEVERITY_LOW_ARB : return "LOW";
default : return "Unknown severity";
}
}
static void APIENTRY DebugCallback
(
GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam
)
{
std::cerr << "GL_DEBUG"
<< ": " << Source(source)
<< ": " << Type(type)
<< ": " << Severity(severity)
<< ": " << message
<< std::endl;
}
};
struct Program
{
static GLuint Load(const char* vert, const char* geom, const char* frag)
{
GLuint prog = glCreateProgram();
if(vert) AttachShader(prog, GL_VERTEX_SHADER, vert);
if(geom) AttachShader(prog, GL_GEOMETRY_SHADER, geom);
if(frag) AttachShader(prog, GL_FRAGMENT_SHADER, frag);
glLinkProgram(prog);
CheckStatus(prog);
return prog;
}
private:
static void CheckStatus(GLuint obj)
{
GLint status = GL_FALSE;
if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status);
if(status == GL_TRUE) return;
GLchar log[ 1 << 15 ] = { 0 };
if(glIsShader(obj)) glGetShaderInfoLog(obj, sizeof(log), NULL, log);
if(glIsProgram(obj)) glGetProgramInfoLog(obj, sizeof(log), NULL, log);
std::cerr << log << std::endl;
exit(EXIT_FAILURE);
}
static void AttachShader(GLuint program, GLenum type, const char* src)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
CheckStatus(shader);
glAttachShader(program, shader);
glDeleteShader(shader);
}
};
#define GLSL(version, shader) "#version " #version "\n" #shader
const char* vert = GLSL
(
330,
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
);
const char* frag = GLSL
(
330,
out vec4 outputColor;
void main()
{
outputColor = vec4(1.0, 1.0, 1.0, 1.0);
}
);
GLuint VAO;
GLuint VBO;
GLuint prog;
void init()
{
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
float verts[] =
{
-1.0, -1.0,
1.0, -1.0,
0.0, 1.0,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
prog = Program::Load(vert, NULL, frag);
glUseProgram(prog);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
}
void display()
{
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(prog);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void glfwErrorCallback(int error, const char* description)
{
std::cerr << "GLFW error: " << description << std::endl;
}
int main(int argc, char** argv)
{
glfwSetErrorCallback(glfwErrorCallback);
if(GL_FALSE == glfwInit())
{
return EXIT_FAILURE;
}
std::cout << "GLFW version : " << glfwGetVersionString() << std::endl;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
if(NULL == window)
{
glfwTerminate();
return EXIT_FAILURE;
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glewExperimental = GL_TRUE;
const GLenum glewErr = glewInit();
if(GLEW_OK != glewErr)
{
std::cerr << "glewInit() failed: " << glewGetErrorString(glewErr) << std::endl;
glfwTerminate();
return EXIT_FAILURE;
}
// consume spurious GL error from GLEW init
glGetError();
GlDebugOutput::Install();
init();
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
int w, h;
glfwGetFramebufferSize(window, &w, &h);
glViewport(0, 0, w, h);
display();
glfwSwapBuffers(window);
}
return EXIT_SUCCESS;
}
如果您的OpenGL實現和/或着色器甚至有一點點關閉,程序應該將血腥謀殺尖叫爲stderr
並退出。
發佈包含着色器和上下文創建的[MCVE](http://stackoverflow.com/help/mcve)。 – genpfault 2015-02-09 19:30:04
@genpfault我假設你的意思是OpenGL上下文的創建,也應該包括我如何從着色器文件讀取? – Yago 2015-02-09 20:32:19
是的,窗口/上下文創建。您可以使用類似[this](http://stackoverflow.com/a/13874526/44729)的內容將着色器文本內聯到字符串中。使用[在上下文中](http://stackoverflow.com/questions/17602130/cant-draw-triangle-using-opengl/17604206#17604206)。 – genpfault 2015-02-09 20:33:21