Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

GLSL noob problem... Goto page 1, 2 Next

| Inside3d Forums Forum Index -> OpenGL Programming

View previous topic :: View next topic
Author | Message
--- | ---
Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Mon May 17, 2010 5:01 pm Post subject: GLSL noob problem... |

Hi all! Well, my journey into OpenGL is progressing. I've made a few projects using the FFP functionality from standard OpenGL 1.1 specification implementation. Now i'm moving onto using OpenGL 2.0 and GLSL. I'm using GLEW and GLUT to test a basic shader manager class. However, I'm getting an access violation error whenever I try to run the program. I think the problem lies with the shader and program objects. Anyways, here is the code:
SHMAN.h

Code:
//GLSL shader manager interface #ifndef _SHMAN_H_ #define _SHMAN_H_ //system includes #include <gl\glew.h>
#include <gl\gl.h>
#include <iostream>
#define MAX_INFO_LOG_SIZE 2048
//Shader manager class
class SHMAN
{
public:
//default constructor, get the shaders
SHMAN(const GLchar * vertShader, const GLchar * fragShader)
{
vertShaderSrc = vertShader;
fragShaderSrc = fragShader;
}
//SHMAN destructor
~SHMAN()
{
CleanUp();
}
//Shader manager core functions
void CreateSHMANObject();
void LoadShaders();
void CompileShaders();
void AttachToProgObj();
void LinkProgObj();
void ValidateProgObj();
void UseProjObj();
void CleanUp(); //detach shaders from program objects and delete the shader objects
private:
GLint success;
GLint currentGPUProg;
const GLchar * vertShaderSrc;
const GLchar * fragShaderSrc;
GLchar * log;
GLuint shmanProg;
GLuint shmanVertsh;
GLuint shmanFragsh;
};
#endif

and the interface implemntation:

Code:
#include "shman.h" using namespace std; void SHMAN::CreateSHMANObject() { shmanVertsh = glCreateShader(GL_VERTEX_SHADER); //create new vertex shader object
shmanFragsh = glCreateShader(GL_FRAGMENT_SHADER); //create new fragment shader object
}
void SHMAN::LoadShaders()
{
//load vertex shader
const GLchar *strPtr[1];
strPtr[0] = vertShaderSrc;
glShaderSource(shmanVertsh, 1, strPtr, NULL);
//load fragment shader
strPtr[0] = vertShaderSrc;
glShaderSource(shmanFragsh, 1, strPtr, NULL);
}
void SHMAN::CompileShaders()
{
//compile the vertex shader and and get compilation status
glCompileShader(shmanVertsh);
glGetShaderiv(shmanVertsh, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shmanVertsh, MAX_INFO_LOG_SIZE, NULL, log);
cout << "\nVertex shader compilation error!" << endl;
cout << "\nPlease see compilation log details below: " << endl;
cout << "\n" << log << endl;
}
//compile the fragment shader and get compilation status
glCompileShader(shmanFragsh);
glGetShaderiv(shmanFragsh, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shmanFragsh, MAX_INFO_LOG_SIZE, NULL, log);
cout << "\nFragment shader compilation error!" << endl;
cout << "\nPlease see compilation log details below: " << endl;
cout << "\n" << log << endl;
}
}
void SHMAN::AttachToProgObj()
{
shmanProg = glCreateProgram();
glAttachShader(shmanProg, shmanVertsh);
glAttachShader(shmanProg, shmanFragsh);
}
void SHMAN::LinkProgObj()
{
//link the program object
glLinkProgram(shmanProg);
glGetProgramiv(shmanProg, GL_LINK_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shmanProg, MAX_INFO_LOG_SIZE, NULL, log);
cout << "\nGPU program object link error!" << endl;
cout << "\nPlease see compilation log details below: " << endl;
cout << "\n" << log << endl;
}
}
void SHMAN::ValidateProgObj()
{
//validate the program before running on GPU
glValidateProgram(shmanProg);
glGetProgramiv(shmanProg, GL_VALIDATE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shmanProg, MAX_INFO_LOG_SIZE, NULL, log);
cout << "\nGPU program validation error!" << endl;
cout << "\nPlease see compilation log details below: " << endl;
cout << "\n" << log << endl;
}
}
void SHMAN::UseProjObj()
{
glUseProgram(shmanProg);
//disable if un-needed
//currentGPUProg = glGetIntegerv(GL_CURRENT_PROGRAM, currentGPUProg);
//cout << "\nCurrent GPU program object handle: " << currentGPUProg << " \n" << endl;
}
void SHMAN::CleanUp()
{
glDetachShader(shmanProg, shmanVertsh);
glDetachShader(shmanProg, shmanFragsh);
glDeleteProgram(shmanProg);
}

It would be really awsome if any one of you could perhaps look at my code and explain to me what I'm doing wrong. Thank you in advance!
_________________
....noodle...

Back to top |

mh Joined: 12 Jan 2008 Posts: 909 |

Posted: Mon May 17, 2010 5:33 pm Post subject: |

You need to allocate memory and then memcpy in your constructor otherwise you risk what is being pointed to going out of scope before it's used. _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010 MHQuake Blog (General) Direct3D 8 Quake Engines

Back to top |

Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Mon May 17, 2010 7:02 pm Post subject: |

Yeah, i tried that, but I still get the same problem. Here is what I added to the constructor:

Code:
//default constructor, get the shaders SHMAN(const GLchar * vertShader, const GLchar * fragShader) { vertShaderSrc = (GLchar*) malloc(sizeof(vertShader)); memcpy(&vertShaderSrc, &vertShader, *vertShaderSrc);
fragShaderSrc = (GLchar*) malloc(sizeof(fragShader));
memcpy(&fragShaderSrc, &fragShader, *fragShaderSrc);
}

_________________
....noodle...

Back to top |

r00k Joined: 13 Nov 2004 Posts: 483 |

Posted: Mon May 17, 2010 9:44 pm Post subject: |

shouldnt memcpy be (dest, src, size) ? memcpy(&fragShaderSrc, &fragShader, sizeof(fragShaderSrc)); of course now im confused which is your source, or destination...

Back to top |

Spike Joined: 05 Nov 2004 Posts: 944 Location: UK |

Posted: Mon May 17, 2010 10:00 pm Post subject: |

vertShaderSrc = (GLchar*) malloc(strlen(vertShader)+1); memcpy(vertShaderSrc, vertShader, strlen(vertShader)+1); is what you want. your code allocates 4 bytes then copies between 0 and 255 bytes onto the stack corrupting it. your vertShader and vertShaderSrc variables are pointers, you don't wanna take the address of the pointer here... that's absurd.
or you could just use:
vertShaderSrc = strdup(vertShader);
but that would make things too easy.
Alternatively, as vertShader is a pointer to a string, if that's always going to be a string immediate that is passed in, then you don't even need the strdup, but yeah, assumptions are assumptions.
_________________
What's a signature?

Back to top |

mh Joined: 12 Jan 2008 Posts: 909 |

Posted: Mon May 17, 2010 11:11 pm Post subject: |

Or alternatively front-load everything into your constructor; compile, link, etc in there. It may not give you all of the flexibility you might want, but consider if you need that flexibility. If you're writing a more general purpose shader management tool maybe you do, but otherwise I would argue that maybe you don't.
_________________
DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines

Back to top |

Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Tue May 18, 2010 5:31 pm Post subject: |

NO luck. I resorted to using my graphic programming lecturer's code, but i still get the same error. Here is all of his code (and it does work, because we have to use it for coursework next semester): GLSLshader.h

Code:
#ifndef _GLSLSHADER_H #define _GLSLSHADER_H #include <GL/glew.h> #include <string> class GLSLshader
{
public:
//constructor creates
GLSLshader(const std::string &filename, GLenum shaderType );
char *ReadShaderFromFile(const std::string &filename);
bool CompileShader();
//the handle used to identify the gl shader object
GLuint ShaderID;
private:
bool Compiled;
};
#endif

GLSLshader.cpp

Code:
#include "GLSLshader.h" #include <string> #include <fstream> #include <iostream> using namespace std;
GLSLshader::GLSLshader(const std::string &filename, GLenum shaderType )
{
Compiled = false;
//initialise our shader to the correct shader type we require.
ShaderID = glCreateShader(shaderType);
const char *source = ReadShaderFromFile(filename);
//read just a single shader from the string we created from the file.
glShaderSource(ShaderID, 1, static_cast<const GLchar**>(&source), NULL);
//compile
Compiled = CompileShader();
//insert error checking
delete [] source;
}
char *GLSLshader::ReadShaderFromFile(const std::string &filename)
{
//file reader taken from opengl Blue book.
ifstream temp(filename.c_str());
int count = 0;
char *buf;
temp.seekg(0, ios::end);
count = temp.tellg();
buf = new char[count + 1];
memset(buf,0,count);
temp.seekg(0, ios::beg);
temp.read(buf, count);
buf[count] = 0;
temp.close();
return buf;
}
bool GLSLshader::CompileShader()
{
glCompileShader(ShaderID);
int ShaderCompileSuccess;
glGetObjectParameterivARB(ShaderID, GL_OBJECT_COMPILE_STATUS_ARB, &ShaderCompileSuccess);
if(!ShaderCompileSuccess)
{
return false;
}
return true;
}

GLSLProgram.h

Code:
#ifndef _GLSLPROGRAM_H #define _GLSLPROGRAM_H #include <GL/glew.h> #include <string> class GLSLprogram
{
public:
GLSLprogram();
void SetupProgram(const std::string &vertexshaderfilename,const std::string &fragmentshaderfilename);
GLuint ProgramID;
private:
};
#endif

GLSLProgram.cpp

Code:
#include "GLSLprogram.h" #include "GLSLshader.h" #include <GL/glew.h> #include <string> #include <fstream>
#include <iostream>
GLSLprogram::GLSLprogram()
{
}
void GLSLprogram::SetupProgram(const std::string &vertexshaderfilename, const std::string &fragmentshaderfilename)
{
int success;
GLuint test = glCreateProgram();
ProgramID = glCreateProgram();
static GLSLshader VertShade(vertexshaderfilename, GL_VERTEX_SHADER);
static GLSLshader FragShade (fragmentshaderfilename, GL_FRAGMENT_SHADER);
glAttachShader(ProgramID, VertShade.ShaderID);
glAttachShader(ProgramID, FragShade.ShaderID);
glLinkProgram(ProgramID);
glGetProgramiv(ProgramID, GL_LINK_STATUS, &success);
if(!success)
{
//error check
}
glValidateProgram(ProgramID);
}

Basically, I'm still getting the runtime access violation errors associated with GLuint's representing the shader and gpu program objects. The error happens whenever the shader or program object identifier is assigned to glCreateShader() and glCreateProgram().
And yes, I'm calling glewInit() in main().
_________________
....noodle...

Back to top |

Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Tue May 18, 2010 5:32 pm Post subject: |

One big factor that might be the root of the problem is that I'm using Visual Studio 2008... _________________ ....noodle...

Back to top |

Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Tue May 18, 2010 5:44 pm Post subject: |

Yup, MSVC2008 might well be the culprit. I made a very simple test application just to see if my assignment of glCreateShader() to a GLenum variable would cause the same access violation run time error, and it did.

Code:
//system includes #include <gl\glew.h> #include <gl\gl.h> #include <gl\glut.h> #include <windows.h>
#include <iostream>
GLenum tmp;
void test()
{
tmp = glCreateShader(GL_VERTEX_SHADER);
}
int main(int argc, char* argv[])
{
glewInit();
glutInit(&argc, argv);
test();
system("PAUSE");
return 0;
}

Anyone got any suggestions?
_________________
....noodle...

Back to top |

mh Joined: 12 Jan 2008 Posts: 909 |

Posted: Tue May 18, 2010 7:50 pm Post subject: |

Switch your character set from Unicode to Multibyte in Project Properties, and that's a pint of beer you owe me. _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010 MHQuake Blog (General) Direct3D 8 Quake Engines

Back to top |

Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Tue May 18, 2010 8:02 pm Post subject: |

Update: That's the first thing I do whenever I start a new project...my project has been using the muli-byte character set all this time, lol. Anyways, I even installed VS2005 a few minutes ago, and I STILL GET THE SAME PROBLEM!!!!!!!!! ARGHHHHHHH!!!!!
However, on a more positive note, I did get a very complex GLSL shader mangment example to work, but it's pretty intense...
see here: http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/loading.php
I'm just so annoyed that I have to spend so much time setting up crap like this, when I should be focusing on actually learning GLSL and writting shaders.
_________________
....noodle...

Back to top |

mh Joined: 12 Jan 2008 Posts: 909 |

Posted: Tue May 18, 2010 8:25 pm Post subject: |

OK then, run it in the debugger. Set a breakpoint here:

Code:
test();

And here:

Code:
system("PAUSE");

And here:

Code:
return 0;

What happens? And which line does it happen on?
Step 2. Change this:

Code:
void test() { tmp = glCreateShader(GL_VERTEX_SHADER); }

to this:

Code:
void test() { tmp = glCreateShader(GL_VERTEX_SHADER); tmp = tmp; }

Set a breakpoint on each line here. When it breaks on the first examine the address of glCreateShader. It is NULL or non-NULL? Run to the next breakpoint. Does it explode? If not, examine the value of tmp. You should have a handle or whatever in there if it worked.
Step 3. Try replacing the glCreateShader call with something simpler; backtracking like this can be useful to isolate problems. A call to glFinish should be enough. Does it explode?
_________________
DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines

Back to top |

Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Fri May 21, 2010 9:39 pm Post subject: |

Thanx for the ongoing help. I'm away from my PC till monday, but when I get back, I'll update you on my progress asap! Many Thanx! _________________ ....noodle...

Back to top |

Zylyx_ Joined: 05 Dec 2007 Posts: 111 Location: scotland, uk |

Posted: Mon May 24, 2010 12:25 pm Post subject: |

Solved: I cant believe how much crap I had to go through to get this working. I'm using the provided game framework (not mine, but my lecturers), which we will have to use to make a game for the next two semesters when I get back to university (coz I'm on summer holiday now).
Here is the shader code:

Code:
//Basic vertex shader void main(void) { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }

Code:
//basic fragment shader void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }

There is still a problem, and that is that I can only run the debug/release versions of the program in visual studio, but not on their own. This will require another week of investigation, lol.
I mean, common, the Khronos group should publish the "Purple Book" aka "The guide to setting up OpenGL in the 21st Century: A Modern Approach". We can all help write it!
_________________
....noodle...

Back to top |

Sajt Joined: 16 Oct 2004 Posts: 1026 |

Posted: Mon May 24, 2010 6:26 pm Post subject: |

Make sure that if you're going to mix shader rendering with fixed-function rendering (i.e. render some objects using both methods in the same scene) you need to replace

Code:
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

with

Code:
gl_Position = ftransform();

or you will get some ugly depth buffer inconsistencies. But you probably already knew that.
_________________
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.

Back to top |

Display posts from previous:

| Inside3d Forums Forum Index -> OpenGL Programming | All times are GMT Goto page 1, 2 Next
Page 1 of 2

Jump to:

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2004 phpBB Group