PDA

View Full Version : Multitexture setup for GLSL



Joel de Vahl
04-17-2005, 04:19 AM
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_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,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_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,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_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,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;
}

Groovounet
04-17-2005, 04:52 AM
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)

Joel de Vahl
04-17-2005, 10:14 AM
Thanks for the help!