FAQ  •  Register  •  Login

GLSL noob problem...

Moderator: Inside3D Admins

<<

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Mon May 17, 2010 5:01 pm

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...
<<

mh

User avatar

Posts: 2172

Joined: Sat Jan 12, 2008 1:38 am

Post Mon May 17, 2010 5:33 pm

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.
Like the fifth day of playing 24-hour Scrabble when you don't want to use any letters because each one means a world to you because you're so deranged.
<<

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Mon May 17, 2010 7:02 pm

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...
<<

r00k

Posts: 922

Joined: Sat Nov 13, 2004 10:39 pm

Post Mon May 17, 2010 9:44 pm

shouldnt memcpy be (dest, src, size) ?

memcpy(&fragShaderSrc, &fragShader, sizeof(fragShaderSrc));
of course now im confused which is your source, or destination... :P
<<

Spike

Posts: 2084

Joined: Fri Nov 05, 2004 3:12 am

Location: UK

Post Mon May 17, 2010 10:00 pm

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.
<<

mh

User avatar

Posts: 2172

Joined: Sat Jan 12, 2008 1:38 am

Post Mon May 17, 2010 11:11 pm

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.
Like the fifth day of playing 24-hour Scrabble when you don't want to use any letters because each one means a world to you because you're so deranged.
<<

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Tue May 18, 2010 5:31 pm

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...
<<

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Tue May 18, 2010 5:32 pm

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

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Tue May 18, 2010 5:44 pm

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...
<<

mh

User avatar

Posts: 2172

Joined: Sat Jan 12, 2008 1:38 am

Post Tue May 18, 2010 7:50 pm

Switch your character set from Unicode to Multibyte in Project Properties, and that's a pint of beer you owe me. :D
Like the fifth day of playing 24-hour Scrabble when you don't want to use any letters because each one means a world to you because you're so deranged.
<<

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Tue May 18, 2010 8:02 pm

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...
<<

mh

User avatar

Posts: 2172

Joined: Sat Jan 12, 2008 1:38 am

Post Tue May 18, 2010 8:25 pm

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?
Like the fifth day of playing 24-hour Scrabble when you don't want to use any letters because each one means a world to you because you're so deranged.
<<

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Fri May 21, 2010 9:39 pm

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...
<<

Zylyx_

Posts: 111

Joined: Wed Dec 05, 2007 6:52 pm

Location: scotland, uk

Post Mon May 24, 2010 12:25 pm

Solved:

Image

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...
<<

Sajt

Posts: 1215

Joined: Sat Oct 16, 2004 3:39 am

Post Mon May 24, 2010 6:26 pm

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.
Next

Return to OpenGL Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Icons provided by Aha Soft