Related
I am trying to create a model using OpenGL, and I tried to enable depth testing.
I use these commands in my main:
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glEnable(GL_DEPTH_TEST);
And this in my display:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
I even tried adding:
glDepthFunc(GL_LEQUAL);
And it doesn't work. I can still see what I think are depth problems.
Here is a video showing the problem: https://www.youtube.com/watch?v=OafrRH4Mzjc
Note: In that video, the board is build right to left, top to bottom, so the first angle is OK, but any other angle is bad.
What am I missing?
Edit: Minimal example file of reproduction:
#define _CRT_SECURE_NO_WARNINGS
#define SIZE_MOVES 17
#include <stdio.h>
/* Include the GLUT library. This file (glut.h) contains gl.h and glu.h */
#include <GL\glew.h>
#include <GL\freeglut.h>
static int left_click = GLUT_UP;
static int right_click = GLUT_UP;
static int xold;
static int yold;
static float rotate_x = 146;
static float rotate_y = -26;
int width, height;
GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 0, 5, -10, 0 };
GLfloat mat_specular[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat mat_shininess[] = { 1 };
// colors
const GLfloat colors[2][4] = {
{ 1.0, 1.0, 1.0, 1.0 }, //white
{ 0.0, 0.0, 0.0, 1.0 } //black
};
// rgb
const GLfloat rgb[3][4] = {
{ 1.0, 0.0, 0.0, 1.0 },
{ 0.0, 1.0, 0.0, 1.0 },
{ 0.0, 0.0, 1.0, 1.0 }
};
void resetMaterial() {
GLfloat c[] = { 1, 1, 1, 1 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, c);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}
void drawSquare(int color) {
glPushMatrix(); {
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, colors[color]);
glScalef(1, 0.5, 1);
glutSolidCube(1);
} glPopMatrix();
}
void drawBoard() {
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++) {
glPushMatrix(); {
glTranslatef(i + 0.5, 0, j + 0.5);
drawSquare((i + j) % 2);
} glPopMatrix();
}
}
void drawAxes() {
glBegin(GL_LINES); {
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgb[0]);
glVertex3f(-2, 0, 0); glVertex3f(5, 0, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgb[1]);
glVertex3f(0, -2, 0); glVertex3f(0, 5, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgb[2]);
glVertex3f(0, 0, -2); glVertex3f(0, 0, 5);
} glEnd();
}
void letThereBeLight() {
/*Add ambient light*/
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
/*Add positioned light*/
GLfloat lightColor1[] = { 0.2f, 0.2f, 0.1f, 1.0f };
GLfloat lightPosition1[] = { -8, 8, 5, 0.0f };
glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor1);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition1);
/*Add directed light*/
GLfloat lightColor2[] = { 0.3, 0.3, 0.3, 1.0f };
GLfloat lightPosition2[] = { 8, 8, -5, 1.0f };
glLightfv(GL_LIGHT1, GL_AMBIENT, lightColor2);
glLightfv(GL_LIGHT1, GL_POSITION, lightPosition2);
}
void display(void) {
// Clear frame buffer and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set up viewing transformation, looking down -Z axis
glLoadIdentity();
gluLookAt(0, 5, -15, 0, 0, 3, 0, 1, 0);
letThereBeLight();
resetMaterial();
// Rotate view:
glPushMatrix(); {
glRotatef(rotate_y, 1, 0, 0);
glRotatef(rotate_x, 0, 1, 0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, colors[0]);
glPushMatrix(); {
glTranslatef(-4, 0, -4); // Move to center
drawBoard();
} glPopMatrix();
drawAxes(); // For debuging
} glPopMatrix();
/* End */
glFlush();
glutSwapBuffers();
}
void mouseFunc(int button, int state, int x, int y) {
if (GLUT_LEFT_BUTTON == button)
left_click = state;
xold = x;
yold = y;
}
void motionFunc(int x, int y) {
if (GLUT_DOWN == left_click) {
rotate_y = rotate_y + (y - yold) / 5.f;
rotate_x = rotate_x + (x - xold) / 5.f;
glutPostRedisplay();
}
xold = x;
yold = y;
}
void reshapeFunc(int new_width, int new_height) {
width = new_width;
height = new_height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50, width / height, 1, 20);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
int main(int argc, char **argv) {
/* Creation of the window */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(900, 600);
glEnable(GL_DEPTH_TEST);
glutCreateWindow("Chess");
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glShadeModel(GL_SMOOTH);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Declaration of the callbacks */
glutDisplayFunc(&display);
glutReshapeFunc(&reshapeFunc);
glutMouseFunc(&mouseFunc);
glutMotionFunc(&motionFunc);
/* Loop */
glutMainLoop();
/* Never reached */
return 0;
}
gluPerspective(50, width / height, 0, 20);
^ wat
zNear needs to be greater than zero (emphasis mine):
Depth buffer precision is affected by the values specified for zNear
and zFar. The greater the ratio of zFar to zNear is, the less
effective the depth buffer will be at distinguishing between surfaces
that are near each other.
If r = zFar / zNear roughtly log2(r) bits of depth buffer
precision are lost. Because r approaches infinity as zNear approaches 0, zNear must never be set to 0.
EDIT: Given the newly-posted MCVE:
int main(int argc, char **argv) {
/* Creation of the window */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(900, 600);
glEnable(GL_DEPTH_TEST); // too soon
glutCreateWindow("Chess");
...
}
It's just like datenwolf said: You're glEnable()ing before you have a current GL context (glutCreateWindow() creates the context and makes it current).
Don't call any gl*() functions until after glutCreateWindow().
public void onSurfaceChanged(int w, int h)
{
Matrix.frustumM(projectionMatrix,0,-(9f/18.5f),(9f/18.5f),-1f,1f,1.0f,1000f);
}
I had to change my near clipping form 0.01f to 1.0f.
I have been trying to make a whale in OpenGL. We have been trying to move the whale using a mouse input. The problem we are facing is with the syntax as well as the logic. We understand that the whale we are making is in a 3 dimensional world whereas the mouse input in in 2D for x and y on the screen.
If someone can be very specific with the syntax of using mouse input relevant to our code, that'd be great!
#include <Windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include "glut.h"
#include <math.h>
GLUquadric *qobja;
float movez = 0;
#define W_SCREEN 1366
#define H_SCREEN 768
#define TERR_D 75
#define TERR_W 750
#define pi 3.14
int mou_x = 0, mou_y = 0;
float alpha = 0;
float fahad = 0;
GLfloat ctrlpoints[4][4][3] = {
{ { -1.5, -1.5, 4.0 },
{ -0.5, -1.5, 2.0 },
{ 0.5, -1.5, -1.0 },
{ 1.5, -1.5, 2.0 } },
{ { -1.5, -0.5, 1.0 },
{ -0.5, -0.5, 3.0 },
{ 0.5, -0.5, 0.0 },
{ 1.5, -0.5, -1.0 } },
{ { -1.5, -1.5, 4.0 },
{ -0.5, -1.5, 2.0 },
{ 0.5, -1.5, -1.0 },
{ 1.5, -1.5, 2.0 } },
{ { -1.5, 1.5, -2.0 },
{ -0.5, 1.5, -2.0 },
{ 0.5, 1.5, 0.0 },
{ 1.5, 1.5, -1.0 } }
};
float cam_xrot = 180, cam_yrot = 180, cam_zrot = 0;
GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat no_shininess[] = { 0.0 };
GLfloat low_shininess[] = { 5.0 };
GLfloat high_shininess[] = { 100.0 };
GLfloat mat_emission[] = { 0.3, 0.2, 0.2, 0.0 };
// Function Prototypes ////////////////////////////////////
void drawTerrain();
void drawAxes();
//drawing function decs
void draw_frust(float inner, float outer, float height, float m_z);
void cleanup();
void camera();
void pyramid();
void draw_closed_cyl(float a, float b, float c);
void draw_whale();
/* Initialize z-buffer, projection matrix, light source,
* and lighting model. Do not specify a material property here.
*/
void initLight(void)
{
GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat position[] = { 0.0, 0.0, 2.0, 1.0 };
GLfloat mat_diffuse[] = { 0.6, 0.6, 0.6, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
0, 1, 12, 4, &ctrlpoints[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);
glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
initLight();
}
///////////////////////////////////////////////////////////
void display(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera();
drawAxes();
qobja = gluNewQuadric();
gluQuadricNormals(qobja, GLU_SMOOTH);
glPushMatrix();
glTranslatef(0, 0, movez);
draw_whale();
glPopMatrix();
}
void draw_whale()
{
glPushMatrix();
glTranslatef(0, 2, 90);
glRotatef(180, 0.0, 0.0, 1.0);
glScalef(1, 1, 2);
glEvalMesh2(GL_FILL, 0, 25, 0, 25);
glPopMatrix();
glPushMatrix();
float count = 5;
float a = 5;
for (float i = 0; i <= 16; i = i + 1)
{
draw_frust(a*sqrt(i), a*sqrt((i + 1)), 2, count * 2);
count++;
alpha = i + 1;
}
//a few smooth runs
for (int j = 0; j < 3; j++)
{
draw_frust(a*sqrt(alpha), a*sqrt(alpha), 2, count * 2);
count++;
}
float co = count;
for (float i = 17; i >= 3; i = i - 1)
{
draw_frust(a*sqrt(i), a*sqrt(i - 1), 2, co * 2);
co++;
fahad = a*sqrt(i - 1);
}
draw_frust(7.07, 5, 2, co * 2);
co++;
draw_frust(5, 3, 2, co * 2);
co++;
draw_frust(3, 1, 2, co * 2);
glPushMatrix();
//fin left
glPushMatrix();
glTranslatef(-25.5, 10, 25);
glRotatef(100, 1, 0, 0);
glRotatef(135, 0, 1, 0);
glRotatef(45, 0, 0, 1);
glScalef(1, 6, 1);
draw_closed_cyl(0, 0, 0);
glPopMatrix();
//fin right
glPushMatrix();
glTranslatef(25.5, 10, 25);
glRotatef(100, 1, 0, 0);
glRotatef(-135, 0, 1, 0);
glRotatef(-45, 0, 0, 1);
glScalef(1, 6, 1);
draw_closed_cyl(0, 0, 0);
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
void draw_frust(float inner, float outer, float height, float m_z)
{
qobja = gluNewQuadric();
gluQuadricNormals(qobja, GLU_SMOOTH);
glPushMatrix();
glTranslatef(0, 0, m_z);
gluDisk(qobja, 0.0, inner, 200, 20);
gluCylinder(qobja, inner, outer, height, 200, 200);
glPopMatrix();
}
void draw_closed_cyl(float a, float b, float c)
{
qobja = gluNewQuadric();
gluQuadricNormals(qobja, GLU_SMOOTH);
glPushMatrix();
glTranslatef(a, b + 2, c);
glRotatef(120, 0, 0, 1);
gluCylinder(qobja, 3.0, 3.0, 2.0, 20, 20);
gluDisk(qobja, 0, 3.0, 20, 20);
glTranslatef(0, 0, 2.0);
gluDisk(qobja, 0, 3.0, 20, 20);
glPopMatrix();
}
void drawTerrain(){
GLfloat color[] = { 0.2, 0.8, 0.2 };
glMaterialfv(GL_FRONT, GL_AMBIENT, color);
glColor3f(0.2, 0.8, 0.2); // this line is not needed when lighting in enabled
glPushMatrix();
glTranslatef(-TERR_W / 2, 0.0, -TERR_D / 2);
glBegin(GL_POLYGON);
glVertex3f(0, 0, 0);
glVertex3f(TERR_W, 0, 0);
glVertex3f(TERR_W, 0, TERR_D);
glVertex3f(0, 0, TERR_D);
glVertex3f(0, 0, 0);
glEnd();
glPopMatrix();
}
void drawAxes(){
glColor3d(1, 0, 0);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(3, 0, 0);
glEnd();
glColor3d(0, 1, 0);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(0, 3, 0);
glEnd();
glColor3d(0, 0, 1);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 3);
glEnd();
}
///////////////////////////////////////////////////////////
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(1.5*60.0, (GLfloat)w / (GLfloat)h, 1, 1.5*120.0);
glMatrixMode(GL_MODELVIEW);
camera();
}
///////////////////////////////////////////////////////////
void camera(){
glLoadIdentity();
glTranslatef(0, 0, -110);
glRotatef(cam_xrot, 1, 0, 0);
glRotatef(cam_yrot, 0, 1, 0);
glRotatef(cam_zrot, 0, 0, 1);
}
///////////////////////////////////////////////////////////
void keyboard(unsigned char key, int x, int y)
{
// Camera controls - Rotation along principle axis
switch (key) {
case 'n':
if (movez <= -100)
movez = movez + 100;
else
movez = movez - 3;
break;
case 'q':
cam_xrot += 10;
if (cam_xrot >360) cam_xrot -= 360;
break;
case 'z':
cam_xrot -= 10;
if (cam_xrot < -360) cam_xrot += 360;
break;
case 'a':
cam_yrot += 10;
if (cam_yrot >360) cam_yrot -= 360;
break;
case 'd':
cam_yrot -= 10;
if (cam_yrot < -360) cam_yrot += 360;
break;
case 'w':
cam_zrot += 10;
if (cam_zrot >360) cam_zrot -= 360;
break;
case 'x':
cam_zrot -= 10;
if (cam_zrot < -360) cam_zrot += 360;
break;
case 27:
cleanup();
exit(0);
break;
default:
break;
}
glutPostRedisplay();
}
///////////////////////////////////////////////////////////
void cleanup() // call once when you exit program
{
}
///////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(W_SCREEN, H_SCREEN);
glutInitWindowPosition(0, 0);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(25, update, 0);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
I am trying to make a motorcycle with primitive shapes. For some reason, the shapes that I have made are see-through. I am not specifying any alpha anywhere; here is my code:
#include <GL/glut.h>
#include <math.h>
GLUquadricObj *quadratic;
static int isWire = 0; // Is wireframe?
static int distance = 10;
static float angleH = 0;
static float angleV = 0;
static float R = 2.0; // Radius of hemisphere.
static int p = 4; // Number of longitudinal slices.
static int q = 6; // Number of latitudinal slices.
#define PI 3.14159265358979324
static unsigned int pipe, seat, cover, wheel, wheelCenter, cycles; // parts of the motorcycle to make as display lists.
GLUquadricObj *cylinder;
void drawCoordinates();
void drawMotorcycle();
void drawTrailer();
void drawHemisphere();
void drawCylinder(float x, float y, float z);
void drawHandle(float x, float y, float z);
void drawLight();
void drawBase();
void setup();
void display () {
/* clear window */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(distance*cos(angleH), distance*cos(angleV), distance*sin(angleH), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
/* future matrix manipulations should affect the modelview matrix */
glMatrixMode(GL_MODELVIEW);
if (isWire) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPushMatrix();
drawCoordinates();
glPushMatrix();
glTranslatef(0.0, 0.0, 0.0); // Move the motorcycle around the world space
drawMotorcycle();
drawTrailer();
glPopMatrix();
glPopMatrix();
/* flush drawing routines to the window */
glFlush();
}
void drawCoordinates()
{
/***************** DRAW AXIS *****************/
glPushMatrix();
GLUquadricObj *xAxis;
xAxis=gluNewQuadric();
glColor3f(1,0,0);
glRotatef(-90, 0, 1, 0);
gluCylinder(xAxis,0.05,0.05,1,5,5);
glPopMatrix();
glPushMatrix();
GLUquadricObj *yAxis;
yAxis=gluNewQuadric();
glColor3f(0,1,0);
glRotatef(-90, 1, 0, 0);
gluCylinder(yAxis,0.05,0.05,1,5,5);
glPopMatrix();
glPushMatrix();
GLUquadricObj *zAxis;
zAxis=gluNewQuadric();
glColor3f(0,0,1);
gluCylinder(zAxis,0.05,0.05,1,5,5);
glPopMatrix();
/***************** END OF DRAW AXIS *****************/
}
void drawMotorcycle()
{
//DRAW ENGINE
glPushMatrix();
//drawCoordinates();
glColor3f(.6, 0, 0);
glScalef(1.4, 0.8, 1.0);
glutSolidSphere(1,8,8);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
//DRAW PIPES UNDER ENGINE
glPushMatrix();
glRotatef(-90, 1, 0, 0);
glRotatef(80, 0, 1, 0);
glTranslatef(0.5, 1.0, -1.5);
glCallList(pipe);
glTranslatef(0.0, -2.0, 0.0);
glCallList(pipe);
glPopMatrix();
//DRAW SEAT
glPushMatrix();
glPushMatrix();
glRotatef(15, 0, 0, 1);
glTranslatef(-2.0, -0.4, 0.0);
glScalef(2.0, 0.2, 1.2);
glCallList(seat);
glPopMatrix();
//DRAW BACK SEAT
glRotatef(-40, 0, 0, 1);
glTranslatef(-2.3, -2.8, 0.0);
glScalef(2.0, 0.2, 1.2);
glCallList(seat);
glPopMatrix();
//DRAW FRONT PLATE
glPushMatrix();
glRotatef(120, 0, 0, 1);
glTranslatef(0.8, -1.3, 0.0);
glScalef(2.0, 0.2, 1.35);
glColor3f(0.5,0.0,0.0);
glutSolidCube(1);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
//DRAW FRONT PIPES
glPushMatrix();
glRotatef(-90, 1, 0, 0);
glRotatef(-30, 0, 1, 0);
glTranslatef(1.3, -0.9, -5.7);
glScalef(1.0, 1.0, 2.5);
glCallList(pipe);
glTranslatef(0.0, 1.7, 0.0);
glCallList(pipe);
glPopMatrix();
//DRAW WHEEL COVERS
glPushMatrix();
glTranslatef(3.5, -3.0, 0.0);
glScalef(1.0, 0.5, 1.0);
glRotatef(45, 0, 0, 1);
glCallList(cover);
glTranslatef(-5.5, 0.0, 0.0);
glRotatef(-100, 0, 0, 1);
glTranslatef(-8.5, 0.2, 0.0);
glCallList(cover);
glPopMatrix();
//DRAW WHEELS
glPushMatrix();
glTranslatef(3.9, -4.1, 0.0);
glCallList(wheel);
glTranslatef(-9.2, 2.0, 0.0);
glCallList(wheel);
glPopMatrix();
//DRAW WHEEL CENTER PIECES
glPushMatrix();
glTranslatef(3.9, -4.1, 0.0);
glCallList(wheelCenter);
glTranslatef(-9.2, 2.0, 0.0);
glCallList(wheelCenter);
glPopMatrix();
//DRAW CYCLES AROUND WHEELS
glPushMatrix();
glTranslatef(3.9, -4.1, 0.0);
glRotatef(-90, 1, 0, 0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glTranslatef(-9.2, 0.0, 2.0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glPopMatrix();
//DRAW HANDLE BARS
glPushMatrix();
glTranslatef(0.2, 2.0, 0.0);
glRotatef(-45, 1, 0, 0);
glScalef(0.7, 0.7, 0.7);
glCallList(pipe);
glRotatef(-90, 1, 0, 0);
glCallList(pipe);
glPopMatrix();
//DRAW LIGHT
glPushMatrix();
glTranslatef(1.0, 1.0, 0.0);
glColor3f(0.5, 0.5, 0.0);
//glScalef(1.0, 0.5, 1.0);
glutSolidSphere(0.5, 5, 5);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
//DRAW BASE
glPushMatrix();
glRotatef(10.0, 0.0, 0.0, 1.0);
glScalef(3.5, 1.5, 1.0);
glTranslatef(-0.4, -1.0, 0.0);
glColor3f(0.3, 0.3, 0.3);
glutSolidCube(1);
glPopMatrix();
//GAS TANK
glPushMatrix();
glScalef(2.5, 1.0, 0.8);
glTranslatef(-0.8, -1.7, -1.4);
glCallList(pipe);
glPopMatrix();
}
void drawTrailer()
{
//DRAW BODY
glPushMatrix();
glColor3f(0.0, 0.0, 0.3);
glScalef(2.0, 2.5, 1.5);
glTranslatef(-4.5, -0.5, 0.0);
glutSolidCube(1);
glPopMatrix();
//DRAW WHEELS
glPushMatrix();
glPushMatrix();
glScalef(0.8, 0.8, 0.8);
glTranslatef(-12.0, -1.5, 2.0);
glCallList(wheel);
glCallList(wheelCenter);
glRotatef(90, 1, 0, 0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glPopMatrix();
glPushMatrix();
glScalef(0.8, 0.8, 0.8);
glTranslatef(-12.0, -1.5, -2.0);
glCallList(wheel);
glCallList(wheelCenter);
glRotatef(90, 1, 0, 0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glPopMatrix();
glPopMatrix();
//DRAW CONNECTION TO MOTORCYCLE
glPushMatrix();
glRotatef(90, 0, 1, 0);
glTranslatef(0.0, -1.0, -8.0);
glCallList(pipe);
glPopMatrix();
}
void drawHemisphere()
{
for(int j = 0; j < q; j++)
{
// One latitudinal triangle strip.
glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i <= p; i++)
{
glVertex3f( R * cos( (float)(j+1)/q * PI/2.0 ) * cos( 2.0 * (float)i/p * PI ),
R * sin( (float)(j+1)/q * PI/2.0 ),
R * cos( (float)(j+1)/q * PI/2.0 ) * sin( 2.0 * (float)i/p * PI ) );
glVertex3f( R * cos( (float)j/q * PI/2.0 ) * cos( 2.0 * (float)i/p * PI ),
R * sin( (float)j/q * PI/2.0 ),
R * cos( (float)j/q * PI/2.0 ) * sin( 2.0 * (float)i/p * PI ) );
}
glEnd();
}
}
void reshape (int w, int h)
{
// (Window of width = zero is not possible).
if(h == 0)
h = 1;
float ratio = 1.0* w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
gluPerspective(90,ratio,-1,1);
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 'c' : distance = 10; angleH=0; angleV=0.0; break;
case 'C' : distance = 10; angleH=0; angleV=0.0; break;
case 'f': distance = (distance == 4)? 4:distance-1; break;
case 'F': distance = (distance == 4)? 4:distance-1; break;
case 'b': distance = (distance == 20)? 20:distance+1; break;
case 'B': distance = (distance == 20)? 20:distance+1; break;
case 'w': if (isWire == 0) isWire = 1; else isWire = 0; break;
case 'W': if (isWire == 0) isWire = 1; else isWire = 0; break;
//case 27: exit(0); break;
default: break;
}
}
void specialKeyboard(int key, int x, int y) {
switch (key)
{
case GLUT_KEY_RIGHT:
angleH -= .2;
break;
case GLUT_KEY_LEFT:
angleH += .2;
break;
case GLUT_KEY_UP:
angleV += .2;
break;
case GLUT_KEY_DOWN:
angleV -= .2;
break;
}
}
void update(void){
glutPostRedisplay();
}
void setup()
{
// PARTS
pipe = glGenLists(1);
seat = glGenLists(1);
cover = glGenLists(1);
wheel = glGenLists(1);
wheelCenter = glGenLists(1);
cycles = glGenLists(1);
glNewList(pipe, GL_COMPILE); // Any cylinder on the motorcycle
GLUquadricObj *cylinder;
cylinder=gluNewQuadric();
glPushMatrix();
glColor3f(.5,.5,.5);
gluCylinder(cylinder,0.2,0.2,3,5,5);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(seat, GL_COMPILE);
glPushMatrix();
glColor3f(0.5, 0.35, 0.05);
glutSolidCube(1);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(cover, GL_COMPILE);
glPushMatrix();
glColor3f(0.5, 0.0, 0.0);
drawHemisphere();
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(wheel, GL_COMPILE);
glPushMatrix();
glColor3f(0.1, 0.1, 0.1);
glutSolidTorus(0.2, 1.2, 20, 20);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(wheelCenter, GL_COMPILE);
glPushMatrix();
glColor3f(0.4, 0.5, 0.5);
glScalef(1.0, 0.5, 1.0);
glutSolidSphere(0.8, 5, 5);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(cycles, GL_COMPILE);
glColor3f(0.5, 0.5, 0.5);
glScalef(0.25, 0.25, 0.25);
cylinder=gluNewQuadric();
gluCylinder(cylinder,0.5,0.5,5,15,5);
glEndList();
}
int main (int argc, char** argv) {
/* initialize GLUT, using any commandline parameters passed to the
program */
glutInit(&argc,argv);
/* setup the size, position, and display mode for new windows */
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH );
/* create and set up a window */
glutCreateWindow("Motorcycle");
setup(); // Build all the display lists, ready to use
glutIdleFunc(update);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyboard);
/* set up depth-buffering */
glEnable(GL_DEPTH_TEST);
/* background color */
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
/* tell GLUT to wait for events */
glutMainLoop();
return 0;
}
You can rotate the camera with the arrow keys to see that the objects are see through. How can I fix this? Is there anything else I can do to improve my code?
In reshape():
// Set the correct perspective.
gluPerspective(90,ratio,-1,1);
I'm guessing you transliterated parameters from a glOrtho() call, where a negative zNear is perfectly legitimate.
From the gluPerspective() docs:
zNear: Specifies the distance from the viewer to the near clipping plane (always positive).
Try this:
gluPerspective(90,ratio,1,100);
You need to add glEnable(GL_DEPTH_TEST); to your initialization function.
i need to draw street lights, but it is illuminating the entire environment, i couldnt make it seem like a spot light. The code below is the one i tried
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0) ;
GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat position[4] = {SCREEN_W/2,SCREEN_H/2,0.0,0.0};
float LightDir[3] = {0.0f, 0.0f, -1.0f}; // towards the viewer
glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, 30);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, LightDir);
glLightfv(GL_LIGHT0, GL_DIFFUSE, color);
Like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h>
/* Some <math.h> files do not define M_PI... */
#ifndef M_PI
#define M_PI 3.14159265
#endif
#define TWO_PI (2*M_PI)
typedef struct lightRec {
float amb[4];
float diff[4];
float spec[4];
float pos[4];
float spotDir[3];
float spotExp;
float spotCutoff;
float atten[3];
float trans[3];
float rot[3];
float swing[3];
float arc[3];
float arcIncr[3];
} Light;
static int useSAME_AMB_SPEC = 1;
/* *INDENT-OFF* */
static float modelAmb[4] = {0.2, 0.2, 0.2, 1.0};
static float matAmb[4] = {0.2, 0.2, 0.2, 1.0};
static float matDiff[4] = {0.8, 0.8, 0.8, 1.0};
static float matSpec[4] = {0.4, 0.4, 0.4, 1.0};
static float matEmission[4] = {0.0, 0.0, 0.0, 1.0};
/* *INDENT-ON* */
#define NUM_LIGHTS 3
static Light spots[] =
{
{
{0.2, 0.0, 0.0, 1.0}, /* ambient */
{0.8, 0.0, 0.0, 1.0}, /* diffuse */
{0.4, 0.0, 0.0, 1.0}, /* specular */
{0.0, 0.0, 0.0, 1.0}, /* position */
{0.0, -1.0, 0.0}, /* direction */
{20.0},
{60.0}, /* exponent, cutoff */
{1.0, 0.0, 0.0}, /* attenuation */
{0.0, 1.25, 0.0}, /* translation */
{0.0, 0.0, 0.0}, /* rotation */
{20.0, 0.0, 40.0}, /* swing */
{0.0, 0.0, 0.0}, /* arc */
{TWO_PI / 70.0, 0.0, TWO_PI / 140.0} /* arc increment */
},
{
{0.0, 0.2, 0.0, 1.0}, /* ambient */
{0.0, 0.8, 0.0, 1.0}, /* diffuse */
{0.0, 0.4, 0.0, 1.0}, /* specular */
{0.0, 0.0, 0.0, 1.0}, /* position */
{0.0, -1.0, 0.0}, /* direction */
{20.0},
{60.0}, /* exponent, cutoff */
{1.0, 0.0, 0.0}, /* attenuation */
{0.0, 1.25, 0.0}, /* translation */
{0.0, 0.0, 0.0}, /* rotation */
{20.0, 0.0, 40.0}, /* swing */
{0.0, 0.0, 0.0}, /* arc */
{TWO_PI / 120.0, 0.0, TWO_PI / 60.0} /* arc increment */
},
{
{0.0, 0.0, 0.2, 1.0}, /* ambient */
{0.0, 0.0, 0.8, 1.0}, /* diffuse */
{0.0, 0.0, 0.4, 1.0}, /* specular */
{0.0, 0.0, 0.0, 1.0}, /* position */
{0.0, -1.0, 0.0}, /* direction */
{20.0},
{60.0}, /* exponent, cutoff */
{1.0, 0.0, 0.0}, /* attenuation */
{0.0, 1.25, 0.0}, /* translation */
{0.0, 0.0, 0.0}, /* rotation */
{20.0, 0.0, 40.0}, /* swing */
{0.0, 0.0, 0.0}, /* arc */
{TWO_PI / 50.0, 0.0, TWO_PI / 100.0} /* arc increment */
}
};
static void
usage(char *name)
{
printf("\n");
printf("usage: %s [options]\n", name);
printf("\n");
printf(" Options:\n");
printf(" -geometry Specify size and position WxH+X+Y\n");
printf(" -lm Toggle lighting(SPECULAR and AMBIENT are/not same\n");
printf("\n");
#ifndef EXIT_FAILURE /* should be defined by ANSI C <stdlib.h> */
#define EXIT_FAILURE 1
#endif
exit(EXIT_FAILURE);
}
static void
initLights(void)
{
int k;
for (k = 0; k < NUM_LIGHTS; ++k) {
int lt = GL_LIGHT0 + k;
Light *light = &spots[k];
glEnable(lt);
glLightfv(lt, GL_AMBIENT, light->amb);
glLightfv(lt, GL_DIFFUSE, light->diff);
if (useSAME_AMB_SPEC)
glLightfv(lt, GL_SPECULAR, light->amb);
else
glLightfv(lt, GL_SPECULAR, light->spec);
glLightf(lt, GL_SPOT_EXPONENT, light->spotExp);
glLightf(lt, GL_SPOT_CUTOFF, light->spotCutoff);
glLightf(lt, GL_CONSTANT_ATTENUATION, light->atten[0]);
glLightf(lt, GL_LINEAR_ATTENUATION, light->atten[1]);
glLightf(lt, GL_QUADRATIC_ATTENUATION, light->atten[2]);
}
}
static void
aimLights(void)
{
int k;
for (k = 0; k < NUM_LIGHTS; ++k) {
Light *light = &spots[k];
light->rot[0] = light->swing[0] * sin(light->arc[0]);
light->arc[0] += light->arcIncr[0];
if (light->arc[0] > TWO_PI)
light->arc[0] -= TWO_PI;
light->rot[1] = light->swing[1] * sin(light->arc[1]);
light->arc[1] += light->arcIncr[1];
if (light->arc[1] > TWO_PI)
light->arc[1] -= TWO_PI;
light->rot[2] = light->swing[2] * sin(light->arc[2]);
light->arc[2] += light->arcIncr[2];
if (light->arc[2] > TWO_PI)
light->arc[2] -= TWO_PI;
}
}
static void
setLights(void)
{
int k;
for (k = 0; k < NUM_LIGHTS; ++k) {
int lt = GL_LIGHT0 + k;
Light *light = &spots[k];
glPushMatrix();
glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
glRotatef(light->rot[0], 1, 0, 0);
glRotatef(light->rot[1], 0, 1, 0);
glRotatef(light->rot[2], 0, 0, 1);
glLightfv(lt, GL_POSITION, light->pos);
glLightfv(lt, GL_SPOT_DIRECTION, light->spotDir);
glPopMatrix();
}
}
static void
drawLights(void)
{
int k;
glDisable(GL_LIGHTING);
for (k = 0; k < NUM_LIGHTS; ++k) {
Light *light = &spots[k];
glColor4fv(light->diff);
glPushMatrix();
glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
glRotatef(light->rot[0], 1, 0, 0);
glRotatef(light->rot[1], 0, 1, 0);
glRotatef(light->rot[2], 0, 0, 1);
glBegin(GL_LINES);
glVertex3f(light->pos[0], light->pos[1], light->pos[2]);
glVertex3f(light->spotDir[0], light->spotDir[1], light->spotDir[2]);
glEnd();
glPopMatrix();
}
glEnable(GL_LIGHTING);
}
static void
drawPlane(int w, int h)
{
int i, j;
float dw = 1.0 / w;
float dh = 1.0 / h;
glNormal3f(0.0, 0.0, 1.0);
for (j = 0; j < h; ++j) {
glBegin(GL_TRIANGLE_STRIP);
for (i = 0; i <= w; ++i) {
glVertex2f(dw * i, dh * (j + 1));
glVertex2f(dw * i, dh * j);
}
glEnd();
}
}
int spin = 0;
void
display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0, 1, 0);
aimLights();
setLights();
glPushMatrix();
glRotatef(-90.0, 1, 0, 0);
glScalef(1.9, 1.9, 1.0);
glTranslatef(-0.5, -0.5, 0.0);
drawPlane(16, 16);
glPopMatrix();
drawLights();
glPopMatrix();
glutSwapBuffers();
}
void
animate(void)
{
spin += 0.5;
if (spin > 360.0)
spin -= 360.0;
glutPostRedisplay();
}
void
visibility(int state)
{
if (state == GLUT_VISIBLE) {
glutIdleFunc(animate);
} else {
glutIdleFunc(NULL);
}
}
int
main(int argc, char **argv)
{
int i;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
/* process commmand line args */
for (i = 1; i < argc; ++i) {
if (!strcmp("-lm", argv[i])) {
useSAME_AMB_SPEC = !useSAME_AMB_SPEC;
} else {
usage(argv[0]);
}
}
glutCreateWindow("GLUT spotlight swing");
glutDisplayFunc(display);
glutVisibilityFunc(visibility);
glMatrixMode(GL_PROJECTION);
glFrustum(-1, 1, -1, 1, 2, 6);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, -3.0);
glRotatef(45.0, 1, 0, 0);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
glMaterialf(GL_FRONT, GL_SHININESS, 10.0);
initLights();
glutMainLoop();
return 0;
}
I'v been trying to anti alias with OGL. I found a code chunk that is supposed to do this but I see no antialiasing. I also reset my settings in Nvidia Control Panel but no luck.
Does this code in fact antialias the cube?
GLboolean polySmooth = GL_TRUE;
static void init(void)
{
glCullFace (GL_BACK);
glEnable (GL_CULL_FACE);
glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);
glClearColor (0.0, 0.0, 0.0, 0.0);
}
#define NFACE 6
#define NVERT 8
void drawCube(GLdouble x0, GLdouble x1, GLdouble y0,
GLdouble y1, GLdouble z0, GLdouble z1)
{
static GLfloat v[8][3];
static GLfloat c[8][4] = {
{0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 1.0},
{0.0, 1.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 1.0},
{0.0, 0.0, 1.0, 1.0}, {1.0, 0.0, 1.0, 1.0},
{0.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}
};
/* indices of front, top, left, bottom, right, back faces */
static GLubyte indices[NFACE][4] = {
{4, 5, 6, 7}, {2, 3, 7, 6}, {0, 4, 7, 3},
{0, 1, 5, 4}, {1, 5, 6, 2}, {0, 3, 2, 1}
};
v[0][0] = v[3][0] = v[4][0] = v[7][0] = x0;
v[1][0] = v[2][0] = v[5][0] = v[6][0] = x1;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
v[0][2] = v[1][2] = v[2][2] = v[3][2] = z0;
v[4][2] = v[5][2] = v[6][2] = v[7][2] = z1;
#ifdef GL_VERSION_1_1
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_COLOR_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, v);
glColorPointer (4, GL_FLOAT, 0, c);
glDrawElements(GL_QUADS, NFACE*4, GL_UNSIGNED_BYTE, indices);
glDisableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_COLOR_ARRAY);
#else
printf ("If this is GL Version 1.0, ");
printf ("vertex arrays are not supported.\n");
exit(1);
#endif
}
/* Note: polygons must be drawn from front to back
* for proper blending.
*/
void display(void)
{
if (polySmooth) {
glClear (GL_COLOR_BUFFER_BIT);
glEnable (GL_BLEND);
glEnable (GL_POLYGON_SMOOTH);
glDisable (GL_DEPTH_TEST);
}
else {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable (GL_BLEND);
glDisable (GL_POLYGON_SMOOTH);
glEnable (GL_DEPTH_TEST);
}
glPushMatrix ();
glTranslatef (0.0, 0.0, -8.0);
glRotatef (30.0, 1.0, 0.0, 0.0);
glRotatef (60.0, 0.0, 1.0, 0.0);
drawCube(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);
glPopMatrix ();
glFlush ();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 't':
case 'T':
polySmooth = !polySmooth;
glutPostRedisplay();
break;
case 27:
exit(0); /* Escape key */
break;
default:
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB
| GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(200, 200);
glutCreateWindow(argv[0]);
init ();
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutDisplayFunc (display);
glutMainLoop();
return 0;
}
Thanks
You should really consider to
find a better (read "up to date") source of information than the redbook
use multisampling/supersampling instead of the almost-deprecated GL_POLYGON_SMOOTH
On your problem:
What is your graphic card ?
Which version of OpenGL are you using ?
Are you depth sorting all your polygons ?
Have you tried to supply GLUT_MULTISAMPLE to the glutInitDisplayMode(..) call? It's not sure your glut implementation supports it though.