我正在使用本教程。我有正确的硬件来运行它(AMD 6870)。我已经按照教程进行了操作,但在它退出之前我只看到了一个闪烁的窗口。当我构建代码时,它构建得很好,但列出了大量找不到 PDB 的 DLL。我单步执行了我的代码(我使用 Visual Studio 2010 prof),它在我的 CreateShaders 函数上退出,并出现无法创建它们的错误。我已经检查了有关该功能的教程,并复制了它。
这是代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define WINDOW_TITLE_PREFIX "Chapter Two - A Triangle"
//Global variable dclerations
int CurrentWidth = 800;
int CurrentHeight = 600;
int WindowHandle = 0;
unsigned FrameCount = 0;
GLuint
vertexShaderId,
fragmentShaderId,
programId,
vaoId,
vboId,
colorBufferId;
//contents of GLSL vertexshader
const GLchar* vertexShader =
{
"version 400\n"\
"layout(location=0) in vec4 in_Position;\n"\
"layout(location=1) in vec4 in_Color;\n"\
"out vec4 ex_Color;\n"\
"void main(void)\n"\
"{\n"\
" gl_Position = in_Position;\n"\
" ex_Color = in_Color;\n"\
"}\n"
};
//contents of fragment shader
const GLchar* fragmentShader =
{
"#version 400\n"\
"in vec4 ex_Color;\n"\
"out vec4 out_Color;\n"\
"void main(void)\n"\
"{\n"\
" out_Color = ex_Color;\n"\
"}\n"
};
//prototypes
void Initialize(int,char*[]);
void InitWindow(int, char*[]);
void ResizeFunction(int, int);
void RenderFunction(void);
void TimerFunction(int);
void IdleFunction(void);
void CleanUp(void);
void CreateVBO(void);
void DestroyVBO(void);
void CreateShaders(void);
void DestroyShaders(void);
int main(int argc, char* argv[])
{
Initialize(argc, argv);
glutMainLoop();
exit(EXIT_SUCCESS);
}
void Initialize(int argc, char* argv[])
{
GLenum GlewInitResult;
InitWindow(argc, argv);
//glew is initialised after the openGL context is created,
//it needs an active context to implement calls
GlewInitResult = glewInit();
//if glew did not init correctly, print errors
if(GLEW_OK != GlewInitResult)
{
fprintf(
stderr,
"ERROR: %s\n",
glewGetErrorString(GlewInitResult)
);
exit(EXIT_FAILURE);
}
fprintf(
stdout,
"INFO: OpenGL Version: %s\n",
glGetString(GL_VERSION));
CreateShaders();
CreateVBO();
glClearColor(0.0f, 0.0f, 0.0f,0.0f);
}
//uses freeglut to create a window
void InitWindow(int argc, char* argv[])
{
//initialises freeglut library
glutInit(&argc, argv);
//creates a forward compatible OpenGL 4.0 core profile
glutInitContextVersion(4,0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
//when window closes, return to main loop
glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);
glutInitWindowSize(CurrentWidth,CurrentHeight);
// enables depth buffer, double buffering, makes RGBA mode
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
//makes window, passes it the value of defined window
WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
if(WindowHandle < 1)
{
fprintf(
stderr,
"ERROR: Could not create a new rendering window.\n"
);
exit(EXIT_FAILURE);
}
//called when window is resized
glutReshapeFunc(ResizeFunction);
//called when scene is to be drawn on screen
glutDisplayFunc(RenderFunction);
glutIdleFunc(IdleFunction);
//(ms passed before func is called, func to call, value to pass)
glutTimerFunc(0,TimerFunction,0);
glutCloseFunc(CleanUp);
}
void ResizeFunction(int Width, int Height)
{
CurrentWidth = Width;
CurrentHeight = Height;
glViewport(0,0,CurrentWidth,CurrentHeight);
}
void RenderFunction(void)
{
FrameCount++;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES,0,3);
glutSwapBuffers();
glutPostRedisplay();
}
//redraws as soon as possible
void IdleFunction(void)
{
glutPostRedisplay();
}
void TimerFunction(int Value)
{
if(0 != Value)
{
char* TempString = (char*)
malloc(512 + strlen(WINDOW_TITLE_PREFIX));
sprintf(
TempString,
"%s: %d Frames Per Second @ %d x %d",
WINDOW_TITLE_PREFIX,
//update every quarter of a second
FrameCount * 4,
CurrentWidth,
CurrentHeight
);
glutSetWindowTitle(TempString);
free(TempString);
}
FrameCount = 0;
glutTimerFunc(250, TimerFunction,1);
}
void CleanUp (void)
{
DestroyShaders();
DestroyVBO();
}
void CreateVBO(void)
{
GLfloat vertices[] = {
-0.8f, -0.8f, 0.0f, 1.0f,
0.0f, 0.8f, 0.0f, 1.0f,
0.8f, -0.8f, 0.0f, 1.0f
};
GLfloat colors[] = {
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f
};
GLenum ErrorCheckValue = glGetError();
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(0);
glGenBuffers(1, &colorBufferId);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferId);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(1);
ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not create a VBO: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}
void DestroyVBO(void)
{
GLenum ErrorCheckValue = glGetError();
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glDeleteBuffers(1, &colorBufferId);
glDeleteBuffers(1, &vboId);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vaoId);
ErrorCheckValue = glGetError();
if(ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not Destroy the VBO: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}
void CreateShaders(void)
{
GLenum ErrorCheckValue = glGetError();
vertexShaderId =glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderId, 1, &vertexShader, NULL);
glCompileShader(vertexShaderId);
fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, 1, &fragmentShader, NULL);
glCompileShader(fragmentShaderId);
programId = glCreateProgram();
glAttachShader(programId, vertexShaderId);
glAttachShader(programId,fragmentShaderId);
glLinkProgram(programId);
glUseProgram(programId);
ErrorCheckValue = glGetError();
if(ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not create the shaders: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}
void DestroyShaders(void)
{
GLenum ErrorCheckValue = glGetError();
glUseProgram(0);
glDetachShader(programId,vertexShaderId);
glDetachShader(programId,fragmentShaderId);
glDeleteShader(fragmentShaderId);
glDeleteShader(vertexShaderId);
glDeleteProgram(programId);
ErrorCheckValue = glGetError();
if(ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"Error: Could not destroy the shaders %s\n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}