OpenGL glLinkProgram возвращает false, но информационный журнал пуст; проверил все

Я должен признать, что я впервые использую шейдеры, ранее я работал только с конвейером фиксированных функций; однако, хотя я уверен, что все, что я сделал, правильно - должна быть ошибка.

glLinkProgram(program) - возвращаетGL_FALSE когда запрашиваетсяGL_LINK_STATUS, Кроме того, информационный журнал пуст (когда я запрашиваю длину журнала - она равна 1, что является нулевым терминатором для документов, оно проверяется). Так что ошибки компоновщика, а не логи. Кроме того, я только что обнаружил, что проблемы с компоновщиком возникают, как только я используюgl_Position переменная в вершинном шейдере, как при назначении, так и при использовании его для расчетов. Я перепробовал всевозможные варианты шейдеров, он выдает ошибки, но он не может создать логи - он просто возвращаетGL_FALSE в любой моментgl_Position тронут. Интересно, что фрагментный шейдер не вызывает никаких проблем.

Фрагментные и вершинные шейдеры компилируются без ошибок. Когда я ввожу синтаксические ошибки, они обнаруживаются, распечатываются, и процесс прерывается перед созданием программы (так что, похоже, он работает нормально). Я отладил и удостоверился, что файлы загружаются правильно, источник завершен нулем, размеры правильные, я проверил количество вложенных программ после вложения, и оно равно 2 (правильно lol). Это удалено для ясности, у меня естьcheckForErrors() метод, который проверяет и печатает ошибки opengl - ни одна не обнаружена.

Я в тупике, пожалуйста, помогите кому-нибудь! Я терял сон из-за этого уже 2 дня ...

Это код для загрузки шейдера:

FILE *file = fopen(fileName.c_str(), "rb");

if(file == NULL)
{
    Log::error("file does not exist: \"" + fileName + "\"");
    return NULL;
}

// Calculate file size
fseek(file , 0 , SEEK_END);
int size = ftell(file);
rewind(file);

// If file size is 0
if(size == 0)
{
    Log::error("file is empty: \"" + fileName + "\"");
    return NULL;
}

char **source = new char*[1];
source[0] = new char[size+1];
source[0][size] = '\0';

// If we weren't able to read the entire file into memory
int readSize = fread(source[0], sizeof(char), size, file);
if(size != readSize)
{
    int fileError = ferror(file);

    // Free the source, log an error and return false
    delete source[0];
    delete [] source;
    fclose(file);
    Log::error("couldn't load file into memory [ferror(" + toString<int>(fileError) + ")]: \"" + fileName + "\" (Size: " + toString<int>(readSize) + "/" + toString<int>(size) + " bytes)");
    return NULL;
}

// Close the file
fclose(file);




// Create the shader object


// shaderType is GLenum that is set based on the file extension. I assure you it is correctly set to either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
GLuint shaderID = glCreateShader(shaderType);

// If we could not create the shader object, check for OpenGL errors and return false
if(shaderID == 0)
{
    checkForErrors();
    Log::error("error creating shader \"" + name);
    delete source[0];
    delete [] source;
    return NULL;
}

// Load shader source and compile it
glShaderSource(shaderID, 1, (const GLchar**)source, NULL);
glCompileShader(shaderID);

GLint success;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
if(!success)
{
    GLchar error[1024];
    glGetShaderInfoLog(shaderID, 1024, NULL, error);
    Log::error("error compiling shader \"" + name + "\"\n    Log:\n" + error);
    delete source[0];
    delete [] source;
    return NULL;
}
else
{
    Log::debug("success! Loaded shader \"" + name + "\"");
}

// Clean up
delete source[0];
delete [] source;

Краткое примечание: glShaderSource - я приведу к (const GLchar **), потому что GCC жалуется на const на неконстантные указатели на символы; В противном случае, я считаю, что я полностью податлив.

Кстати, ошибок там нет. Шейдеры (ниже) компилируются без ошибок.

Вершинный шейдер:

void main()
{
    // If I comment the line below, the link status is GL_TRUE.
    gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
}

Фрагмент шейдера:

void main()
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Ниже приведен код, который создает шейдерную программу, прикрепляет объекты и ссылки и т. Д .:

// Create a new shader program
GLuint program = glCreateProgram();
if(program == 0)
{
    Log::error("RenderSystem::loadShaderProgram() - could not create OpenGL shader program; This one is fatal, sorry.");
    getContext()->fatalErrorIn("RenderSystem::loadShaderProgram(shader1, shader2)", "OpenGL failed to create object using glCreateProgram()");
    return NULL;
}

// Attach shader objects to program
glAttachShader(program, vertexShaderID);
glAttachShader(program, fragmentShaderID);

// Link the program
GLint success = GL_FALSE;
glLinkProgram(program);
checkForErrors();
glGetProgramiv(program, GL_LINK_STATUS, &success);
if(success == GL_FALSE)
{
    GLchar errorLog[1024] = {0};
    glGetProgramInfoLog(program, 1024, NULL, errorLog);
    Log::error(std::string() + "error linking program: " + errorLog);
    return NULL;
}

success = GL_FALSE;
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &success);
if(success == GL_FALSE)
{
    GLchar errorLog[1024] = {0};
    glGetProgramInfoLog(program, 1024, NULL, errorLog);
    checkForErrors();
    Log::error(std::string() + "error validating shader program; Details: " + errorLog);
    return NULL;
}

Обычно это даже не доходит до проверки программы ... Я так расстроен этим, очень трудно не быть вульгарным.

Ваша помощь необходима, и любая помощь искренне ценится!

РЕДАКТИРОВАТЬ: я все работаю на Intel HD 3000 (с поддержкой OpenGL до 3.1). Моя целевая версия OpenGL - 2.0.

РЕДАКТИРОВАТЬ 2: Я также хотел бы отметить, что у меня были некоторые проблемы с чтением шейдеров из текстовых файлов, если я установил флаги «r» или «rt» в fopen - размер чтения был меньше, чем фактический размер примерно на 10 байтов (последовательно на все файлы) - и feof () вернет true. Когда я переключился на чтение в двоичном формате («rb»), проблема исчезла, и файлы были прочитаны полностью. Я попробовал несколько альтернативных реализаций, и все они выдавали одну и ту же ошибку во время компоновки (и я печатаю исходный код шейдера на консоль сразу после чтения файла, чтобы убедиться, что он выглядит правильно.)

Ответы на вопрос(1)

Ваш ответ на вопрос