Ошибка 1282, если я присоединяю фрагмент программы к программе

Я пытаюсь запустить программу, используя шейдеры. В Еще один вопрос, который я сделал, Я обнаружил, что смешиваю функции фиксированного конвейера с более новыми вещами (из OpenGL 2.0), поэтому я попытался удалить все «старые вещи», такие как glMatrixMode, но я не уверен, правильно ли я это делаю. В сомнениях я также удалил вызовы типа glLightfv, которые я не совсем уверен, разрешены ли они, если я использовал программируемый конвейер.

Это основной код:

#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <vector>
#include "utility.hpp"#include "program.hpp"
GLfloat width=600, height=800;
Program* program_ref;

void init()
{
glewInit();
Shader vertex_shader= Shader("vertex_shader",GL_VERTEX_SHADER);
// This just reads the file "vertex_shader", creates the shader and compiles it
Shader geometry_shader= Shader(); // This means that the shader is empty
// So the program class will be enough smart to recognize it and don't attach it
Shader fragment_shader= Shader("fragment_shader",GL_FRAGMENT_SHADER);
program_ref= new Program(vertex_shader,geometry_shader,fragment_shader);
// This creates a program, attaches the shaders to it, links and uses it
}

void display()
{
vector<GLfloat> quad{-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5};
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2,GL_FLOAT,0,quad.data());
glDrawArrays(GL_QUADS,0,4);
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
cout << glGetError() << endl;
}

void reshape(int w, int h)
{
width=w;
height=h;
glutPostRedisplay();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
init();
glewInit();
glutMainLoop();
return 0;
}

(Дополнительные классы, чтобы увидеть, в комментариях я написал как ведут себя Program и Shader)

shader.hpp:

#ifndef shader_hpp
#define shader_hpp

#include "utility.hpp"#include "shader.hpp"#include <fstream>

#define MAX_SIZE (size_t)1.0e5class Shader
{
private:
GLuint id;
GLenum type;
bool null;
public:
Shader()
{
id=-1;
type= -1;
null= true;
}
Shader(const string& filename,GLenum type)
{
GLchar* data= new GLchar[MAX_SIZE];
streamsize count;
this->type= type;
ifstream is;
is.open(filename);
is.read(data,MAX_SIZE);
count= is.gcount();
is.close();
id=glCreateShader(type);
glShaderSource(id,1,(const GLchar**)&data,&count);
glCompileShader(id);
delete[] data;
null= false;
}
GLuint getId() const
{
return id;
}
GLenum getType() const
{
return type;
}
bool isNull() const
{
return null;
}
};

#endif

program.hpp:

#ifndef program_hpp
#define program_hpp

#include "utility.hpp"#include "shader.hpp"
class Program
{
private:
GLuint id;
public:
Program(const Shader& vertex_shader, const Shader& geometry_shader, const Shader& fragment_shader)
{
id= glCreateProgram();
if(!vertex_shader.isNull())
{
glAttachShader(id,vertex_shader.getId());
}
if(!geometry_shader.isNull())
{
glAttachShader(id,geometry_shader.getId());
}
if(!fragment_shader.isNull())
{
glAttachShader(id,fragment_shader.getId());
}
glLinkProgram(id);
glUseProgram(id);
}
GLuint getId()
{
return id;
}
};

#endif

Там просто созданы два класса, чтобы все упростить при использовании glew для компиляции шейдеров и их присоединения к программе.

Проблема заключается в следующем: если я просто присоединяю вершинный шейдер, а не фрагментный шейдер, все в порядке, и я вижу квад, нарисованный с правильным цветом (красным, потому что в вершинном шейдере ниже я установлю цвет на красный) , Если вместо этого я также прикрепляю фрагментный шейдер, я вижу, что квадроцикл белый. Я также попытался увидеть, что не так, и я напечатал результат glGetError (). Если я включаю фрагментный шейдер, я получаю ошибку 1282, если я не включаю его, я не получаю никакой ошибки (0).

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

void main()
{
gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor  = vec4(1,0,0,1);
// The only relevant thing I do is to set the color to red
// I see the quad red if I attach only the vertex shader and not the fragment shader
gl_TexCoord[0] = gl_MultiTexCoord0;
}

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

void main()
{
gl_fragColor= gl_Color;
}

3

Решение

Дайте этому шанс:

#include <GL/glew.h>
#include <GL/glut.h>
#include <vector>
#include <iostream>

using namespace std;

void CheckStatus( GLuint obj )
{
GLint status = GL_FALSE, len = 10;
if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
if( glIsShader(obj) )   glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
vector< char > log( len, 'X' );
if( glIsShader(obj) )   glGetShaderInfoLog( obj, len, NULL, &log[0] );
if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
cerr << &log[0] << endl;
exit( -1 );
}

GLuint LoadShader( GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader );
return shader;
}

GLuint LoadProgram( const char* vert, const char* geom, const char* frag )
{
GLuint program = glCreateProgram();
if( vert ) glAttachShader( program, LoadShader( GL_VERTEX_SHADER, vert ) );
if( geom ) glAttachShader( program, LoadShader( GL_GEOMETRY_SHADER, geom ) );
if( frag ) glAttachShader( program, LoadShader( GL_FRAGMENT_SHADER, frag ) );
glLinkProgram( program );
CheckStatus( program );
return program;
}

#define GLSL(version, shader)  "#version " #version "\n" #shader

const GLchar* vert = GLSL
(
120,
void main()
{
gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor  = vec4(1.0,0.0,0.0,1.0);
// The only relevant thing I do is to set the color to red
// I see the quad red if I attach only the vertex shader and not the fragment shader
gl_TexCoord[0] = gl_MultiTexCoord0;
}
);

const GLchar* frag = GLSL
(
120,
void main()
{
gl_FragColor= gl_Color;
}
);

void display()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);

static GLuint prog = LoadProgram( vert, NULL, frag );
glUseProgram( prog );
glEnableClientState(GL_VERTEX_ARRAY);
GLfloat quad[] = {-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5};
glVertexPointer(2,GL_FLOAT,0,quad);
glDrawArrays(GL_QUADS,0,4);
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("test");
glutDisplayFunc(display);
glewInit();
glutMainLoop();
return 0;
}

Как указал Антони Блом gl_fragColor должно быть gl_FragColor, Строчные буквы f душит компилятор GLSL в моей системе.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]