!! Решение: Эта проблема возникла из-за использования старого драйвера - расширения не были доступны, хотя я ошибочно думал, что они были. Обновление драйвера решило проблему. См. Комментарии для диагностики и решения.
У меня есть среда сборки 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?