glCreateShader возвращает 0, нужна помощь в отладке - PullRequest
3 голосов
/ 13 августа 2011

!! Решение: Эта проблема возникла из-за использования старого драйвера - расширения не были доступны, хотя я ошибочно думал, что они были. Обновление драйвера решило проблему. См. Комментарии для диагностики и решения.

У меня есть среда сборки Windows, использующая Cygwin и GCC, и я делаю ссылки на библиотеки для GLEE, GLUT и opengl32. Это сборка Win32.

Все вызовы glCreateShader возвращают 0, но я не вижу никаких ошибок. Нижеследующее основано на руководствах Lighthouse для 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:

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

Основываясь на полученных здесь отзывах, я проверил свою поддержку OpenGL с помощью утилиты glewinfo, и она сообщает, что эта система ограничена до 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? Как вы настраиваете и связываете свою среду, чтобы вы могли разрабатывать с более чем 1.1, используя cygwin и Eclipse?

Ответы [ 2 ]

4 голосов
/ 15 августа 2011

Решение этого вопроса было предоставлено в комментариях, и я выделю его здесь, чтобы закрыть этот вопрос.

Все, что требовалось, - это обновление драйвера до версии, которая поддерживает расширения, которые я использую . Поэтому я установил драйвер OpenGL от NVidia, который можно найти здесь - http://developer.nvidia.com/opengl-driver

Похоже, что исходный драйвер моей системы NVidia был подорван, так что использовался собственный драйвер Windows OpenGL. Это поддерживает только OpenGL 1.1. Но я ошибочно подумал, что GL_VERSION версии 1.1.0 нормален для Windows - основываясь на некоторых дурных советах, которые я получил. И тот факт, что я смог скомпилировать и выполнить этот код без ошибок, заставил меня предположить, что расширения присутствовали. Их не было.

3 голосов
/ 06 ноября 2014

У меня была та же проблема, но это был глупый трюк на языке C ++: мой шейдер был скомпилирован в глобальную / статическую переменную (которая была классом-оберткой для использования программного шейдера), который был инициализирован до того, как появился контекст GL , Надеюсь, это поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...