PDA

View Full Version : [VBO] Multi-texturing for skybox not working



Rares
09-28-2009, 10:18 AM
I want make a skybox in GLSL, but I have a problem. Before this I render a cube and one texture for all cube and it's working. I make a 6 bmp files for skybox and do it in code:

First, I make a handle for skybox buffer, 72 element array and 6 handles for textures:



GLuint skyID;
GLuint sky1;
GLuint sky2;
GLuint sky3;
GLuint sky4;
GLuint sky5;
GLuint sky6;
GLfloat * SkyBox = new GLfloat[72];


Then, in main function I initialized this array for skybox coordinates. Later, I create 2 functions for loading shaders (one shader to normal texturing and one for skybox):



SetShaders("myShader.vert.txt","myShader.frag.txt");
CreateProgram();
SetShadersSky("skybox.vert.txt","skybox.frag.txt");
CreateProgramSky();


Next, I create buffer for skybox coord and load textures:



loadBitmapFromFile("skybox1.bmp",&bitmap);
glGenTextures(1,&sky1);
glBindTexture(GL_TEXTURE_2D,sky1);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, bitmap.width, bitmap.height, GL_RGB, GL_UNSIGNED_BYTE, bitmap.data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);


I do this 6 times, for 6 textures.

Now is the time for a render function:



void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0,0.0,0.0,1.0);
glEnable(GL_DEPTH_TEST);

glUseProgram(SkyBoxP);
glBindBuffer(GL_ARRAY_BUFFER,skyID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*72,SkyB ox,GL_DYNAMIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,0);
glEnableVertexAttribArray(glGetAttribLocation(Prog ram,"sky_in"));
glBindBuffer(GL_ARRAY_BUFFER,texID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*48,Tex, GL_DYNAMIC_DRAW);
glVertexAttribPointer(glGetAttribLocation(SkyBoxP,"sky_in"),2,GL_FLOAT,GL_FALSE,0,0);
glDrawArrays(GL_QUADS,0,72);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,sky1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
textureLocation = glGetUniformLocation(Program,"sky1");
glUniform1i(textureLocation,0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,sky2);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
textureLocation = glGetUniformLocation(Program,"sky2");
glUniform1i(textureLocation,1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D,sky3);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
textureLocation = glGetUniformLocation(Program,"sky3");
glUniform1i(textureLocation,2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D,sky4);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
textureLocation = glGetUniformLocation(Program,"sky4");
glUniform1i(textureLocation,3);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D,sky5);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
textureLocation = glGetUniformLocation(Program,"sky5");
glUniform1i(textureLocation,4);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D,sky6);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
textureLocation = glGetUniformLocation(Program,"sky6");
glUniform1i(textureLocation,5);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D,0);

glUseProgram(Program);
glBindBuffer(GL_ARRAY_BUFFER,boxID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*72,Box, GL_DYNAMIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,0);
glEnableVertexAttribArray(glGetAttribLocation(Prog ram,"tex_in"));
glBindBuffer(GL_ARRAY_BUFFER,texID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*48,Tex, GL_DYNAMIC_DRAW);
glVertexAttribPointer(glGetAttribLocation(Program,"tex_in"),2,GL_FLOAT,GL_FALSE,0,0);
glDrawArrays(GL_QUADS,0,72);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
textureLocation = glGetUniformLocation(Program,"texture");
glUniform1i(textureLocation,0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D,0);
}


And shaders:



Vertex:

attribute vec2 sky_in;
varying vec2 sky;

void main()
{
glTexCoord[0] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[0];
glTexCoord[1] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[1];
glTexCoord[2] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[2];
glTexCoord[3] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[3];
glTexCoord[4] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[4];
glTexCoord[5] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[5];
gl_Position = ftransform();
}

Fragment:

uniform sampler2D sky1;
uniform sampler2D sky2;
uniform sampler2D sky3;
uniform sampler2D sky4;
uniform sampler2D sky5;
uniform sampler2D sky6;
varying vec2 sky;

void main()
{
vec4 texel0, texel1, texel2, texel3, texel4, texel5, color;
texel0 = texture2D(sky1,sky);
texel1 = texture2D(sky2,sky);
texel2 = texture2D(sky3,sky);
texel3 = texture2D(sky4,sky);
texel4 = texture2D(sky5,sky);
texel5 = texture2D(sky6,sky);
color = mix(texel0,texel1,texel2,texel3,texel4,texel5);
gl_FragColor = color;
}


Only, what I see is textured cube (but textured in one texture) in white box (this is skybox, but not textured). My problem is that, skybox isn't textured and cube isn't textured in few textures, but in one.

I hope that, you can forgive me about my poor English.

Rares
09-29-2009, 11:27 AM
Anyone can help me?

V-man
09-30-2009, 06:47 AM
What in the world is this?



glTexCoord[0] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[0];
glTexCoord[1] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[1];
glTexCoord[2] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[2];
glTexCoord[3] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[3];
glTexCoord[4] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[4];
glTexCoord[5] = vec4(sky_in,0.0,0.0);
sky = gl_TexCoord[5];


why don't you just do
sky = sky_in;

Also, call glGetError to see if there are any error codes.
I also recommend GLIntercept
http://www.opengl.org/wiki/Debugging_Tools

k_szczech
09-30-2009, 07:00 AM
First of all - why do you need multitexturing to draw a textured cube?
Draw 6 quads, each one with single 2D texture.
Or draw a cube with a single cube texture.

You're complicating such a simple thing :) Take a step back and rethink this.

Rares
09-30-2009, 10:25 AM
So, can't I draw a cube in once and texture him?

Ilian Dinev
09-30-2009, 10:43 AM
You could make a texture-atlas, i.e 6x1 or 3x2 and draw the 12 triangles at once.
Fetching 6 texels per fragment is a huge overhead, in comparison.

Rares
09-30-2009, 11:22 AM
Ok, I have new problem. I draw a skybox, but binded is a one texture for all (skybox and object). I write this code for rendering:



for(int i = 0; i < 6; i++)
{
glUseProgram(SkyProg);
glBindBuffer(GL_ARRAY_BUFFER,skyID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*12,0,GL _DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER,0,12,&amp;SkyBox[i*12]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,0);

glEnableVertexAttribArray(glGetAttribLocation(SkyP rog,"sky_in"));
glBindBuffer(GL_ARRAY_BUFFER,texID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*8,0,GL_ DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER,0,8,&amp;Tex[i*8]);
glBindTexture(GL_TEXTURE_2D,skytex[i]);
textureLocation = glGetUniformLocation(SkyProg,"skytex");
glUniform1i(textureLocation,0);
glVertexAttribPointer(glGetAttribLocation(SkyProg,"sky_in"),2,GL_FLOAT,GL_FALSE,0,&amp;Tex[i*8]);
glDrawArrays(GL_QUADS,i*12,12);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glUseProgram(0);
}


I generated a full array, but in rendering I use only part of array. Now, I don't see anything.

I have this:

http://screenup.pl/?l=VBAZ3YE

If I use this code:



for(int i = 0; i < 6; i++)
{
glUseProgram(SkyProg);
glBindBuffer(GL_ARRAY_BUFFER,skyID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*12,0,GL _DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER,0,12,&amp;SkyBox[i*12]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,0);

glEnableVertexAttribArray(glGetAttribLocation(SkyP rog,"sky_in"));
glBindBuffer(GL_ARRAY_BUFFER,texID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*8,0,GL_ DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER,0,8,&amp;Tex[i*8]);
glBindTexture(GL_TEXTURE_2D,skytex[i]);
textureLocation = glGetUniformLocation(SkyProg,"skytex");
glUniform1i(textureLocation,0);
glVertexAttribPointer(glGetAttribLocation(SkyProg,"sky_in"),2,GL_FLOAT,GL_FALSE,0,&amp;Tex[i*8]);
glDrawArrays(GL_QUADS,i*12,12);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glUseProgram(0);
}


Result is that:

http://screenup.pl/?l=AAAPTQO

BTW Cube in center is other object whitch I'll render in next, so don't mention about it.