glCreateShader返回0,需要帮助调试

时间:2011-08-13 18:58:55

标签: opengl

!!解决方案:这个问题源于使用旧驱动程序 - 扩展程序不可用,但我错误地认为它们是。升级驱动程序解决了问题。请参阅有关诊断和解决方案的注释。

我有一个使用cygwin和GCC的windows构建环境,并且链接到GLEE,GLUT和opengl32的库。这是一个Win32版本。

对glCreateShader的所有调用都返回0,但我没有收到任何错误。以下是基于GLUT和GLSL的Lighthouse教程,因此GL操作的顺序应该是正确的。

以下是相关代码..

#define WIN32

#include <stdio.h>

#include <GL/GLee.h>
#include <GL/glut.h>

#include "SampleUtils.h"
#include "LineShaders.h"

GLint lineVertexHandle      = 0;
unsigned int lineShaderProgramID;

...

int main(int argc, char **argv) {

// init GLUT and create window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("Lighthouse3D Tutorials");

// register callbacks
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);

    // initialize the shaders
init();
// enter GLUT event processing cycle
glutMainLoop();
return 0;
}

void init() {
glClearColor( 0.0, 0.0, 0.0, 1.0 ); /* Set the clear color */

lineShaderProgramID = SampleUtils::createProgramFromBuffer(lineMeshVertexShader,lineFragmentShader);

lineVertexHandle = glGetAttribLocation(lineShaderProgramID,"vertexPosition");

}

SampleUtils是一个实用程序类,具有以下着色器处理方法。着色器lineMeshVertexShader和lineFragmentShader在LineShaders.h中定义。

unsigned int
SampleUtils::createProgramFromBuffer(const char* vertexShaderBuffer,
                                 const char* fragmentShaderBuffer)
{

checkGlError("cPFB");

// scroll down for initShader() - we never get past this point.
GLuint vertexShader = initShader(GL_VERTEX_SHADER, vertexShaderBuffer);

if (!vertexShader)
    return 0;    

GLuint fragmentShader = initShader(GL_FRAGMENT_SHADER,
                                    fragmentShaderBuffer);
if (!fragmentShader)
    return 0;

GLuint program = glCreateProgram();
if (program)
{
    glAttachShader(program, vertexShader);
    checkGlError("glAttachShader");

    glAttachShader(program, fragmentShader);
    checkGlError("glAttachShader");

    glLinkProgram(program);
    GLint linkStatus = GL_FALSE;
    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);

    if (linkStatus != GL_TRUE)
    {
        GLint bufLength = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
        if (bufLength)
        {
            char* buf = (char*) malloc(bufLength);
            if (buf)
            {
                glGetProgramInfoLog(program, bufLength, NULL, buf);
                LOG("Could not link program: %s", buf);
                free(buf);
            }
        }
        glDeleteProgram(program);
        program = 0;
    }
}
return program;

}

unsigned int
SampleUtils::initShader(unsigned int shaderType, const char* source)
{
checkGlError("initShader");
//GLuint shader = glCreateShader((GLenum)shaderType);

/* trying explicit enum, just in case - shader is still always 0 */
GLuint shader = glCreateShader(GL_VERTEX_SHADER);

LOG("SHADER %i", shader);

if (shader)
{
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);
    GLint compiled = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);

    if (!compiled)
    {
        GLint infoLen = 0;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
        if (infoLen)
        {
            char* buf = (char*) malloc(infoLen);
            if (buf)
            {
                glGetShaderInfoLog(shader, infoLen, NULL, buf);
                LOG("Could not compile shader %d: %s", 
                    shaderType, buf);
                free(buf);
            }
            glDeleteShader(shader);
            shader = 0;
        }
    }
}
return shader;

}

void
SampleUtils::checkGlError(const char* operation)
{ 

for (GLint error = glGetError(); error; error = glGetError())
    LOG("after %s() glError (0x%x)", operation, error);


}

我想知道在调用glCreateShader时上下文是否未完全初始化。但我也尝试在回调中调用init(),但没有效果。我对这个问题的搜索提出了建立一个已知良好示例的建议,以确认glCreateShader的可用性 - 如果有人有一个C ++,请建议。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

更新:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

根据这里的反馈,我使用glewinfo实用程序检查了我的OpenGL支持,并且它报告此系统仅限于1.1。 - https://docs.google.com/document/d/1LauILzvvxgsT3G2KdRXDTOG7163jpEuwtyno_Y2Ck78/edit?hl=en_US

e.g。

---------------------------
    GLEW Extension Info
---------------------------

GLEW version 1.6.0
Reporting capabilities of pixelformat 2
Running on a GDI Generic from Microsoft Corporation
OpenGL version 1.1.0 is supported

GL_VERSION_1_1:                                                OK
---------------

GL_VERSION_1_2:                                                MISSING
---------------

etc.

奇怪的是,使用GLEE我能够编译这些扩展,尽管它们显然不起作用。我检查了我的gl.h和glext.h头文件,它们是最新的 - 扩展就在那里。那么在Windows上如何解决这个问题呢?你如何设置和链接你的环境,以便你可以使用cygwin和Eclipse进行超过1.1的开发?

2 个答案:

答案 0 :(得分:4)

评论中提供了这个问题的解决方案,我在此突出显示它以便结束这个问题。

所需要的只是驱动程序升级到支持我正在使用的扩展程序的版本。所以我安装了NVidia的OpenGL驱动程序,可以在这里获得 - http://developer.nvidia.com/opengl-driver

似乎我的系统的原始NVidia驱动程序已被破坏,因此正在使用本机Windows OpenGL驱动程序。这仅支持OpenGL 1.1。但我错误地认为在Windows上GL_VERSION为1.1.0是正常的 - 基于我得到的一些不好的建议。事实上,我能够无错误地编译和执行此代码,这使我认为扩展存在。他们不是。

答案 1 :(得分:3)

我遇到了同样的问题,但这是一个愚蠢的C ++语言技巧:我的着色器是在全局/静态变量(使用程序着色器的包装类)中编译的,在具有GL上下文之前已经初始化了。希望它可以帮助...