0

我正在使用本教程。我有正确的硬件来运行它(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);
}

}
4

1 回答 1

0

DLL/PDB 是正常的,我认为它对您的代码没有任何影响(我相信它涉及从 DLL 加载调试信息,这不是必需的)。

着色器有自己的错误报告机制,它在 glGetError 之外,你应该将它添加到你的代码中。

编译每个单独的着色器后,您要调用:

glGetShaderivwith 选项GL_COMPILE_STATUS(如果编译成功,则返回 true/false)。

如果编译失败,您可以通过glGetShaderInfoLog.

然后在链接程序后,您想调用glGetProgramivget GL_LINK_STATUS,并再次使用glGetProgramInfoLog.

于 2012-06-12T19:21:03.887 回答