opengl multitexturing glsl - only one texture at a time - c++

It seems like if i use texture(texture0,textCoord) for one time and then i try to use it again with an other texture texture(texture1,textCoord); it returns (0,0,0,0); and i just dont know why .
In my program it seems to be an order of workines ,if the depht works than the others wont ,
if i dont use the depth than only the color works and so on .( Depht , Color , Normal , Pos , Shine is the order)
this is the fragment shader :
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex3;
uniform sampler2D depht;
void main()
{
float UNIT = 1./640. ;
//vec4 depht = texture(depht,gl_TexCoord[0].st);
vec4 color = texture(tex0,gl_TexCoord[0].st);
vec4 norma = texture(tex1,gl_TexCoord[0].st);
vec4 posit = texture(tex2,gl_TexCoord[0].st);
vec4 shine = texture(tex3,gl_TexCoord[0].st);
if(false){
gl_FragColor=( texture2D(tex0,gl_TexCoord[0].st +vec2(0,0))+
texture2D(tex0,gl_TexCoord[0].st +vec2(0,-UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(UNIT,-UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(UNIT,0))+
texture2D(tex0,gl_TexCoord[0].st +vec2(UNIT,UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(0,UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(-UNIT,UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(-UNIT,0))+
texture2D(tex0,gl_TexCoord[0].st +vec2(-UNIT,-UNIT)))/9.;
}else{
gl_FragColor=(norma+color);
}
}
this is the binding part :
fbotest.drawFBO();
DEFERRED.UseNow();
DrawGLScene();
fbotest.readFBO();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
DEFERRED2.UseNow();
//glBlendFunc (GL_ONE, GL_ONE);
glEnable( GL_BLEND );
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbotest.Color);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fbotest.Normal);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, fbotest.Pos);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, fbotest.Shine);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, fbotest.Depht);
glEnable(GL_TEXTURE_2D);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex0"),0);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex1"),1);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex2"),2);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex3"),3);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"depht"),4);
glLoadIdentity();
glBegin(GL_QUADS);
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE2, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE3, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE4, 1.0, 0.0);
glVertex3f( 1,-1,-3);
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE1, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE2, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE3, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE4, 1.0, 1.0);
glVertex3f( 1,1 ,-3);
glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE1, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE2, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE3, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE4, 0.0, 1.0);
glVertex3f( -1,1,-3);
glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE1, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE2, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE3, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE4, 0.0, 0.0);
glVertex3f(-1,-1,-3);
glEnd();
glActiveTextureARB(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable( GL_BLEND );
and this is may FBO class :
class deferred{
public :
unsigned int FBO;
unsigned int Depht;
unsigned int Color;
unsigned int Normal;
unsigned int Pos;
unsigned int Shine;
deferred();
void initFBO();
void readFBO();
void drawFBO();
};
void deferred::readFBO(){
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
glBindFramebuffer(GL_READ_FRAMEBUFFER,FBO);
}
void deferred::drawFBO(){
glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,FBO);
}
deferred::deferred(){
FBO =0;
Depht =0;
Color =0;
Normal =0;
Pos =0;
Shine =0;
}
void deferred::initFBO(){
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
glGenTextures(1,&Depht );
glGenTextures(1,&Color );
glGenTextures(1,&Normal);
glGenTextures(1,&Pos );
glGenTextures(1,&Shine );
int WindowWidth = Ww;
int WindowHeight= Wh;
glBindTexture(GL_TEXTURE_2D, Color);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Color, 0);
glBindTexture(GL_TEXTURE_2D, Normal);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, Normal, 0);
glBindTexture(GL_TEXTURE_2D, Pos);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, Pos, 0);
glBindTexture(GL_TEXTURE_2D, Shine);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, Shine, 0);
glBindTexture(GL_TEXTURE_2D, Depht);
glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Depht, 0);
GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
glDrawBuffers(4, DrawBuffers);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE) {
cout <<"Frame Buffer ERROR : "<< Status << "\n" ;
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex0"),0);
Try changing these to look like this. GL_TEXTURE_2D should be enabled when binding. ALso the ID at the end of glBindTexture shoulder go up - 0 1 2 3 4 5. I'm not sure what your values are returning. Then you send that data each time with glUinform1i which will bind the texture bound at 0.

I've changed this :
void deferred::readFBO(){
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
glBindFramebuffer(GL_READ_FRAMEBUFFER,FBO);
}
void deferred::drawFBO(){
glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,FBO);
}
with this :
> void deferred::readFBO(){
> glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
> glBindFramebuffer(GL_READ_FRAMEBUFFER,FBO);
>
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, 0, 0);
}
>
> void deferred::drawFBO(){
> glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
> glBindFramebuffer(GL_DRAW_FRAMEBUFFER,FBO);
>
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Color , 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, Normal, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, Pos , 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, Shine , 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, Depht , 0);
}
and now it works . I belive it is a litle slow even if i dont see any changes in framerates and i dont quite know why i cant let the textures binded to the framebuffer , but yea it solved the problem .

Related

Deferred shader textures from FBO display as black

I am trying to use deferred shading to implement SSAO and I have problems to access my textures in the deferred fragment shader. The code is in C++/Qt5 and makes use of Coin3D to generate the rest of the UI (but this shouldn't really matter here).
The fragment shader of the deferred pass is:
#version 150 compatibility
uniform sampler2D color;
uniform sampler2D position;
uniform sampler2D normal;
uniform vec3 dim;
uniform vec3 camPos;
uniform vec3 camDir;
void main()
{
// screen position
vec2 t = gl_TexCoord[0].st;
// the color
vec4 c = texture2D(color, t);
gl_FragColor = c + vec4(1.0, t.x, t.y, 1.0);
}
The code for running the deferred pass is
_geometryBuffer.Unbind();
// push state
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_DEPTH_BUFFER_BIT |
GL_COLOR_BUFFER_BIT |
GL_LIGHTING_BIT |
GL_SCISSOR_BIT |
GL_POLYGON_BIT |
GL_CURRENT_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_CULL_FACE);
}
// bind shader
// /!\ IMPORTANT to do before specifying locations
_deferredShader->bind();
_CheckGLErrors("deferred");
// specify positions
_deferredShader->setUniformValue("camPos", ...);
_deferredShader->setUniformValue("camDir", ...);
_geometryBuffer.Bind(GBuffer::TEXTURE_TYPE_NORMAL, 2);
_deferredShader->setUniformValue("normal", GLint(2));
_geometryBuffer.Bind(GBuffer::TEXTURE_TYPE_POSITION, 1);
_deferredShader->setUniformValue("position", GLint(1));
_geometryBuffer.Bind(GBuffer::TEXTURE_TYPE_DIFFUSE, 0);
_deferredShader->setUniformValue("color", GLint(0));
_CheckGLErrors("bind");
// draw screen quad
{
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glColor3f(0, 0, 0);
glVertex2f(-1, -1);
glTexCoord2f(1, 0);
glColor3f(0, 0, 0);
glVertex2f( 1, -1);
glTexCoord2f(1, 1);
glColor3f(0, 0, 0);
glVertex2f( 1, 1);
glTexCoord2f(0, 1);
glColor3f(0, 0, 0);
glVertex2f(-1, 1);
glEnd();
}
_deferredShader->release();
// for debug
_geometryBuffer.Unbind(2);
_geometryBuffer.Unbind(1);
_geometryBuffer.Unbind(0);
_geometryBuffer.DeferredPassBegin();
_geometryBuffer.DeferredPassDebug();
// pop state
{
glPopAttrib();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
I know that the textures have been correctly processed in the geometry buffer creation because I can dump them into files and get the expected result.
The deferred pass doesn't work. The shader compiled correctly and I get the following result on screen:
And the last part of my code (DeferredPassBegin/Debug) is to draw the FBO to the screen (as shown in screenshot) as a proof that the GBuffer is correct.
The current result seems to mean that the textures are not correctly bound to their respective uniform, but I know that the content is valid as I dumped the textures to files and got the same results as shown above.
My binding functions in GBuffer are:
void GBuffer::Unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
void GBuffer::Bind(TextureType type, uint32_t idx)
{
glActiveTexture(GL_TEXTURE0 + idx);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textures[static_cast<uint32_t>(type)]);
}
void GBuffer::Unbind(uint32_t idx)
{
glActiveTexture(GL_TEXTURE0 + idx);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
Finally, the textures are 512/512, and I created them in my GBuffer with:
WindowWidth = WindowHeight = 512;
// Create the FBO
glGenFramebuffers(1, &_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
const uint32_t NUM = static_cast<uint32_t>(NUM_TEXTURES);
// Create the gbuffer textures
glGenTextures(NUM, _textures);
glGenTextures(1, &_depthTexture);
for (unsigned int i = 0 ; i < NUM; i++) {
glBindTexture(GL_TEXTURE_2D, _textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WindowWidth, WindowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i + _firstIndex, GL_TEXTURE_2D, _textures[i], 0);
}
// depth
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _depthTexture, 0);
GLenum buffers[NUM];
for(uint32_t i = 0; i < NUM; ++i){
buffers[i] = GLenum(GL_COLOR_ATTACHMENT0 + i + _firstIndex);
}
glDrawBuffers(NUM, buffers);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("FB error, status: 0x%x\n", status);
return _valid = false;
}
// unbind textures
glBindTexture(GL_TEXTURE_2D, 0);
// restore default FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
How can I debug farther at this stage?
I know that the texture data is valid, but I can't seem to bind it to the shader correctly (but I have other shaders that use textures loaded from files and which work fine).
--- Edit 1 ---
As asked, the code for DeferredPassBegin/Debug (mostly coming from this tutorial )
void GBuffer::DeferredPassBegin() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo);
}
void GBuffer::DeferredPassDebug() {
GLsizei HalfWidth = GLsizei(_texWidth / 2.0f);
GLsizei HalfHeight = GLsizei(_texHeight / 2.0f);
SetReadBuffer(TEXTURE_TYPE_POSITION);
glBlitFramebuffer(0, 0, _texWidth, _texHeight,
0, 0, HalfWidth, HalfHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
SetReadBuffer(TEXTURE_TYPE_DIFFUSE);
glBlitFramebuffer(0, 0, _texWidth, _texHeight,
0, HalfHeight, HalfWidth, _texHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
SetReadBuffer(TEXTURE_TYPE_NORMAL);
glBlitFramebuffer(0, 0, _texWidth, _texHeight,
HalfWidth, HalfHeight, _texWidth, _texHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
}
Arghk!!!
So I expected that texture parameters were not mandatory, but as I looked at some code, I just tried to specify my texture parameters. When generating the FBO textures, I use now
for (unsigned int i = 0 ; i < NUM; i++) {
glBindTexture(GL_TEXTURE_2D, _textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WindowWidth, WindowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i + _firstIndex, GL_TEXTURE_2D, _textures[i], 0);
}
And with this change, I get the expected result (with only c in the fragment shader, and similar correct results if I switch to visualizing the normal / position).
Conclusion: one must specify the texture parameters for deferred shading to work (at least with the graphics setup of my application / machine).

opengl - Only one texture displaying

I have been trying draw a hut (as a cylinder with a cone on top) and add a brick txture to the wall and a roof-tile texture to the roof. However, I am only getting the first texture that I load (the bricks).
Here is my code (Please note that I have tried to switch between textures using glActiveTexture):
void drawCylinder()
{
int width, height;
unsigned char * data_for_wall = SOIL_load_image("./bricks.jpg", &width, &height, NULL, 0);
glDisable(GL_LIGHTING);
glGenTextures( 2, textures );
glActiveTexture(GL_TEXTURE0);
glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_wall);
for(float theta = 0.0; theta <= 360.0; theta += 10.0 )
{
//colors[k] = color4(0.69, 0.35, 0.0, 1.0); //This color is brown.
tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.0);
float x = 0.15*sin(theta*DegreesToRadians);
float y = 0.15*cos(theta*DegreesToRadians);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.0, y, 1.0);
// This is the
// bottom of the cylinder. The points are plotted in a full circle. The first three numbers are the x,y and z values
// respectively. The last number (ie. 1.0) is not important - it just converts to homogeneous coordinates.
++global_index;
tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.25);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.25, y, 1.0);
// This is the
// top of the cylinder
++global_index;
}
}
//The roof of the hut
void drawCone()
{
int width, height;
unsigned char * data_for_roof = SOIL_load_image("./roof_tiles.jpg", &width, &height, NULL, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture( GL_TEXTURE_2D, textures[1] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_roof);
int index = 0;
int l = 0;
for(float theta = 0.0; theta <= 360.0; theta += 10.0)
{
tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.25);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.0, 0.5, 0.0, 1.0); // This is the top of the cone.
++global_index;
tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.5);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.25*sin(theta*DegreesToRadians), 0.25, 0.25*cos(theta*DegreesToRadians), 1.0);
// This is the
// bottom of the cone.
++global_index;
}
}
And here is the display function:
void
display( void )
{
mat4 mv = Translate(0.0, -0.065, -rad)*RotateX(Theta[0])*RotateY(Theta[1])*RotateZ(Theta[2]);
mat4 p = Perspective(10.0, aspectRatio, zNear, zFar);
glUniformMatrix4fv( matrix_loc, 1, GL_TRUE, mv );
glUniformMatrix4fv( projection_loc, 1, GL_TRUE, p );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUniform3fv( theta, 1, Theta );
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glDrawArrays( GL_TRIANGLE_STRIP, 0, 74 );
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glDrawArrays( GL_TRIANGLE_STRIP, 74, 74);
glutSwapBuffers();
}
I am not sure if it is important to include the fragment shader but I will do it anyways:
#version 150
in vec2 texCoord;
out vec4 fColor;
uniform sampler2D texture;
void main()
{
fColor = texture2D( texture, texCoord );
}
I have been struggling for hours to get this right. Does anyone know what I have done wrong?
glActiveTexture() is used to set the texture slot that you are binding a texture to when multi-texturing (rendering more than one texture in a single pass). For example, you might have one texture for a texture map, another for normal map and so on.
However, you are not multi-texturing, because you render the walls and the cone in separate passes (i.e. two separate calls to glDrawArrays()), and your shader only uses a single texture per pass. So within each pass you are only rendering a single texture, which will be in slot 0.
If you set the active texture to GL_TEXTURE1 and then call glBindTexture() then the texture will be bound to slot 1, and slot 0 will remain unchanged.
So, set the active texture slot to 0 both times. Remove this line from your display() function:
glActiveTexture(GL_TEXTURE1);

texture(...) function always returns 0

I have been trying to get shadow mapping to work for quite some time now and I am still no closer than I was a month ago. I am beginning to think it may be an issue with my GL drivers because I haven't been able to see any side effects such as "light acne."
I was told to start using a sampler2DShadow instead of a sampler2D and this is what I did. However, whenever I sample the map using texture(...) the result is always 0. Why would this be happening?
I have tried entering manual depthCoord values and I still get 0. Could this be a result of the shadowMap itself (i.e the way it has been setup?) or is it a driver issue?
Framebuffer Setup
FramebufferName = 0;
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Fragment Shader
uniform sampler2DShadow shadowMap;
in vec4 depthCoord;
void main(){
//The final color after lighting is stored as 'FinalColor'
float visibility = 1.0;
if (texture(shadowMap, depthCoord.xyz) == 0.0){
visibility = 0.1;
}
color = vec4(finalColor.rgb * visibility, 1.0);
}
Rendering Code
glm::vec3 lightInvDir = glm::vec3(0,-10,-10);
glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20);
glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0));
glm::mat4 depthModelMatrix = glm::mat4(1.0);
glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;
glm::mat4 biasMatrix(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);
glm::mat4 depthBiasMVP = biasMatrix*depthMVP;
/* Shadow */
subShader->useShader();
glViewport(0,0,512,512);
glUniformMatrix4fv(glGetUniformLocation(subShader->getShader(),"depthMVP"), 1, GL_FALSE, &depthMVP[0][0]);
glBindFramebuffer(GL_FRAMEBUFFER, Shadows::framebuffer());
renderBuffer(objBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
/* Clear */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Shader */
objShader->useShader();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Shadows::shadowmap());
glUniform1f(glGetUniformLocation(objShader->getShader(),"shadowMap"),0);
/* Render Scene */
glUniformMatrix4fv(glGetUniformLocation(objShader->getShader(),"depthBiasMVP"), 1, GL_FALSE, &depthBiasMVP[0][0]);
glViewport(0,0,640,480);
glUniform1f(glGetUniformLocation(objShader->getShader(),"renderingPass"),1.0);
renderBuffer(objBuffer);
The majority of this code has been learned from sites such as (http://www.opengl-tutorial.org/) with modifications based on (http://www.fabiensanglard.net/shadowmapping/index.php) and the red book.

ShadowMaps + 2 Lights (or more) + glsl1.2 = Trouble

Well, I've done a test to see if it works the shadowmapping using two light source. Something is wrong, the first shadowmap make a correct shade, but the second shadowmap not. This is the complete code.
FUNCTIONS
void setupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z){
glLoadIdentity();
gluLookAt(position_x,position_y,position_z,lookAt_x,lookAt_y,lookAt_z,0,1,0);
}
void setTextureMatrix1(){
static double modelView[16];
static double projection[16];
const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE6);
glLoadIdentity();
glLoadMatrixd(bias);
glMultMatrixd (projection);
glMultMatrixd (modelView);
glMatrixMode(GL_MODELVIEW);
}
void setTextureMatrix2(){
static double modelView[16];
static double projection[16];
const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE7);
glLoadIdentity();
glLoadMatrixd(bias);
glMultMatrixd (projection);
glMultMatrixd (modelView);
glMatrixMode(GL_MODELVIEW);
}
void startTranslate1(float x,float y,float z){
glPushMatrix();
glTranslatef(x,y,z);
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE6);
glPushMatrix();
glTranslatef(x,y,z);
}
void startTranslate2(float x,float y,float z){
glPushMatrix();
glTranslatef(x,y,z);
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE7);
glPushMatrix();
glTranslatef(x,y,z);
}
void endTranslate(){
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void drawObjects1(){
glColor4f(0.3f,0.3f,0.3f,1);
glBegin(GL_QUADS);
glVertex3f(-35,2,-35);
glVertex3f(-35,2, 15);
glVertex3f( 15,2, 15);
glVertex3f( 15,2,-35);
glEnd();
glColor4f(0.9f,0.9f,0.9f,1);
startTranslate1(0,4,-5);
glutSolidCube(4);
endTranslate();
}
void drawObjects2(){
glColor4f(0.3f,0.3f,0.3f,1);
glBegin(GL_QUADS);
glVertex3f(-35,2,-35);
glVertex3f(-35,2, 15);
glVertex3f( 15,2, 15);
glVertex3f( 15,2,-35);
glEnd();
glColor4f(0.9f,0.9f,0.9f,1);
startTranslate2(0,4,-5);
glutSolidCube(4);
endTranslate();
}
MAIN
int main(){
GLuint depthTextureId;
glGenTextures(1, &depthTextureId);
glBindTexture(GL_TEXTURE_2D, depthTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fboId;
GLenum FBOstatus;
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId, 0);
FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
/////////////////////////////////////////////////////////////////////
GLuint depthTextureId2;
glGenTextures(1, &depthTextureId2);
glBindTexture(GL_TEXTURE_2D, depthTextureId2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fboId2;
GLenum FBOstatus2;
glGenFramebuffersEXT(1, &fboId2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId2);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId2, 0);
FBOstatus2 = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(FBOstatus2 != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
GLfloat angulo = 0.0;
GLfloat posZ = 0.0;
glEnable(GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
MAIN LOOP
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(5.0,15.0,0.0,-5.0,0.0,-5.0);
glCullFace(GL_FRONT);
drawObjects1();
setTextureMatrix1();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId2);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(p_light[0],p_light[1],p_light[2],l_light[0],l_light[1],l_light[2]);
glCullFace(GL_FRONT);
drawObjects2();
setTextureMatrix2();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glViewport(0,0,640,480);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glUseProgram(p);
glUniform1i(shadowMapUniform,6);
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_2D,depthTextureId);
glUniform1i(shadowMapUniform2,7);
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D,depthTextureId2);
glCullFace(GL_BACK);
setupMatrices(p_camera[0],p_camera[1],p_camera[2],l_camera[0],l_camera[1],l_camera[2]);
drawObjects1();
glBindTexture(GL_TEXTURE_2D,0);
glUseProgram(0);
VERTEX SHADER
varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;
void main(){
ShadowCoord1 = gl_TextureMatrix[6] * gl_Vertex;
ShadowCoord2 = gl_TextureMatrix[7] * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
}
FRAGMENT SHADER
uniform sampler2D ShadowMap;
uniform sampler2D ShadowMap2;
varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;
varying vec3 pvertice;
void main(){
vec4 shadowCoordinateWdivide1 = ShadowCoord1 / ShadowCoord1.w ;
vec4 shadowCoordinateWdivide2 = ShadowCoord2 / ShadowCoord2.w ;
shadowCoordinateWdivide1.z += 0.0001;
shadowCoordinateWdivide2.z += 0.0001;
float distanceFromLight1 = texture2D(ShadowMap,shadowCoordinateWdivide1.st).z;
float distanceFromLight2 = texture2D(ShadowMap2,shadowCoordinateWdivide2.st).z;
float shadow1 = 1.0;
if (ShadowCoord1.w > 0.0){
shadow1 = distanceFromLight1 < shadowCoordinateWdivide1.z ? 0.5 : 1.0 ;
}
float shadow2 = 1.0;
if (ShadowCoord2.w > 0.0){
shadow2 = distanceFromLight2 < shadowCoordinateWdivide2.z ? 0.5 : 1.0 ;
}
gl_FragColor = mix(shadow1,shadow2,0.5) * gl_Color;
}
What is wrong? This looks like...
If I try to move around the object it looks bad.
While with a single light in the same position it looks like this.
If I try to move around the object this looks good.
Thanks.
Those bias impact self shadowing, try setting them a bit higher.
shadowCoordinateWdivide1.z += 0.0001;
shadowCoordinateWdivide2.z += 0.0001;

opengl shader problems with mrt

I have two textures with same size attached to one fbo, and I want to render another texture into one of the attached textures, and I want to render a blue shape of the figure of the input texture to the other fbo attached texture.
the (updated) vertex shader:
#version 330
in vec2 coord;
out vec2 f_coord;
void main() {
gl_Position = vec4(coord, 0.0, 1.0);
f_coord = (1.0+coord)/2.0;
}
the (updated) fragment shader:
#version 330
uniform sampler2D my_texture;
in vec2 f_coord;
out vec4 FragData[2];
void main() {
if(texture(my_texture,f_coord).a == 0.0)
discard;
FragData[0]=texture(my_texture,f_coord);
FragData[1]=vec4(0.5, 0.5, 1.0, 1.0);
}
With this fragment shader everything works fine. The texture and the blue stamp of the texture contures are rendered properly.
Here is a screenshot:
http://s14.directupload.net/file/d/3487/kvkqdbl7_png.htm
But if I want to render the texture into gl_FragData[1] and the blue conture stamp into gl_FragData[0]
#version 330
uniform sampler2D my_texture;
in vec2 f_coord;
out vec4 FragData[2];
void main() {
if(texture(my_texture,f_coord).a == 0.0)
discard;
FragData[0]=vec4(0.5, 0.5, 1.0, 1.0);
FragData[1]=texture(my_texture,f_coord);
}
than I get two totally blue textures. The strange thing is: Both target textures are totally blue, but I have set the glViewport just to a part of the texture.
Here a screenshot:
http://s1.directupload.net/file/d/3487/9loqibdc_png.htm
The fbo attachments have the half screen size
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glutGet(GLUT_WINDOW_WIDTH)/2, glutGet(GLUT_WINDOW_HEIGHT), 0, GL_RGBA, GL_BYTE, 0);
So I can render both textures to the screen for checking.
This is how I created the framebufferobject
void init_fbo()
{
glGenTextures(1, &fbo.texture0);
glBindTexture(GL_TEXTURE_2D, fbo.texture0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glutGet(GLUT_WINDOW_WIDTH)/2, glutGet(GLUT_WINDOW_HEIGHT), 0, GL_RGBA, GL_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenTextures(1, &fbo.texture1);
glBindTexture(GL_TEXTURE_2D, fbo.texture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glutGet(GLUT_WINDOW_WIDTH)/2, glutGet(GLUT_WINDOW_HEIGHT), 0, GL_RGBA, GL_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &fbo.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo.fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
fbo.texture0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
fbo.texture1, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
I use those global struct variables
struct
{
GLuint fbo;
GLuint texture0;
GLuint texture1;
} fbo;
struct
{
GLuint program;
GLint uni_texture;
GLint att_coord;
} shader_fbo;
struct
{
GLuint program;
GLint uni_texture;
GLint att_coord;
} shader_screen;
And this is my render function
void render()
{
GLenum buffers[2];
GLfloat vertices[] = { -1.0, -1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0 };
GLubyte indices[] = { 0, 1, 2,
1, 2, 3 };
/*render to mrt fbo*/
glUseProgram(shader_fbo.program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture.texID);
glUniform1i(shader_fbo.uni_texture, 0);
glEnableVertexAttribArray(shader_fbo.att_coord);
glVertexAttribPointer(shader_fbo.att_coord,
2,
GL_FLOAT,
GL_FALSE,
0,
vertices);
glBindFramebuffer(GL_FRAMEBUFFER, fbo.fbo);
buffers[0] = GL_COLOR_ATTACHMENT0;
buffers[1] = GL_COLOR_ATTACHMENT1;
glDrawBuffers(2, buffers);
glViewport(0, 0,
texture.width, texture.height);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture.texID);
glUniform1i(shader_fbo.uni_texture, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
glDisableVertexAttribArray(shader_fbo.att_coord);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
/*render both textures now to screen*/
glUseProgram(shader_screen.program);
glEnableVertexAttribArray(shader_screen.att_coord);
glVertexAttribPointer(shader_screen.att_coord,
2,
GL_FLOAT,
GL_FALSE,
0,
vertices);
/*render the first texture to the left side of the screen*/
glViewport(0, 0,
glutGet(GLUT_WINDOW_WIDTH)/2, glutGet(GLUT_WINDOW_HEIGHT));
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbo.texture0);
glUniform1i(shader_screen.uni_texture, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
/*render the second texture to the right side of the screen*/
glViewport(glutGet(GLUT_WINDOW_WIDTH)/2, 0,
glutGet(GLUT_WINDOW_WIDTH)/2, glutGet(GLUT_WINDOW_HEIGHT));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbo.texture1);
glUniform1i(shader_screen.uni_texture, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
glutSwapBuffers();
}