Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Allegro 5 OpenGL GLSL Shader Problem

Credits go to RPG Hacker for helping out!
This thread is locked; no one can reply to it. rss feed Print
Allegro 5 OpenGL GLSL Shader Problem
DQBO1998
Member #16,394
June 2016
avatar

I need help setting up my OpenGL shader, I just don't know what I'm doing wrong. I wrapped OpenGL shader system into a class called ShaderProgram. It's constructor is the next.

#SelectExpand
1 ShaderProgram(std::string vpath, std::string fpath){ 2 3 std::string vertex_shader_source_code; 4 5 if(get_file_lines(vpath, vertex_shader_source_code)){ 6 7 std::cout << "ShaderProgram: File " << vpath << " not found" << std::endl; 8 exit(1); 9 10 } 11 12 GLuint vertex_shaderID = glCreateShader(GL_VERTEX_SHADER); 13 const char *VERTEX_SHADER_SOURCE_CODE = vertex_shader_source_code.c_str(); 14 glShaderSource(vertex_shaderID, 1, &VERTEX_SHADER_SOURCE_CODE, NULL); 15 glCompileShader(vertex_shaderID); 16 17 //add here shader compilation detection// 18 19 std::string fragment_shader_source_code; 20 21 if(get_file_lines(fpath, fragment_shader_source_code)){ 22 23 std::cout << "ShaderProgram: File " << fpath << " not found" << std::endl; 24 exit(1); 25 26 } 27 28 GLuint fragment_shaderID = glCreateShader(GL_FRAGMENT_SHADER); 29 const char *FRAGMENT_SHADER_SOURCE_CODE = fragment_shader_source_code.c_str(); 30 glShaderSource(fragment_shaderID, 1, &FRAGMENT_SHADER_SOURCE_CODE, NULL); 31 glCompileShader(fragment_shaderID); 32 33 //add here shader compilation detection// 34 35 shaderID = glCreateProgram(); 36 glAttachShader(shaderID, vertex_shaderID); 37 glAttachShader(shaderID, fragment_shaderID); 38 glLinkProgram(shaderID); 39 40 glDeleteShader(vertex_shaderID); 41 glDeleteShader(fragment_shaderID); 42 43 }

the vpath variable refers to the vertex shader file path and the fpath variable to
fragment shader file path.

the get_file_lines is a private method that stores the file lines in a string to be
compiled by OpenGL, it attaches them in the next format.

line + '\0'

So in a loop all the lines end up being added separated by the '\0' character. As I
understand you can pass them in that way to OpenGL and it should compile correctly, but I'm not sure.

I'm using this window flags.

#SelectExpand
1 ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE | ALLEGRO_OPENGL_3_0 | ALLEGRO_OPENGL

The problem is that when I setup the shader it does nothing, no effect is applied to the screen output. Also I've tried using external shaders from the internet but the results are the same, obviously calling glUseProgram().

I use this code for drawing, implementing VAO and VBOs.

#SelectExpand
1 glBindVertexArray(vaoID); 2 glEnableVertexAttribArray(0); 3 glDrawArrays(GL_TRIANGLES, 0, size); 4 glDisableVertexAttribArray(0); 5 glBindVertexArray(0);

and this one to load the information to VAO.

#SelectExpand
1void store_in_vao(GLfloat *position, GLuint &size, GLuint &vaoID, GLuint &vboID){ 2 3 glGenVertexArrays(1, &vaoID); 4 glBindVertexArray(vaoID); 5 6 glGenBuffers(1, &vboID); 7 glBindBuffer(GL_ARRAY_BUFFER, vboID); 8 9 glBufferData(GL_ARRAY_BUFFER, size*3*sizeof(GLfloat), position, GL_STATIC_DRAW); 10 glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); 11 12 glBindVertexArray(0); 13 glBindBuffer(GL_ARRAY_BUFFER, 0); 14 15}

The Allegro version I have is 5.0.11.

RPG Hacker
Member #12,492
January 2011
avatar

A small recommendation: You shouldn't use manual line breaks when writing text on the web unless you're actually starting a new paragraph. Using manual line breaks in the middle of your sentences makes the formatting look all messed up, depending on where you are reading the text

My name is
Pattrick. <- bad

My name is Pattrick. <- good

;)

DQBO1998 said:

the get_file_lines is a private method that stores the file lines in a string to be compiled by OpenGL, it attaches them in the next format.

Does that function return a bool or an int on error? I kinda expected it to return a bool, in which case it would early-out of the constructor on success, but I assume it returns an int on error?

Quote:

line + '\0'

So in a loop all the lines end up being added separated by the '\0' character. As I understand you can pass them in that way to OpenGL and it should compile correctly, but I'm not sure.

Actually, I don't think so. When you do that, each single line of the file is null-terminated and I assume the function would only read the first line in that case. Instead, you should separate them with \n and only put a \0 at the end of the string (which probably is there already anyways). If you want to have \0 at the end of each line, you actually have to pass an array to that function containing a pointer to the start of each line and then pass the number of lines in that array to glShaderSource() where you are currently passing a 1. Just changing the \0 to \n should be easier, though. I also recommend querying the error message of OpenGL's shader compiler. There should be a function for that. That way you'll know exactly what went wrong and don't have to take a wild guess. Just print the error message, if there is any, to the Debugger.

Also where and how exactly are you binding your shader program? I didn't see that anywhere in your code snippets above.

Polybios
Member #12,293
October 2010

Allegro 5.0.11? The new Allegro 5.2 comes with shader support, maybe you could try that instead of rolling your own?

DQBO1998
Member #16,394
June 2016
avatar

I've tried making the modifications that you told me RPG Hacker ;D, and I achieved some progress. But the shader just doesn't work >:(, using the shader's information extracted through the function "glGetShaderInfoLog" I got this error in both of the shaders.

(0) : error C0000: syntax error, unexpected $end at token "<EOF>"

This is the file reading method.

#SelectExpand
1 2 bool get_shader_file_lines(std::string &path, std::string dest){ 3 4 std::ifstream file; 5 file.open(path); 6 7 if(not file.is_open()) 8 return true; 9 10 std::string buffer; 11 12 while(true){ 13 14 if(file.eof()) 15 break; 16 17 std::getline(file, buffer); 18 dest += buffer + '\n'; 19 20 } 21 22 return false; 23 24 }

It returns true if a problem occurs.

The shader class constructor, not really good code, it's just for the current testing.

#SelectExpand
1 2 Shader(std::string vert, std::string frag){ 3 4 std::string vertex_shader_source_code; 5 6 vertex_shader_file = get_shader_file_lines(vert, vertex_shader_source_code); 7 8 vertex_shaderID = glCreateShader(GL_VERTEX_SHADER); 9 const char *vcode = vertex_shader_source_code.c_str(); 10 GLint vcode_size = vertex_shader_source_code.size(); 11 glShaderSource(vertex_shaderID, 1, &vcode, &vcode_size); 12 glCompileShader(vertex_shaderID); 13 14 glGetShaderiv(vertex_shaderID, GL_COMPILE_STATUS, &vertex_shader_compile_var); 15 16 GLint length = 0; 17 glGetShaderiv(vertex_shaderID, GL_INFO_LOG_LENGTH, &length); 18 char *info = new char[length]; 19 glGetShaderInfoLog(vertex_shaderID, length, NULL, info); 20 vertex_shader_log = info; 21 delete[] info; 22 23 std::string fragment_shader_source_code; 24 25 fragment_shader_file = get_shader_file_lines(frag, fragment_shader_source_code); 26 27 fragment_shaderID = glCreateShader(GL_FRAGMENT_SHADER); 28 const char *fcode = fragment_shader_source_code.c_str(); 29 GLint fcode_size = fragment_shader_source_code.size(); 30 glShaderSource(fragment_shaderID, 1, &fcode, &fcode_size); 31 glCompileShader(fragment_shaderID); 32 33 glGetShaderiv(fragment_shaderID, GL_COMPILE_STATUS, &fragment_shader_compile_var); 34 35 length = 0; 36 glGetShaderiv(fragment_shaderID, GL_INFO_LOG_LENGTH, &length); 37 info = new char[length]; 38 glGetShaderInfoLog(fragment_shaderID, length, NULL, info); 39 fragment_shader_log = info; 40 delete[] info; 41 42 }

Then this methods for enabling and disabling the shader.

#SelectExpand
1 2 void start(){ 3 4 glUseProgram(shaderID); 5 6 } 7 8 void stop(){ 9 10 glUseProgram(0); 11 12 }

The vertex shader.

#SelectExpand
1 2in vec3 position; 3 4out vec3 colour; 5 6void main(void){ 7 8 gl_Position = vec4(position.x, position.y, position.z, 1.0); 9 10}

And the fragment shader.

#SelectExpand
1 2in vec3 colour; 3 4out vec4 out_Color; 5 6void main(void){ 7 8 out_Color = vec4(colour, 1.0); 9 10}

Those shaders are basically useless but are just for testing, the only thing I want to know is why is OpenGL generating that error seen before, maybe is the way I extract the string using c_str() in lines 9 and 28. Also I've separated the lines using '\n' instead of '\0'.

RPG Hacker
Member #12,492
January 2011
avatar

bool get_shader_file_lines(std::string &path, std::string dest){

Is that your actual code? If so, you're not passing dest by reference, you're passing it by value (thus making a copy of it, all modifications inside the function are lost once it returns). Change that std::string dest into a std::string& dest.

That error message (unexpected token) specifically means that the string contains something the compiler didn't expect. This should be relatively easy to determine. Just put a breakpoint at this line

glShaderSource(vertex_shaderID, 1, &vcode, &vcode_size);

and look at the contents of of vcode. You will probably find that it only points to an empty string (\0) since the function didn't modify its contents.

DQBO1998
Member #16,394
June 2016
avatar

Well, this entire question was useless because that was causing the problem, sorry for wasting your time with such stupid mistake. I'm going to mark RPG Hacker as the one that answered the question because he showed me were the error was. the next time I should pay more attention :).

RPG Hacker
Member #12,492
January 2011
avatar

Don't worry, oversights like that happen to the best of us. ;)
Glad to hear the problem is solved.

Go to: