【问题标题】:glCreateShader returns 0glCreateShader 返回 0
【发布时间】:2011-08-13 18:58:54
【问题描述】:

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

所有对 glCreateShader 的调用都返回 0,但我没有发现任何错误。以下是基于灯塔教程的GLUT和GLSL,所以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++ 的,请建议。


UPDATE:

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

例如

---------------------------
    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 的开发?

【问题讨论】:

  • 我从未使用过 GLee,但我知道由于其独特的加载方法,如果您的 OpenGL 版本不支持该功能,它可能会简单地返回 0。那么您是否获得了 OpenGL 上下文版本 2.0 或更高版本?
  • 没有 glGetString(GL_VERSION) 给我 1.1.0。但我读过这在 Windows 上是可以预料的。我会试试 GLEW 看看是否有帮助。
  • @olo 我认为 GLEW 不会改变这一点。只有当您的硬件仅支持 GL 1.1 或者您有一个非常旧的图形驱动程序(可能是 Windows 默认的?)时,才会出现这种情况。或者您可能链接到错误的“opengl32.dll”而不是系统目录中的那个?。
  • 我的 NVidia 驱动程序是 8.15.11.8593 版,日期为 2009 年。这是在较新的 Win 7 64 位系统上。我正在链接到 opengl32,它应该是我 system32 目录中的 dll。
  • 如果您获得的是 1.1.0 版本,那么您正在错误地初始化 OpenGL。

标签: opengl


【解决方案1】:

cmets 中提供了这个问题的解决方案,我在此强调它是为了结束这个问题。

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

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

【讨论】:

  • 如果其他人遇到和我一样的问题:我在一些调试代码中的 glBegin() 和 glEnd() 期间不小心调用了 glCreateShader()。它返回 0 并且没有给出错误。在 glBegin() 和 glEnd() 中只能调用 OpenGL 函数的子集。见opengl.org/sdk/docs/man2/xhtml/glBegin.xml
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 2015-06-21
    • 2016-10-28
    • 2019-02-20
    • 2015-06-17
    • 2012-01-04
    • 2018-02-23
    相关资源
    最近更新 更多