Problem passing same textures to glsl repeatedly

Hello!
I am trying to implement a ray casting algorithm in glsl. I want automatically rotate the volume, as I don’t want to implement any mouse/keyboard interaction yet.

So in order to do this, I have 2 textures: frontfaceTex, backfaceTex attached to GL_COLOR_ATTACHMENT0_EXT and GL_COLOR_ATTACHMENT1_EXT of my framebuffer. In these 2 textures I am rendering the front face and the back face of a cube.

void drawCubesToTextures()
{

	static int i=0;
	cout<<i++<<endl;

	static float rotate = 0; 
	rotate += 1.0;

	//////////////////////////
	//frontface of the cube///
	//////////////////////////
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
	glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
	
	glViewport(0,0,256, 256);

	// Set the render target
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

	glPushMatrix();
		glRotatef(rotate,1,1,0);
			
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
		glClearColor(0.0,0.0,0.0,0.0);

		glEnable(GL_CULL_FACE);
		glCullFace(GL_FRONT);
		drawQuads(1.0,1.0, 1.0);
		glDisable(GL_CULL_FACE);
	glPopMatrix();

	glPopAttrib();
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

	///////////////////////////
	//backface of the cube/////
	///////////////////////////
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
	glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
	glViewport(0,0,256, 256);

	// Set the render target
	glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);

	glPushMatrix();
		glRotatef(rotate,1,1,0);

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
		glClearColor(0.0,0.0,0.0,0.0);

		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);
		drawQuads(1.0,1.0, 1.0);
		glDisable(GL_CULL_FACE);
	glPopMatrix();

	glPopAttrib();
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

} 

Now, can someone please tell me what am I doing wrong in the display function, as my texture will appear only for the first time the “display” function is called? (ONLY when variable i form the above function = 0 the texture is displayed)

 void displayShader()
{
	drawCubesToTextures();

	GLint location1,location2, location3D, locationTF;

	glPushAttrib(GL_ALL_ATTRIB_BITS);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	setShaders();
	
	location1=glGetUniformLocationARB(p,"frontTexture");
	glActiveTextureARB(GL_TEXTURE0_ARB);
	glBindTexture(GL_TEXTURE_2D, frontfaceTex);
	glUniform1iARB(location1, 0);

	location2=glGetUniformLocationARB(p,"backTexture");
	glActiveTextureARB(GL_TEXTURE1_ARB);
	glBindTexture(GL_TEXTURE_2D, backfaceTex);
	glUniform1iARB(location2, 1);

	glBegin( GL_QUADS );
		glTexCoord2d(0.0,0.0); glVertex2f(-1.0,-1.0);
		glTexCoord2d(1.0,0.0); glVertex2f(1.0,-1.0);
		glTexCoord2d(1.0,1.0); glVertex2f(1.0,1.0);
		glTexCoord2d(0.0,1.0); glVertex2f(-1.0,1.0);
	glEnd();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	glPopAttrib();

	releaseShaders();

	glutSwapBuffers();
	glFlush();
}

my shaders (dunno if the problem is here, as for the first rendering pass I get the result I need…)

 
varying vec4 texCoord;

void main()
{
	gl_Position = ftransform();
	texCoord = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}


uniform sampler2D frontTexture;
uniform sampler2D backTexture;

varying vec4 texCoord;

void main()
{
	gl_FragColor = texture2D(frontTexture,texCoord.xy);
}

p.s.
When using the normal opengl way to display a texture, I get the desired result no matter how many times the “display” function is called. That’s my reason why I am posting in the Shader part of this forum
ps2
I am minimizing/maximizing the display window to get the “display” function called again… (the result is in increasing the value of i variable, rotating the cube by i degrees, and the part that it does not work, displaying the textures using glsl)
Tnx a lot for taking the time to read my long story :slight_smile:

Hi,

You don’t need to call glGetUniformLocation every frame, if you have only one program (vertex + fragment shader). call it once in your setup code (locations do not change unless You relink program object). Your problem may be located in setShaders , or releaseShaders functions, do they modify modelview/projection matrices or any attributes?

ps. to trigger redisplay use glutTimerFunc.

Tnx for reply

I made the following modification, but still it does not work

 	static int firstPass=1;
	if (firstPass)
	{
		location1=glGetUniformLocationARB(p,"frontTexture");
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(GL_TEXTURE_2D, frontfaceTex);
		glUniform1iARB(location1, 0);

		location2=glGetUniformLocationARB(p,"backTexture");
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(GL_TEXTURE_2D, backfaceTex);
		glUniform1iARB(location2, 1);

                firstPass = 0;
	}


setshaders and release shaders are (no modification to any matrix is made)

 void setShaders() {

	char *vs = NULL,*fs = NULL;


	v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
	f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);


	vs = textFileRead("ray.vert");
	fs = textFileRead("ray.frag");

	const char * ff = fs;
	const char * vv = vs;

	glShaderSourceARB(v, 1, &vv,NULL);
	glShaderSourceARB(f, 1, &ff,NULL);

	free(vs);free(fs);

	glCompileShaderARB(v);
	glCompileShaderARB(f);

	p = glCreateProgramObjectARB();
	glAttachObjectARB(p,f);
	glAttachObjectARB(p,v);

	glLinkProgramARB(p);
	
	glUseProgramObjectARB(p);

}

void releaseShaders() {

	glDetachObjectARB(p,f);
	glDetachObjectARB(p,v);
	glDeleteObjectARB(p);
}

Any other thoughts? :expressionless:

Yes, You are recompiling your shaders every frame. Do it once in setup. I’m pretty new to OpenGL, but I’ve never seen functions like glAttachProgramObjectARB. From OGL version 2.0 up shaders are in core, so You can drop ARB suffix. I use following functions to setup my shaders:


GLboolean loadShader( GLuint* shader, GLenum type, const char* name )
{
	GLboolean ok = GL_TRUE;
	GLint success;
	GLint size;
	char* shaderSrc;
	char infoLog[1024];
	
	*shader = glCreateShader( type );
	
	FILE* file = fopen( name, "r" );
	
	if(!file)
	{
		printf( "
Error: %s shader source not found! (%s)
", ((type == GL_VERTEX_SHADER)? "vertex" : "fragment"), name );
		ok = GL_FALSE;
	}
	else
	{
		fseek( file, 0, SEEK_END );
		size = ftell( file );
		shaderSrc = malloc( size+1 );
		rewind( file );
		fread( shaderSrc, 1, size, file );
		shaderSrc[size] = '\0';
		fclose( file );
		
		glShaderSource( *shader, 1, (const GLchar**)&shaderSrc, &size );
		
		glCompileShader( *shader );
		glGetShaderiv( *shader, GL_COMPILE_STATUS, &success );
		glGetShaderInfoLog( *shader, 1024, NULL, infoLog );
		
		if (!success)
		{
			printf( "
Error in %s shader compilation! (%s)
", ((type == GL_VERTEX_SHADER)? "vertex" : "fragment"), name );
			printf( "Info log:
 %s
", infoLog );
			ok = GL_FALSE;
		}
		else
			printf( "
%s Shader compiled successfully (%s)
 log
%s
", ((type == GL_VERTEX_SHADER)? "Vertex" : "Fragment"), name,  infoLog );
		
		free( shaderSrc );
	}
	
	return ok;
}


GLboolean createProgram( GLuint* program, GLuint vc, GLuint* vertex, GLuint fc, GLuint* fragment )
{
	GLboolean ok = GL_TRUE;
	GLint success;
	GLuint i;
	char infoLog[1024];
	
	*program = glCreateProgram();
	
	for(i = 0;i < vc;i++)
		glAttachShader( *program, vertex[i] );
	
	for(i = 0;i < fc;i++)
		glAttachShader( *program, fragment[i] );
	
	glLinkProgram( *program );
	glGetProgramiv( *program, GL_LINK_STATUS, &success );
	glGetProgramInfoLog( *program, 1024, NULL, infoLog );
	
	if (!success)
	{
		printf( "
Error in programlinkage!
" );
		printf( "
Info log: %s
 ", infoLog );
		ok = GL_FALSE;
	}
	else
		printf( "
Program linked successfully
log
%s
", infoLog );
	
	glValidateProgram( *program );
	glGetProgramiv( *program, GL_VALIDATE_STATUS, &success );
	glGetProgramInfoLog( *program, 1024, NULL, infoLog );
	
	if (!success)
	{
		printf( "
Error in program validation!
" );
		printf( "
Info log: %s
", infoLog );
		ok = GL_FALSE;
	}
	else
		printf( "
Program validated successfully
log
%s
", infoLog );
	
	return ok;
}

and in my setup function (called before entering main loop):


GLuint vs, fs, prog;
GLboolean ok = loadShader( &vs, GL_VERTEX_SHADER,   "./shaders/vertex.glsl.vs" ) &&
	loadShader( &fs, GL_FRAGMENT_SHADER, "./shaders/fragment.glsl.fs" ) &&
	createProgram( &prog, 1, &vs, 1, &fs );

where is function that does the rotation, and how it is called?

You can see the rotation in the first function that I posted, void drawCubesToTextures(). There is there at some point glRotated(rotate, 1,1,0).

ok, so it seems that You are rendering to textures without shaders, and then display result with shader, am I right?

To switch back to fixed functionality (on the end of your displayShader func) call glUseProgram(0); (or in old-fashion ARB: glUseProgramObjectARB(0):wink: instead of deleting all shaders.

Tnx a lot, it worked!

Aff, struggled a lot with this problem

Again, tnx!