Rotating object around itself in OpenGL - c

i'm having trouble rotating a room around itself. its center is at (5,5,0) so i thought if i translated the room and the objects in the room with glTranslatef(5,5,5) then glRotatef(rotateroom,0,0,1) and then draw the items and use glTranslate(-5,-5,0) it would rotate the room and everything in it around 5,5,0 but it seems to still be rotating around (0,0,0) and i'm not really sure what I'm doing wrong. Thanks for the help in advance.
void drawside(){
int i,j;
/*for (j = 0; j <= 8; j++) {
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord2f((GLfloat)i/30.0, (GLfloat)j/8.0);
glEnd();
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord2f((GLfloat)j/8.0, (GLfloat)i/30.0);
glEnd();
}*/
glEvalMesh2(GL_FILL, 0, 20, 0, 20);
}
void drawRoom(){
//floor
glBegin(GL_POLYGON);
glColor3f(1,1,1);
glNormal3f(0,0,0);
glVertex3f(0,0,0);
glNormal3f(0,10,0);
glVertex3f(0,10,0);
glNormal3f(10,10,0);
glVertex3f(10,10,0);
glNormal3f(10,0,0);
glVertex3f(10,0,0);
glEnd(
);
//wall
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glNormal3f(0,10,0);
glVertex3f(0,10,0);
glNormal3f(0,10,10);
glVertex3f(0,10,10);
glNormal3f(10,10,10);
glVertex3f(10,10,10);
glNormal3f(10,10,0);
glVertex3f(10,10,0);
glEnd();
//wall2
glBegin(GL_POLYGON);
glColor3f(0,1,0);
glNormal3f(10,10,0);
glVertex3f(10,10,0);
glNormal3f(10,10,0);
glVertex3f(10,10,10);
glNormal3f(10,0,10);
glVertex3f(10,0,10);
glNormal3f(10,0,0);
glVertex3f(10,0,0);
glEnd();
}
void drawObjects(){
glColor3f(1,0,1);
glTranslatef(2,2,0);
if(conefill == 1)
glShadeModel(GL_FLAT);
else
glShadeModel(GL_SMOOTH);
glutSolidCone(cone,5,10,2);
glTranslatef(5,5,0);
glColor3f(1,0,0);
if(spherefill == 1)
glShadeModel(GL_FLAT);
else
glShadeModel(GL_SMOOTH);
glutSolidSphere(sphere,20,20);
}
void display(){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(viewx,viewy, viewz,viewx +lx, 5, viewz + ly,0.0f, 0.0f, 1.0f);
//gluLookAt(viewx,viewy,viewz,headup,headright,5,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat light_position[] = {-1.0,5.0,5.0,0.0};
//GLfloat light_direction[] = {-5,-5,-5};
//GLfloat amb[] = {0,0,0,1};
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
//glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION,light_direction);
//glLightfv(GL_LIGHT0, GL_AMBIENT,amb);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(5,5,0);
glRotatef(rotateroom,0,0,1);
glPushMatrix();
drawRoom();
glPopMatrix();
glColor3f(0.0, 0.0, 1.0);
glPushMatrix();
glTranslatef(6,3,1);
glPushMatrix ();
drawside();
glPopMatrix();
glPushMatrix();
//glTranslatef(5,0,0);
glRotatef(90,1,0,0);
//glTranslatef(-5,0,0);
glTranslatef(0,.5,.5);
drawside();
glPopMatrix();
glPushMatrix();
//glTranslatef(5,0,0);
glRotatef(180,1,0,0);
//glTranslatef(-5,0,0);
glTranslatef(0,1,0);
drawside();
glPopMatrix();
glPushMatrix();
glRotatef(90,0,0,1);
glTranslatef(-.5,.5,0);
drawside();
glPopMatrix();
glPushMatrix();
glRotatef(270,0,0,1);
glTranslatef(.5,.5,0);
drawside();
glPopMatrix();
glPopMatrix();
drawObjects();
glTranslatef(-5,-5,0);
glPopMatrix();
glutSwapBuffers();
glFlush();
}

You only need to invert the order of the istruction:
glRotatef(rotateroom,0,0,1);
glTranslatef(5,5,0);
Whenever you trasform a point you must invert the sequence of trasformation you want to apply. This dipend on the way the transformation matrix are multiplicated.

Related

OpenGL glPushMatrix() and glPopMatrix in for loop

I'm new to OpenGL, and I'm going to make something like this. And the problem is, the loop seems like invoked only once, but I don't know why it becomes like that.
glDisable(GL_CULL_FACE);
int n = 32;
float angle = 0.0f;
float green = 0.0f;
float blue = 1.0f;
float color = 1.0/n;
glColor3f(0.0, 0.0, 1.0);
glTranslatef(0.0, 5.0, 0.0);
drawArrow();
for(int i = 0; i < n; i++){
green = green + color;
blue = blue - color;
glPushMatrix();
glRotatef(angle+(360/n), 0.0f, 0.0f, 1.0f);
glColor3f(0.0, green, blue);
drawArrow();
glPopMatrix();
}
glEnable(GL_CULL_FACE);
The issue is that all the arrows are drawn with the same orientation.
What you want to do is to step forward the rotation of the arrows by an angle.
The angle for each arrow has to depend on the control variable of the loop (i). The angle between 2 arrows is 360.0/n and the angle of an arrow is 360.0*i/n:
glRotatef(angle+(360/n), 0.0f, 0.0f, 1.0f);
float partAngle = 360.0f * (float)i/(float)n;
glRotatef(angle + partAngle, 0.0f, 0.0f, 1.0f);
An other option would be to use the glPushMatrix / glPopMatrix. Push the matrix after the rotation angle has been set, so the rotation grows up by 360.0f/n in the loop:
glPushMatrix();
for(int i = 0; i < n; i++){
green = green + color;
blue = blue - color;
glRotatef(angle+(360.0f/n), 0.0f, 0.0f, 1.0f);
glPushMatrix();
glColor3f(0.0, green, blue);
drawArrow();
glPopMatrix();
}
glPopMatrix();
for (int i = 0; i < n; i++)
{
green += color;
blue -= color;
angle += 360 / n;
glPushMatrix();
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glColor3f(0.0, green, blue);
drawArrow();
glPopMatrix();
}

OpenGL glBegin and glPushMatrix

I try to design a scene with 3 spheres and one line horizontal as equator. I got to draw the 3 spheres but I don't know why the line is not draw.
This is my code, for if you can see where I'm wrong:
#include <GL/gl.h>
#include <GL/glut.h>
void render(void);
void reshape(int w, int h);
int angle = 90;
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 50);
glutInitWindowSize(800, 600);
glutCreateWindow("Planets");
glutDisplayFunc(render);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
void render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 1);
// Equator
glBegin(GL_LINES);
glColor3f(1,1,1);
glLineWidth(1);
glTranslated(0, 0, 0);
glVertex2f(0, 2);
glVertex2f(2,2);
glEnd();
// Sun
glPushMatrix();
glLoadIdentity();
glColor3f(1.0, 1.0, 0.0);
glTranslated(0, 0, -2);
glRotated(angle, 1, 0, 0);
glutWireSphere(.3, 20, 20);
glPopMatrix();
//Earth
glPushMatrix();
glLoadIdentity();
glColor3f(0.0, 0.0, 1.0);
glTranslated(0.7, 0, -2);
glRotated(angle, 1, 0, 0);
glutWireSphere(.15, 20, 20);
glPopMatrix();
// Moon
glPushMatrix();
glLoadIdentity();
glColor3f(1.0, 0.0, 1.0);
glTranslated(1, 0, -2);
glRotated(angle, 1, 0, 0);
glutWireSphere(.05, 10, 10);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h) {
const double ar = (double) w / (double) h;
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
You specify a frustum that has the near clip plane at z=-2. Your intended line would be drawn at z=0, thus outside the projection volume, thereby clipped into non-rendering.
glTranslate(0,0,0) is a no-op BTW.

Lines and textures will not show up together

Here is how I draw the line and I using mouse to draw the line
static struct
{
GLfloat p[MAX_POINTS][2];
GLuint point_cnt;
} contours [ MAX_CONTOURS ] ;
GLuint point_cnt_mouse;
point_cnt_mouse = contours[contour_cnt].point_cnt;
glColor3f( 0.0, 0.0, 0.0 );
glBegin(GL_LINES);
glLineWidth(5.0);
int i;
int j;
for(i = 0; i <= contour_cnt; i++)
{
GLuint point_cnt;
point_cnt = contours[i].point_cnt;
if (contours[i].point_cnt == 0)
{
glVertex2fv ( P );
glVertex2fv ( P );
}//if
else
{
for(j = 2; j <= point_cnt; j++)
{
glVertex2fv (contours[i].p[j-2]);
glVertex2fv (contours[i].p[j-1]);
}//for
}//else
}//for
if(point_cnt_mouse > 0)
{
glVertex2fv(contours[contour_cnt].p[point_cnt_mouse-1]);
glVertex2fv(P);
}//if
glEnd();
then I use glTexImage2D() to make GL_TEXTURE_2D then
my display is
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix ();
glTranslatef(-4.0, 5.0, -6.0);
//this is box and load texture on it
drawPlane();
glPopMatrix();
glutSwapBuffers();
glFlush();
}
void myinit()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
//load png image
drawLogo();
glDisable(GL_DEPTH_TEST);
}
Logo won't show up with lines, why? Can any one tell what is wrong with my code?
Make sure to disable texturing (glDisable(GL_TEXTURE_2D)) before drawing your line(s). And re-enable (glEnable(GL_TEXTURE_2D)) before drawing your texture.
If you're using the default GL_MODULATE texture environment make sure to set the current color to white (glColor3ub(255,255,255)) before drawing with the texture. If you draw the texture after the glColor3f( 0.0, 0.0, 0.0 ) in your line routine then GL_MODULATE will multiply all your texel RGB values by zero, giving you black everywhere.
It looks kind of suspicious to me that your display() function never calls drawLogo().
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix ();
glTranslatef(-4.0, 5.0, -6.0);
//this is box and load texture on it
drawPlane();
glPopMatrix();
glutSwapBuffers();
glFlush();
}

gluCylinder() how works OpenGL

I wanted to build a cricket ground with OpenGL. I made several polygons to indicate field, pitch and bowling lines. But the problem is when I am trying to use gluCylinder to make stumps I made depth glEnable(GL_DEPTH_TEST), but my polygons are then not working. I just want to know how Can I use gluCylinder to make stumps with those polygons I have made.
I have following code, but want to add stumps here but I cant,
#include <GL/gl.h>
#include <GL/glut.h>
static double deg=0.0;
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glRotatef(deg, 0.0, 0.0, 1.0); // Rotate by deg
// field
glColor3f (0.0, 0.5, 0.0);
glBegin(GL_POLYGON);
glVertex3f (0, 0, 0.0);
glVertex3f (1, 0, 0.0);
glVertex3f (1, 0.75, 0.0);
glVertex3f (0.8, 0.82, 0.0);
glVertex3f (0.6, 0.85, 0.0);
glVertex3f (0.4, 0.85, 0.0);
glVertex3f (0.2, 0.82, 0.0);
glVertex3f (0.0, 0.75, 0.0);
glEnd();
// pitch
glColor3f (0.25, 0.30, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0.5,0.65,0.0);
glVertex3f(0.47,0.35,0.0);
glVertex3f(0.60,0.35,0.0);
glVertex3f(0.57,0.65,0.0);
glEnd();
//ump line
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(0.49,0.63,0.0);
glVertex3f(0.49,0.6315,0.0);
glVertex3f(0.58,0.6315,0.0);
glVertex3f(0.58,0.63,0.0);
glEnd();
//bat line
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(0.46,0.40,0.0);
glVertex3f(0.46,0.4025,0.0);
glVertex3f(0.61,0.4025,0.0);
glVertex3f(0.61,0.40,0.0);
glEnd();
glFlush ();
}
void init (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: // "esc" on keyboard
exit(0);
break;
case 97: // "a" on keyboard
deg = deg+5.0;
glutPostRedisplay();
break;
case 100:
deg = deg-5.0;
glutPostRedisplay();
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (600, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
glEnable(GL_DEPTH_TEST) requires a depth buffer. Make sure to allocate one via oring in GLUT_DEPTH in your glutInitDisplayMode() call.
Make sure to clear your new depth buffer via oring in GL_DEPTH_BUFFER_BIT in your glClear() call.
#include <GL/glut.h>
static double deg=0.0;
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(deg, 0.0, 0.0, 1.0); // Rotate by deg
// field
glColor3f (0.0, 0.5, 0.0);
glBegin(GL_POLYGON);
glVertex3f (0, 0, 0.0);
glVertex3f (1, 0, 0.0);
glVertex3f (1, 0.75, 0.0);
glVertex3f (0.8, 0.82, 0.0);
glVertex3f (0.6, 0.85, 0.0);
glVertex3f (0.4, 0.85, 0.0);
glVertex3f (0.2, 0.82, 0.0);
glVertex3f (0.0, 0.75, 0.0);
glEnd();
// pitch
glColor3f (0.25, 0.30, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0.5,0.65,0.0);
glVertex3f(0.47,0.35,0.0);
glVertex3f(0.60,0.35,0.0);
glVertex3f(0.57,0.65,0.0);
glEnd();
//ump line
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(0.49,0.63,0.0);
glVertex3f(0.49,0.6315,0.0);
glVertex3f(0.58,0.6315,0.0);
glVertex3f(0.58,0.63,0.0);
glEnd();
//bat line
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(0.46,0.40,0.0);
glVertex3f(0.46,0.4025,0.0);
glVertex3f(0.61,0.4025,0.0);
glVertex3f(0.61,0.40,0.0);
glEnd();
glPopMatrix();
glFlush ();
}
void init (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: // "esc" on keyboard
exit(0);
break;
case 'a': // "a" on keyboard
deg = deg+5.0;
glutPostRedisplay();
break;
case 'z':
deg = deg-5.0;
glutPostRedisplay();
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Be aware that GL_POLYGON only supports convex polygons.

OpenGL: smudges drawn on image surfaces

I am trying to code an interface to a rubik's cube.
However when I draw it there are smudges on the faces of the cube:
Here is the well-commented code. Can someone please help me and perhaps run the code and tell me where I might be going wrong?
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
void init() {
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
}
static float x_degs = 0.0f;
static float y_degs = 0.0f;
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 'q':
exit(EXIT_SUCCESS);
case 'h':
y_degs -= 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
case 'j':
x_degs -= 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
case 'k':
x_degs += 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
case 'l':
y_degs += 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
}
}
// half the length of one card
static const float card_half_size = 1.0f;
// half the space between cards
static const float space_half_size = 0.1f;
// number of cards per face
static const int NUM_CARDS_PER_FACE = 4;
/*
// start position of center of top left card
const float start = - 3 * (card_half_size + space_half_size);
// increment between center of cards
const float incr = 2 * (card_half_size + space_half_size);
// half the size of a cube face
const float cube_half_size = 4 * (card_half_size + space_half_size);
*/
// draw a card centered at the origin
void draw_card() {
glBegin(GL_QUADS);
glVertex3f(- card_half_size, - card_half_size, 0.0f);
glVertex3f(- card_half_size, card_half_size, 0.0f);
glVertex3f(card_half_size, card_half_size, 0.0f);
glVertex3f(card_half_size, - card_half_size, 0.0f);
glEnd();
}
// draw a cube face made up of cards
void draw_card_face() {
const float cube_half_size = 4 * (card_half_size + space_half_size);
const float start = - 3 * (card_half_size + space_half_size);
const float incr = 2 * (card_half_size + space_half_size);
glColor3f(0.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f(- cube_half_size, - cube_half_size, -0.001f);
glVertex3f(- cube_half_size, cube_half_size, -0.001f);
glVertex3f(cube_half_size, cube_half_size, -0.001f);
glVertex3f(cube_half_size, - cube_half_size, -0.001f);
glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
for (int i = 0; i < NUM_CARDS_PER_FACE; i++)
for (int j = 0; j < NUM_CARDS_PER_FACE; j++) {
glPushMatrix();
glTranslatef(start + i * incr, start + j * incr, 0.0f);
draw_card();
glPopMatrix();
}
}
// draw a cube made up of cards
void draw_card_cube() {
const float cube_half_size = 4 * (card_half_size + space_half_size);
// front face
glPushMatrix();
glTranslatef(0.0f, 0.0f, cube_half_size);
draw_card_face();
glPopMatrix();
// back face
glPushMatrix();
glTranslatef(0.0f, 0.0f, - cube_half_size);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
draw_card_face();
glPopMatrix();
// right face
glPushMatrix();
glTranslatef(cube_half_size, 0.0f, 0.0f);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
draw_card_face();
glPopMatrix();
// left face
glPushMatrix();
glTranslatef(- cube_half_size, 0.0f, 0.0f);
glRotatef(- 90.0f, 0.0f, 1.0f, 0.0f);
draw_card_face();
glPopMatrix();
// top face
glPushMatrix();
glTranslatef(0.0f, cube_half_size, 0.0f);
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
draw_card_face();
glPopMatrix();
// bottom face
glPushMatrix();
glTranslatef(0.0f, - cube_half_size, 0.0f);
glRotatef(- 90.0f, 1.0f, 0.0f, 0.0f);
draw_card_face();
glPopMatrix();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(x_degs, 1.0f, 0.0f, 0.0f);
glRotatef(y_degs, 0.0f, 1.0f, 0.0f);
gluLookAt(-0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
draw_card_cube();
glutSwapBuffers();
}
void reshape(int w, int h) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15.0f, 15.0f, -15.0f, 15.0f, -15.0f, 15.0f);
glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow(argv[0]);
init();
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
OK, I have revised the code so that I draw th cyan rectangles 0.01f units behind instead of 0.001f units behind and this seems to have fixed the z-fighting. However I would have liked to use glPolygonOffset(factor, units) to fix this problem but I was unable to do it, for the following
reasons:
I don't know how to set facor and units (I've tried 1.0 for both).
I've tried different values to no outcome.
Here is the code without the bleeding/stitching/z-fighting:
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
void init() {
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
}
static float x_degs = 0.0f;
static float y_degs = 0.0f;
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 'q':
exit(EXIT_SUCCESS);
case 'h':
y_degs -= 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
case 'j':
x_degs -= 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
case 'k':
x_degs += 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
case 'l':
y_degs += 1.0f;
glutPostRedisplay();
glutSwapBuffers();
break;
}
}
// half the length of one card
static const float card_half_size = 1.0f;
// half the space between cards
static const float space_half_size = 0.1f;
// number of cards per face
static const int NUM_CARDS_PER_FACE = 4;
/*
// start position of center of top left card
const float start = - 3 * (card_half_size + space_half_size);
// increment between center of cards
const float incr = 2 * (card_half_size + space_half_size);
// half the size of a cube face
const float cube_half_size = 4 * (card_half_size + space_half_size);
*/
// draw a card centered at the origin
void draw_card() {
glBegin(GL_QUADS);
glVertex3f(- card_half_size, - card_half_size, 0.0f);
glVertex3f(- card_half_size, card_half_size, 0.0f);
glVertex3f(card_half_size, card_half_size, 0.0f);
glVertex3f(card_half_size, - card_half_size, 0.0f);
glEnd();
}
// draw a cube face made up of cards
void draw_card_face() {
const float cube_half_size = 4 * (card_half_size + space_half_size);
const float start = - 3 * (card_half_size + space_half_size);
const float incr = 2 * (card_half_size + space_half_size);
glColor3f(0.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f(- cube_half_size, - cube_half_size, -0.001f);
glVertex3f(- cube_half_size, cube_half_size, -0.001f);
glVertex3f(cube_half_size, cube_half_size, -0.001f);
glVertex3f(cube_half_size, - cube_half_size, -0.001f);
glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
for (int i = 0; i < NUM_CARDS_PER_FACE; i++)
for (int j = 0; j < NUM_CARDS_PER_FACE; j++) {
glPushMatrix();
glTranslatef(start + i * incr, start + j * incr, 0.0f);
draw_card();
glPopMatrix();
}
}
// draw a cube made up of cards
void draw_card_cube() {
const float cube_half_size = 4 * (card_half_size + space_half_size);
// front face
glPushMatrix();
glTranslatef(0.0f, 0.0f, cube_half_size);
draw_card_face();
glPopMatrix();
// back face
glPushMatrix();
glTranslatef(0.0f, 0.0f, - cube_half_size);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
draw_card_face();
glPopMatrix();
// right face
glPushMatrix();
glTranslatef(cube_half_size, 0.0f, 0.0f);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
draw_card_face();
glPopMatrix();
// left face
glPushMatrix();
glTranslatef(- cube_half_size, 0.0f, 0.0f);
glRotatef(- 90.0f, 0.0f, 1.0f, 0.0f);
draw_card_face();
glPopMatrix();
// top face
glPushMatrix();
glTranslatef(0.0f, cube_half_size, 0.0f);
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
draw_card_face();
glPopMatrix();
// bottom face
glPushMatrix();
glTranslatef(0.0f, - cube_half_size, 0.0f);
glRotatef(- 90.0f, 1.0f, 0.0f, 0.0f);
draw_card_face();
glPopMatrix();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(x_degs, 1.0f, 0.0f, 0.0f);
glRotatef(y_degs, 0.0f, 1.0f, 0.0f);
gluLookAt(-0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
draw_card_cube();
glutSwapBuffers();
}
void reshape(int w, int h) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15.0f, 15.0f, -15.0f, 15.0f, -15.0f, 15.0f);
glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow(argv[0]);
init();
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
I think you're drawing your checkers as coplanar quads of the faces of your main cube ; if this is the case, the problem you encounter is called "z fighting".
You can take a look at point 12.040 Depth buffering seems to work, but polygons seem to bleed through polygons that are in front of them. What's going on? here :
http://www.opengl.org/resources/faq/technical/depthbuffer.htm
Basically, your depth buffer does not have enough precision to resolve which quad to display for each pixel, causing the problem.
You can either manually add an offset to your checker quads, to move them away from the cube ; or use depth bias through glPolygonOffset to solve the issue.
I think you're trying to do coplanar rendering. Look into glPolygonOffset() instead of using small Z offsets like you do.
This is what I get from your code, compiled with gcc -std=c99 -lGL -lGLU -lglut a.c: no smudges. Can you post yours? (Ubuntu 11.10, Intel GPU)

Resources