Шейдеры OpenGL не связаны с шейдерной программой

Я пытаюсь добавить шейдеры с помощью GLFW/GLEW.

Я получаю сообщение об ошибке, что шейдеры загружены, но у них нет допустимого объектного кода.

Это код, который у меня есть для загрузки шейдеров:

class SHADER {
public:

void LoadShaders(const char *vertexFile, const char *fragmentFile);

char *vertexShader;
char *fragmentShader;

private:

int Load(const char *filename, char*&shaderSource);
fstream file;
};

int SHADER::Load(const char *filename, char *&shaderSource) {
file.open(filename, ios::in);
if(file.is_open()) {
    file.tellg();
    file.seekg(0,ios::end);
    unsigned long len = file.tellg();
    file.seekg(ios::beg);

    if(len == 0 ) {
        return -2;
    } else {
        shaderSource = new char[len + 1];
        file.read(shaderSource,len);
        file.close();
        printf("%s\n",shaderSource);
    }
} else {
    return -1;
}
return 0;
}

void SHADER::LoadShaders(const char *vertexFile, const char *fragmentFile) {
int resultVertex = this->Load(vertexFile, vertexShader);
int resultFragment = this->Load(fragmentFile, fragmentShader);
if(resultVertex ==0 && resultFragment ==0) {
    printf("Shaders loaded succesfully.\n");
}
if(resultVertex == -2) {
    printf("VertexShader is empty!\n");
}
if(resultFragment == -2) {
    printf("FragmentShader is empty!\n");
}
if(resultVertex == -1) {
    printf("Unable to load VertexShader!\n");
}
if(resultFragment == -1) {
    printf("Unable to load FragmentShader!\n");
}
}

Это код для инициализации шейдеров:

SHADER Shaders;
GLhandleARB vertexShader, fragmentShader, shaderProgram;

Shaders.LoadShaders("vertexShader.vert","fragmentShader.frag");

const char* vertTemp = Shaders.vertexShader;
vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
glShaderSourceARB(vertexShader, 1, &vertTemp, NULL);
glCompileShaderARB(vertexShader);
traceShaderInfoLog(vertexShader);

const char* fragTemp = Shaders.fragmentShader;
fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
glShaderSourceARB(fragmentShader, 1, &fragTemp, NULL);
glCompileShaderARB(fragmentShader);
traceShaderInfoLog(fragmentShader);

delete[] Shaders.vertexShader;
delete[] Shaders.fragmentShader;

shaderProgram = glCreateProgramObjectARB();
glAttachObjectARB(shaderProgram,vertexShader);
glAttachObjectARB(shaderProgram,fragmentShader);
glLinkProgramARB(shaderProgram);
traceProgramInfoLog(shaderProgram);

glUseProgramObjectARB(shaderProgram);

Это vertexShader.vert и fragmentShader.frag:

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

И это ошибка, которую я получаю, когда печатаю журнал, я получаю этот действительно странный символ в конце сценариев, который появляется каждый раз, когда я снова компилирую другой символ:

void main(){
    //gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_Position = ftransform();
}┘
void main(){
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}♣
Shaders loaded succesfully.
Vertex shader was successfully compiled to run on hardware.

Fragment shader failed to compile with the following errors:
ERROR: 0:3: error(#132) Syntax error: '<' parse error
ERROR: error(#273) 1 compilation errors.  No code generated

Fragment shader(s) were not successfully compiled before glLinkProgram() was called.
Link failed.

person tversteeg    schedule 20.06.2012    source источник
comment
Странный символ возникает из-за того, что не удалось добавить NUL (вы оставили для него место, но никогда не записывали последний символ). В Shader::LOAD установите shaderSource[len] = 0;.   -  person Ben Voigt    schedule 20.06.2012
comment
Я все еще получаю странный символ, когда устанавливаю shaderSource[len] = 0;   -  person tversteeg    schedule 20.06.2012


Ответы (2)


Ваша функция загрузки, скорее всего, проблема: подпись должна читаться

int SHADER::Load(const char *filename, char *&shaderSource) // Note the &

для быстрого исправления. Вы выделяете память в этой функции и переназначаете ее указателю — вы только загружаете источник по этому адресу — но это никогда не покидает функцию.

Компилятор, скорее всего, получает пустую строку из-за того, что память инициализируется нулем (вы запускаете это в отладке?) и не терпит неудачу, потому что иногда это нормально. Но компоновщик замечает, что на самом деле нет никакого кода для компоновки!

person ltjax    schedule 20.06.2012
comment
Кроме того, вы не должны освобождать () память, которую вы обновили [] - вы должны удалить [] ее. И деструктор вашего класса SHADER будет там, где это можно сделать, а также инициализирует нулевыми значениями эти указатели в конструкторе. Или еще лучше: используйте std::string или любой достойный строковый класс. - person ltjax; 20.06.2012
comment
Спасибо, но теперь я получил эту ошибку: Shaders loaded succesfully. Vertex shader was successfully compiled to run on hardware. Fragment shader failed to compile with the following errors: ERROR: 0:3: error(#132) Syntax error: '<' parse error ERROR: error(#273) 1 compilation errors. No code generated Fragment shader(s) were not successfully compiled before glLinkProgram() was called. Link failed. - person tversteeg; 20.06.2012
comment
Вы добавили символ нулевого завершения, как предложил Бен Фойгт? У вас все еще есть эти странные символы при печати исходного кода? Вероятно, вам следует добавить флаг std::ios::binary в open() при чтении такого файла, чтобы Tellg работал так, как вы ожидаете. - person ltjax; 20.06.2012

Если не удается установить связь, извлеките журнал ошибок связи, в котором могут быть дополнительные подсказки.

См. glGetProgramInfoLog.

person Ben Voigt    schedule 20.06.2012
comment
Я использовал glGetProgramInfoLog, и это привело к ERROR: error(#280) Not all shaders have valid object code ERROR: error(#280) Not all shaders have valid object code - person tversteeg; 20.06.2012