Multitexture setup for GLSL

Hi,

I’m not sure if this is the right forum, please move this post if it’s the wrong one… =)

I have a problem with multitexture and GLSL, all txture lookups are occuring from texture0, even if I try to read from textureN.

Is this a known problem?

Setup code below:

 

int main(int argc, char *argv[]){
	int width = 1024, height = 768;
	bool done = false;
	SDL_Surface *screen;
	SDL_Event event;

	SDL_Init(SDL_INIT_VIDEO);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL);

    // Init OpenGL
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(80.0f, (GLfloat)width / (GLfloat)height, 0.1f, 1000.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.5f, 0.9f, 1.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	
	glCullFace(GL_BACK);
	glEnable(GL_CULL_FACE);

	// Load some textures
	GLuint texture[3];
	glGenTextures(3, &texture[0]);
	Texture tmp;

	tmp = loadBMP("mur.bmp");
	glBindTexture(GL_TEXTURE_2D, texture[0]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, tmp.width, tmp.height, GL_RGB, GL_UNSIGNED_BYTE, tmp.data);
	delete[] tmp.data;

	tmp = loadBMP("mur_normal.bmp");
	glBindTexture(GL_TEXTURE_2D, texture[1]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, tmp.width, tmp.height, GL_RGB, GL_UNSIGNED_BYTE, tmp.data);
	delete[] tmp.data;

	tmp = loadBMP("mur_bump.bmp");
	glBindTexture(GL_TEXTURE_2D, texture[2]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, tmp.width, tmp.height, GL_RGB, GL_UNSIGNED_BYTE, tmp.data);
	delete[] tmp.data;

	// A light
	GLfloat light_position[]={ 10.0f, 10.0f, 3.0f, 1.0f };
	GLfloat light_color[]={ 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat ambient_color[]={ 0.2f, 0.2f, 0.2f, 1.0f };
	GLfloat mat_specular[]={ 0.3f, 0.3f, 0.3f, 1.0f };
	glShadeModel(GL_SMOOTH);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular );
	glLightfv(GL_LIGHT0, GL_POSITION, light_position );
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color );
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_color );
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color );

	//Load GLSL progs
	char *vs, *fs;
	GLuint f, v, p;
	v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
	f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
	vs = textFileRead("test.vert");
	fs = textFileRead("test.frag");
	const char * ff = fs;
	const char * vv = vs;
	glShaderSourceARB(v, 1, &vv,NULL);
	glShaderSourceARB(f, 1, &ff,NULL);
	glCompileShaderARB(v);
	glCompileShaderARB(f);
	p = glCreateProgramObjectARB();
	glAttachObjectARB(p,v);
	glAttachObjectARB(p,f);
	delete[] fs;
	delete[] vs;
	glLinkProgramARB(p);
	printInfoLog(p);
	glUseProgramObjectARB(p);

	// Doit!
	float rot = 0;
	while(!done){
		rot += 1;

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
		glUseProgramObjectARB(p);

		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
		glLoadIdentity();

		glActiveTextureARB(GL_TEXTURE2_ARB);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[2]);

		glActiveTextureARB(GL_TEXTURE1_ARB);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[1]);

		glActiveTextureARB(GL_TEXTURE0_ARB);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[0]);

		glTranslatef(0,0,-2);
		glRotatef(rot, 1.0f, 1.0f, 0.0f);
		glBegin(GL_QUADS);
			glNormal3f(0.0f, 0.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1.0f, 1.0f);
			glVertex3f(1.0f, 1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.0f, 1.0f);
			glVertex3f(-1.0f, 1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.0f, 0.0f);
			glVertex3f(-1.0f, -1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1.0f, 0.0f);
			glVertex3f(1.0f, -1.0f, 0.0f);
		glEnd();
		glBegin(GL_QUADS);
			glNormal3f(0.0f, 0.0f, -1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1.0f, 0.0f);
			glVertex3f(1.0f, -1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.0f, 0.0f);
			glVertex3f(-1.0f, -1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.0f, 1.0f);
			glVertex3f(-1.0f, 1.0f, 0.0f);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
			glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1.0f, 1.0f);
			glVertex3f(1.0f, 1.0f, 0.0f);
		glEnd();

	    while(SDL_PollEvent(&event)){
		    switch(event.type){
				case SDL_KEYDOWN:
					done = true;
				  break;
				case SDL_QUIT:
			    done = true;
			    break;
				default:
			    break;
			}
		}

		SDL_GL_SwapBuffers();
	}

	SDL_Quit();
	return 0;
}

 

You never send the sampler to GLSL programs …
You have to use the function glUniform1iARB() and only this one, to say to the GLSL program, witch texture from witch texture unit it must used.

PS : gluBuild2DMipmaps is older, it’s better to use the extension GL_SGIS_mipmap_generate. (If your hardware it’s used, high probably)

Thanks for the help!