OPEN GL Color Mapping - opengl

I have the following working code(I took it from an example).
It produces a cube with its sides coloured differently.
Is there any way that I can assign colour to every(a group) of pixels on the sides depending on their position or some simulation. Some thing like a colour map of a scalar field on to the surface of the cube... ?
Can someone give me an example of doing so on arbitrary surfaces?
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/freeglut_ext.h>
void init(void)
{
glClearColor(0,0,0,0);
glShadeModel(GL_FLAT);
}
void DrawCube(void)
{
glLoadIdentity();
gluLookAt(0, 10, 10, 0, 1, 0, 0, -2, -35.7);
glBegin(GL_QUADS);
//face in xy plane
glColor3f(0.12, 0.91, 0.02);//this the color with which complete cube is drawn.
glVertex3f(0,0 ,0 );
glVertex3f(5, 0, 0);
glVertex3f(5, 5, 0);
glVertex3f(0, 5, 0);
//face in yz plane
glColor3f(1, 0.23, 0.56);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 5);
glVertex3f(0, 5, 0);
glVertex3f(0, 5, 5);
//face in zx plance
glColor3f(0.45, .81, 1);
glVertex3f(0, 0, 0 );
glVertex3f(0, 0, 5);
glVertex3f(5, 0, 5);
glVertex3f(5, 0, 0);
//|| to xy plane.
glColor3f(0.23, 0.78,0.13);
glVertex3f(0, 0, 5);
glVertex3f(5, 0, 5);
glVertex3f(5, 5, 5);
glVertex3f(0, 5, 5);
//|| to yz plane
glColor3f(0.73, 0.58, 0.58);
glVertex3f(0,0 ,5 );
glVertex3f(5, 0, 5);
glVertex3f(5, 5, 5);
glVertex3f(0, 5, 5);
//|| to zx plane
glVertex3f(0.58, 0, 0.82);
glVertex3f(0, 5, 0 );
glVertex3f(0, 5, 5);
glVertex3f(5, 5, 5);
glVertex3f(5, 5, 0);
glEnd();
glFlush();
}
void reshape(int w,int h){
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, 1.5, 20);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv){
glutInit(&argc, argv);//we initizlilze the glut. functions
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(800, 800);
glutCreateWindow(argv[1]);
init();
glutDisplayFunc(DrawCube);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

Related

Perspective drawing in OpenGL using glFrustum

I'm trying to draw a cube in cabinet perspective. This is the cube in glOrtho:
Other faces:
Back - cyan, Left - magenta, down - blue
This is what I get
This is what I want to achieve
My code:
//init function
glClearColor(1, 1, 1, 1);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-10, 10, -10, 10, 4,6);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0,0,-lat);//it doesn't show in the window without this.
DisplayAxis();
DisplayObject();
break;
//object initalization. I use glGenList and glCallList to draw it
void InitObject() {
glNewList(k, GL_COMPILE);
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex3d(0, lat, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, 0, lat);
glVertex3d(0, 0, lat);
glEnd();
glColor3f(1, 1, 0);
glBegin(GL_QUADS);
glVertex3d(lat, 0, 0);
glVertex3d(lat, 0, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, lat, 0);
glEnd();
glColor3f(0, 1, 0);
glBegin(GL_QUADS);
glVertex3d(0, lat, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, lat, 0);
glVertex3d(0, lat, 0);
glEnd();
glColor3f(0, 0, 1);
glBegin(GL_QUADS);
glVertex3d(0, 0, 0);
glVertex3d(lat, 0, 0);
glVertex3d(lat, 0, lat);
glVertex3d(0, 0, lat);
glEnd();
glColor3f(1, 0, 1);
glBegin(GL_QUADS);
glVertex3d(0, 0, lat);
glVertex3d(0, 0, 0);
glVertex3d(0, lat, 0);
glVertex3d(0, lat, lat);
glEnd();
glColor3f(0, 1, 1);
glBegin(GL_QUADS);
glVertex3d(0, lat, 0);
glVertex3d(lat, lat, 0);
glVertex3d(lat, 0, 0);
glVertex3d(0, 0, 0);
glEnd();
glEndList();
}
What am I doing wrong here? I tried some rotations on the object but I get some skewed results(I can post more images if needed).
The object is clipped by the near plane of the Viewing frustum.
Not you have to translate the object along the negativ z axis, to move the object in between the near and far plane of the viewing frustum:
glTranslated(0,0,-lat);//it doesn't show in the window without this.
Since the view space z axis points out out the viewport, you have to shift the object along the negative z axis.
The distance to the near plane is 4 and the distance to the far plane is 6:
glFrustum(-10, 10, -10, 10, 4,6);
The distance to the front of the cube is less than 4, thus it is clipped by the near plane.
Change the frustum, and keep the cube completely in the frustum to solve the issue:
glFrustum(-10, 10, -10, 10, 4,6);
glFrustum(-2.5, 2.5, -2.5, 2.5, 1, 10);
glTranslated(0,0,-lat);
glTranslated(0, 0, -6);
For a good perspective and look at the scene, use a projection matrix (frustum) with a smaller field of view:
glFrustum(-1, 1, -1, 1, 1, 12);
Alternatively you can define the frustum by gluPerspective and set the field of view angle in degrees:
gluPerspective(90, 1, 1, 12);
The view matrix defines the position and viewing direction of the observer (viewer) within the scene.
If you want a different look at the scene the you have to rotate the scene (glRotate):
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0, 0, -8);
glRotatef(30, 1, 0, 0);
glRotatef(-45, 0, 1, 0);
Alternatively the look at the scene (view matrix) can be defined by gluLookAt . Arguments 1-3 are the position of the observer (x,y, z components of eye or camera position). The Arguments 4-6 are the target point (where the observer looks at). The arguments 7-9 are the upwards vector.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5, 5, 7, 0, 0, 0, 0, 1, 0);

Built-in polygon clipping in OpenGL

Why does the below code is showing a triangle in front of the quad for:
gluLookAt(10, 10, 60, 0, 0, 0, 0, 1, 0)
and
glOrtho(-30, 30, -30, 30, 0, 90)
Expected Output: Because the 'z' value of the triangle is less than the quad and the observer is at 60 unit in the positive 'z' axis, the rectangle should have been visible as a whole and only a few parts of the triangle would had been visible.
glBegin(GL_QUADS);
glColor3f(1, 1, 1);
glVertex3f(10, 10, 15); glVertex3f(20, 10, 15); glVertex3f(20, 20, 15); glVertex3f(10, 20, 15);
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0);
glVertex3f(22, 14, 0);
glVertex3f(16, 22, 0);
glEnd();
First of all, your question is totally unrelated to clipping - Clipping means calculating the intersection of the primitves against some clip area or clip volume.
The triangle does appear because you draw it after the quad. By default, OpenGL will not apply any visibility algorithms. However, OpenGL does support the Z buffer algorithm in form of the depth test.
So finally I have got answer to this.
It required few lines of code to be added.
Adding below 3 lines in the initialization step
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
Initializing display mode to add depth information (GLUT_DEPTH ) as below
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
Below is the complete code for displaying a rectangle behind which is a traingle.
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#include<iostream>
using namespace std;
void FPS(void);
GLint gFramesPerSecond = 0;
int TIMER_SPEED = 10000;
float i = 40;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(10, 10, i-=.2, 10, 10, -10, 0, 1, 0);
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0); glVertex3f(20, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0); glVertex3f(0, 20, 0);
glColor3f(0, 0, 1);
glVertex3f(0, 0, 0); glVertex3f(0, 0, 50);
glEnd();
glBegin(GL_QUADS);
glColor3f(1, 1, 1);
glVertex3f(10, 10, 10); glVertex3f(20, 10, 15); glVertex3f(20, 20, 15); glVertex3f(10, 20, 15);
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(0, 1, 0);
glVertex3f(12, 12, 20);
glVertex3f(22, 14, 12);
glVertex3f(16, 22, 12);
glEnd();
glutSwapBuffers();
}
void timer(int v)
{
static GLfloat u = 0.0;
u += 0.01;
glutTimerFunc(TIMER_SPEED/60.0, timer, ++v);
display();
}
void Init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}
void Resize(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-15, 30, -15, 30, 15, 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(200, 200);
glutCreateWindow("3D Object in OpenGL");
glutKeyboardFunc(myKeyboard);
Init();
glutDisplayFunc(display);
glutReshapeFunc(Resize);
glutTimerFunc(100, timer, 0);
glutMainLoop();
return 0;
}

How do I draw a cube with all faces having different textures?

I'm trying to move my code over to modern Opengl, but am having trouble. Right now my code will draw a cube and it will put a texture on, but it will only attach the first texture to all of my face. I am also using SOIL to load my textures into my program. What am I doing wrong?
This is my code:
class Rectangle
{
public:
Rectangle();
Rectangle(float x, float y, float z, float width, float height, float depth, string frontFace, string backFace, string leftFace,
string RightFace, string topFace, string bottomFace);
void Draw();
private:
GLuint m_Textures[6];
string m_TextureNames[6];
GLfloat m_Vertices[72]; // v0,v1,v2,v3 (front)
// normal array
GLfloat m_Normals[72]; // v0,v1,v2,v3 (front)
// color array
GLfloat m_Colours[72]; // v0,v1,v2,v3 (front)
// index array of vertex array for glDrawElements() & glDrawRangeElement()
GLubyte m_Indices[36]; // front
GLfloat m_Texcoords[48];
};
Rectangle::Rectangle(float x, float y, float z, float width, float height, float depth, string topFace, string bottomFace, string frontFace,
string backFace, string leftFace, string rightFace)
{
m_CenterX = x;
m_CenterY = y;
m_CenterZ = z;
m_Width = width;
m_Height = height;
m_Depth = depth;
m_TextureNames[0] = topFace;
m_TextureNames[1] = bottomFace;
m_TextureNames[2] = frontFace;
m_TextureNames[3] = backFace;
m_TextureNames[4] = leftFace;
m_TextureNames[5] = rightFace;
m_ObjectType = Textured;
GLfloat tempVert[] = { // front
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// top
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
// back
1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
// bottom
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// left
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
// right
1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
};
// normal array
GLfloat tempNormals[] = { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left)
0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7,v4,v3,v2 (bottom)
0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 }; // v4,v7,v6,v5 (back)
// color array
GLfloat tempColors[] = { 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, // v0,v1,v2,v3 (front)
1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, // v0,v3,v4,v5 (right)
1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, // v0,v5,v6,v1 (top)
1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, // v1,v6,v7,v2 (left)
0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // v7,v4,v3,v2 (bottom)
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1 }; // v4,v7,v6,v5 (back)
// index array of vertex array for glDrawElements() & glDrawRangeElement()
GLubyte tempIndices[] = { 0, 1, 2, 2, 3, 0, // front
4, 5, 6, 6, 7, 4, // right
8, 9,10, 10,11, 8, // top
12,13,14, 14,15,12, // left
16,17,18, 18,19,16, // bottom
20,21,22, 22,23,20 }; // back
GLfloat tempTexcoords[2*4*6] = {
// front
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
};
for (int i = 1; i < 6; i++)
memcpy(&tempTexcoords[i*4*2], &tempTexcoords[0], 2*4*sizeof(GLfloat));
copy(tempVert, tempVert + 72, m_Vertices);
copy(tempNormals, tempNormals + 72, m_Normals);
copy(tempColors, tempColors + 72, m_Colours);
copy(tempIndices, tempIndices + 36, m_Indices);
std::copy(tempTexcoords, tempTexcoords + 48, m_Texcoords);
LoadTexture(m_TextureNames);
}
void Rectangle::LoadTexture(string TextureName[6])
{
// Create texture index array.
glGenTextures(6, m_Textures);
for(int i = 0 ; i < 1 ; i++)
{
glBindTexture(GL_TEXTURE_2D, m_Textures[i]);
// Set our texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // NOTE the GL_NEAREST Here!
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // NOTE the GL_NEAREST Here!
std::string fileType;
fileType.append(m_TextureNames[i], m_TextureNames[i].size()-3,3);
if(fileType == "jpg")
{
m_Textures[i] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
m_TextureNames[i].c_str(),
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
// allocate a texture name
}
else
{
m_Textures[i] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
m_TextureNames[i].c_str(),
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
// allocate a texture name
}
}
}
// Function to draw Sphere.
void Rectangle::Draw()
{
// enable and specify pointers to vertex arrays
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, m_Normals);
glTexCoordPointer(2, GL_FLOAT, 0, m_Texcoords);
glColorPointer(3, GL_FLOAT, 0, m_Colours);
glVertexPointer(3, GL_FLOAT, 0, m_Vertices);
for (int i=0;i<6;i++)
{
glPushMatrix();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_Textures[i]);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, m_Indices);
glPopMatrix();
}
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
Rectangle testRect;
// Drawing routine.
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
testRect.Draw();
glutSwapBuffers();
}
// Initialization routine.
void setup(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
testRect = Rectangle(2, 0.0, 0.0, 1, 2, 1, "grass.bmp","grass.bmp", "grass.bmp", "launch.png", "launch.png", "launch.png");
// Turn on OpenGL texturing.
glEnable(GL_TEXTURE_2D);
glShadeModel (GL_SMOOTH);
}
The posted code has a few issues:
It's loading only one texture:
glGenTextures(6, m_Textures);
for(int i = 0 ; i < 1 ; i++)
{
glBindTexture(GL_TEXTURE_2D, m_Textures[i]);
...
If you want to load 6 textures, like the rest of the code suggests, you'll have to use 6 for the end value of the loop:
for(int i = 0 ; i < 6 ; i++)
It's creating texture ids twice, and sets parameters with the wrong texture bound. At the start of LoadTexture(), it generates 6 texture ids:
glGenTextures(6, m_Textures);
and then binds them, and makes glTexParameteri() to set various parameters on them. But then it calls SOIL_load_ogl_texture() with a flag asking it to create a new id again, and then stores that one away:
m_Textures[i] = SOIL_load_OGL_texture(
m_TextureNames[i].c_str(),
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
To fix this, you can omit the gGenTextures() call, and move the code to bind the texture and call glTexParameteri() after the SOIL_load_ogl_texture() call. Also, this uses a flag to generate mipmaps, but sets the texture filters to not use mipmapping.
In the draw function, it loops over the 6 faces, but then draws the entire cube each time:
for (int i=0;i<6;i++)
{
glPushMatrix();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_Textures[i]);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, m_Indices);
glPopMatrix();
}
The second argument to glDrawElements() specifies the number of vertices to be rendered. With the value 36, all vertices will be used (6 sides of the cube, with 2 triangles each, with 3 vertices each.
Also, the glPushMatrix()/glPopMatrix() serves absolutely no purpose. The draw loop should look something like this:
glActiveTexture(GL_TEXTURE0);
for (int i=0;i<6;i++)
{
glBindTexture(GL_TEXTURE_2D, m_Textures[i]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, m_Indices + i * 6);
}
I don't see the depth test being enabled anywhere. Add this to setup():
glEnable(GL_DEPTH_TEST);
I do it a little differently that works, so maybe the issue is in the difference.
I would bind each texture to a different GL_Texture (GL_Texture0, GL_Texture1...) so that each texture has it's own data. I don't know how SOIL works, but in my case for the first texture after:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
I would include a call:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture1Width, texture1Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapData);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_Textures[0]);
And I would repeat this process for each of the 6 textures.
Then I would draw each face:
// First face
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_Textures[0]);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, m_Indices);
// Second face
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_Textures[1]);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, m_Indices);
And so on for each face.
EDIT:
I did some checking about SOIL, and it looks to me like (using SOIL) you would:
GLuint m_Textures[6];
int img_width, img_height;
glGenTextures(6, m_Textures);
// For each texture
unsigned char* img = SOIL_load_image(m_TextureNames[0].c_str(), &img_width, &img_height, NULL, 0); // or m_TextureNames[1].c_str() ...
glBindTexture(GL_TEXTURE_2D, m_Textures[0]); // or m_textures[1]...
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // NOTE the GL_NEAREST Here!
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // NOTE the GL_NEAREST Here!
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img_width, img_height, 0, GL_RGB, GL_UNSIGNED_BYTE, img);
glActiveTexture(GL_TEXTURE0); // or GL_TEXTURE1....
glBindTexture(GL_TEXTURE_2D, m_Textures[0]); // or m_Textures[1]...

Opengl draw to texture.. recursion?

I' experimenting in draw to texture with opengl.
I've found this simple and clear c code that do that (see in the end).
It draws a cube on a texture, and then a cube on the screen using the previous texture. The generated image is a cube with, in the textures, a lot of cube inside a cube inside a cube etc..: it seems a recursion loop.
But why? I was expecting only 2 cubes. And It seems an infinite recursion loop.. where is the actual recursion? and when does it stops?
/* ============================================================================
**
** Demonstration of rendering to texture
** Copyright (C) 2005 Julien Guertault
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** ========================================================================= */
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#define SIZE 256
static unsigned char texture[3 * SIZE * SIZE];
static unsigned int texture_id;
static int window_width = 500;
static int window_height = 500;
/*
** Just a textured cube
*/
void Cube(void)
{
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, -1, 1);
glTexCoord2i(1, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 0); glVertex3f(-1, 1, -1);
glTexCoord2i(0, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 1); glVertex3f( 1, -1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, 1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, -1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, -1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, 1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, 1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, -1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, -1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, 1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, 1);
glEnd();
}
/*
** Function called to update rendering
*/
void DisplayFunc(void)
{
static float alpha = 20;
glLoadIdentity();
glTranslatef(0, 0, -10);
glRotatef(alpha, 1, 0, 0);
glRotatef(20 , 0, 1, 0);
/* Define a view-port adapted to the texture */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, 1, 5, 15);
glViewport(0, 0, SIZE, SIZE);
glMatrixMode(GL_MODELVIEW);
/* Render to buffer */
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Cube();
glFlush();
/* Copy buffer to texture */
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 5, 5, 0, 0, SIZE - 10, SIZE - 10);
/* Render to screen */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, window_width / (float) window_height, 5, 15);
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Cube();
/* End */
glFlush();
glutSwapBuffers();
/* Update again and again */
alpha = alpha + 0.1;
glutPostRedisplay();
}
/*
** Function called when the window is created or resized
*/
void ReshapeFunc(int width, int height)
{
window_width = width;
window_height = height;
glutPostRedisplay();
}
/*
** Function called when a key is hit
*/
void KeyboardFunc(unsigned char key, int x, int y)
{
int foo;
foo = x + y; /* Has no effect: just to avoid a warning */
printf("%d",foo);
if ('q' == key || 'Q' == key || 27 == key)
exit(0);
}
int main(int argc, char **argv)
{
/* Creation of the window */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("Render to texture");
/* OpenGL settings */
glEnable(GL_DEPTH_TEST);
/* Texture setting */
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SIZE, SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, texture);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
/* Declaration of the callbacks */
glutDisplayFunc(&DisplayFunc);
glutReshapeFunc(&ReshapeFunc);
glutKeyboardFunc(&KeyboardFunc);
/* Loop */
glutMainLoop();
/* Never reached */
return 0;
}
/* ========================================================================= */
But why? I was expecting only 2 cubes. And It seems an infinite recursion loop.. where is the actual recursion? and when does it stops?
It's a feedback loop. Small experiment for you: Take a webcam connect it to your computer and let it show a live picture of the webcam. Now point the webcam on the screen so that it looks at the image it produced.
This is kind of what happens here: A cube with a texture is drawn. That picture is now copied to the texture. Then the cube is drawn again, but this time the texture already contains that cube so it's a cube with cubes on it. Also, for your pleasure the same cube is drawn to the screen, but that doesn't feed back.
If you want to have one nesting deep, you must disable texturing when drawing the cube that gets copied to the texture.
Update Code modification that doesn't recurse
void DisplayFunc(void)
{
First render without texture so we don't feed back. Also make the drawing color black, so this will result in a solid black cube on black background.
/* Render to buffer */
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D); /* <<<<<< */
glColor3f(0,0,0); /* <<<<<< */
Cube();
On a side note: For this there should really a frame buffer object be used, instead of relying on the back buffer to not be clobbered (overlapping windows may make it fail the pixel ownership test).
/* Copy buffer to texture */
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 5, 5, 0, 0, SIZE-10, SIZE-10);
/* Render to screen */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, window_width / (float) window_height, 5, 15);
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Reenable texturing and switch color to white so that we can see the texture (or use GL_REPLACE texture mode).
glEnable(GL_TEXTURE_2D);
glColor3f(1,1,1);
Cube();
/* End */
glFlush();
glutSwapBuffers();
/* Update again and again */
alpha = alpha + 0.1;
glutPostRedisplay();
}

Cube drawing opengl, but a confused image of cube is drawn

Hi
I am trying to draw a cube of size 5*5*5 with six diffrent face colors. How ever,I can not see all the faces colored diffrently, all I see is a cube, with confusing colors format.
Some faces are clearly visible, while top face , parallel to zx plane is not visible.
Thanks in advance
void init(void)
{
glClearColor(0,0,0,0);
glShadeModel(GL_FLAT);
}
void DrawCube(void)
{
glLoadIdentity();
gluLookAt(10, 10, 10, 0, 0, 0, 0, 1, 0);
glBegin(GL_QUADS);
//face in xy plane
glColor3f(0.82, 0.41, 0.12);//this the color with which complete cube is drawn.
glVertex3f(0,0 ,0 );
glVertex3f(5, 0, 0);
glVertex3f(5, 5, 0);
glVertex3f(0, 5, 0);
//face in yz plane
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 5);
glVertex3f(0, 5, 0);
glVertex3f(0, 5, 5);
//face in zx plance
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0 );
glVertex3f(0, 0, 5);
glVertex3f(5, 0, 5);
glVertex3f(5, 0, 0);
//|| to xy plane.
glColor3f(0, 0, 1);
glVertex3f(0, 0, 5);
glVertex3f(5, 0, 5);
glVertex3f(5, 5, 5);
glVertex3f(0, 5, 5);
//|| to yz plane
glColor3f(0.73, 0.58, 0.58);
glVertex3f(0,0 ,5 );
glVertex3f(5, 0, 5);
glVertex3f(5, 5, 5);
glVertex3f(0, 5, 5);
//|| to zx plane //this face is not visible. I am not understanding why.
glVertex3f(0.58, 0, 0.82);
glVertex3f(0, 5, 0 );
glVertex3f(0, 5, 5);
glVertex3f(5, 5, 5);
glVertex3f(5, 5, 0);
glEnd();
glFlush();
}
void reshape(int w,int h){
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, 1.5, 20);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv){
glutInit(&argc, argv);//we initizlilze the glut. functions
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(DrawCube);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
//|| to zx plane //this face is not visible. I am not understanding why.
glVertex3f(0.58, 0, 0.82);
You want glColor3f. I'm guessing this is a typo.
Two unrelated things:
Your || to xy plane quad is the same as your || to yz plane quad.
You aren't clearing the color buffer before drawing. You probably want glClear(GL_COLOR_BUFFER_BIT) at the start of DrawCube