Best way to detect Collision in 3d OpenGL graphics? - c++

I am implementing a 3d game in OpenGL but I'm stuck on collision detection, game contains multiple pendulums and a cannon which shoots pendulum like:
I try to implement collision detection by taking distance between two objects:
dx=ax-bx
dy=ay-by
dz=az-bz
distance = sqrt(dx*dx + dy*dy + dz*dz);
where ax,ay,az is pendulum points and bx,by,bz is cannon bomb point.
distance<=A_radius+B_radius for collision detection checking distance less then determine collision detection occur.
But unfortunately this logic did not work.
Pendulum is made using gluSphere and gluCylinder and this code here
glPushMatrix();
glTranslated(0,0,40);
drawCanon();
glPopMatrix();
glPushMatrix();
glTranslatef(600, 0, -410);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(bx, by, bz);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
//GLUquadricObj *ctrees;
for (int i = 0; i < allPendulum.size(); i++)
{
glPushMatrix();
glTranslatef(400, 50, -400);
allPendulum[i].drawRope();
glPopMatrix();
glPushMatrix();
glTranslatef(400, 50, -400);
allPendulum[i].drawPend();
glPopMatrix();
}
drawCanon code is here
void drawCanon()
{
glPushMatrix();
glTranslatef(600, 0, -380);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(600, 0, -410);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(300, 0, -40);
//glRotatef(rorate, 0, 0, 0);
drawWheelAttacher();
glPopMatrix();
//canon fire with bomb
glPushMatrix();
glTranslatef(605, 3, -390);
glRotatef(longFire, xRotate, yRotate, zRotate);
//glTranslatef(0, 0, -25);
drawFireHolder();
//printf_s("Long fire is %d", longFire);
glPopMatrix();
glPushMatrix();
glTranslatef(605, 3, -390);
glRotatef(longFire, xRotate, yRotate, zRotate);
glTranslatef(0, 0, bombX);
glTranslatef(0, 0, 25);
drawBomb();
glPopMatrix();
}
Complete code if any one want is here
#include <iostream>
#include <fstream>
#include <math.h>
#include <glut.h>
#include <glut.h>
#include "Turtle.h"
#include "cube.h"
#include"pixMap.h"
#include "pendulum.h"
#include "vector"
void timer(int);
void drawRope(void);
void drawBob(void);
void drawLongPipe(void);
void initializePendulum(void);
void addPendulumInVector(void);
void drawCanon(void);
void drawCar(void);
void drawWheel(void);
void drawWheelAttacher(void);
void drawFireHolder(void);
void drawBomb(void);
void mouseControl(int x,int y);
void mouseClick(int button, int state, int x, int y);
void specialKeyHandler(int key, int x, int y);
void handlerMove();
RGBpixmap pix[5];
int zaxis = -300;
int xaxis=0, yaxis;
int rorate = 0;
bool check = false;
int carX = 0, carY, carZ;
int bombX=0;
void key(unsigned char key, int x, int y);
void drawFlorr();
float L = 100;
int longFire = 200;
bool fire = false;
const int screenWidth = 1000; // width of screen window in pixels
const int screenHeight = 1000; // height of screen window in pixels
float ww = 800;
float wh = 800;
float f = 520, n = 10.0;
static GLdouble ort1[] = { -200, 200, -33, 140 };
//static GLdouble viewer[] = { 525, 25, -180 };
static GLdouble viewer[] = { 729, 25, -334 };
// 729, 25, -334 ,525, 25 ,-350
static GLdouble up[] = { 0, 1, 0 };
static GLdouble objec[] = { 525, 25, -350 };
//
//static GLdouble objec[] = { 605.0, 0, -300 };
float x, y = 0.0, z, z1;
float xmax = screenWidth - 200.0;
float zmax = screenWidth - 200.0;
float xmin, zmin;
float step = 10.0;
float bx = bombX, by = 0, bz = 450;
float dx, dy, dz;
float fov = 39; // previous 80
using std::cout;
using std::fstream;
using std::ios;
#define PI 3.1415926535898
pendulum Pendulum,PedulumTwo,PendulumThree;
std::vector<pendulum> allPendulum;
float camAngle = 10;
int xRotate = 0, yRotate = 0, zRotate = 1;
void myInit(void)
{
//glClearColor(0.0,0.0,0.0,0.0); // background color is white
//glPointSize(2.0); // a 'dot' is 2 by 2 pixels
//glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
gluOrtho2D(0.0, screenWidth, 0.0, screenHeight);//dino window
//gluOrtho2D(1.0, 1.0, 1.0,1.0);//house window
//gluOrtho2D(1.0, 1.0, 1.0, 1.0);//bird window
glViewport(0, 0, screenWidth, screenHeight);
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluLookAt(viewer[0], viewer[1], viewer[2], objec[0], objec[1], objec[2], 0, 1, 0);
glMatrixMode(GL_PROJECTION);
//glOrtho(-1, 1, -1, 1, -1, 100);
glLoadIdentity();
gluPerspective(fov, 1.333, n, f);
//gluPerspective(90, 1, 1.333, 1000);
//gluPerspective(50, screenWidth / screenHeight, 0.000001, 2000);
glPointSize(2.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(viewer[0], viewer[1], viewer[2]); // Translation to the camera center
glRotatef(-camAngle * 57.2957795, 0, 1, 0); // Rotate to correspond to the camera
glTranslatef(0.016, 0, -0.05); // Offset to draw the object
//glutWireCone(0.005, 0.9, 20, 20);
glPopMatrix();
//cube.drawFace(10, 20, 10, 22);
drawFlorr();
glPushMatrix();
//glTranslated(0, 0, 40);
drawPipe();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,40);
drawCanon();
glPopMatrix();
/*
glPushMatrix();
glTranslatef(600, 0, -410);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(bx, by, bz);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
*/
// drawWheelAttacher();
//Line.turn(90);
/*
*/
//glLineWidth(10.0);
//Turtle Line(Point2(600, 70, -300), -90);
//glColor3f(1, 0, 0);
//Line.forward(1, 1);
//Line.turnTo(-45);
//Line.forward(100, 1);
//drawRope();
//GLUquadricObj *ctrees;
for (int i = 0; i < allPendulum.size(); i++)
{
glPushMatrix();
glTranslatef(400, 50, -400);
allPendulum[i].drawRope();
glPopMatrix();
glPushMatrix();
glTranslatef(400, 50, -400);
allPendulum[i].drawPend();
glPopMatrix();
}
//drawEveryThing();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // set display mode
glutInitWindowSize(screenWidth, screenHeight); // set window size
glutInitWindowPosition(10, 10); // set window position on screen
glEnable(GL_DEPTH_TEST);
glutCreateWindow("Dino Line Drawing"); // open the screen window
glutDisplayFunc(myDisplay); // register redraw function
myInit();
glEnable(GL_TEXTURE_2D);
pix[0].readBMPFile("grass.bmp");
pix[0].setTexture(2001);
pix[1].readBMPFile("wood.bmp");
pix[1].setTexture(2002);
pix[2].readBMPFile("ROPE.bmp");
pix[2].setTexture(2003);
pix[3].readBMPFile("bob.bmp");
pix[3].setTexture(2004);
glutKeyboardFunc(key);
initializePendulum();
addPendulumInVector();
glutTimerFunc(1,timer,1);
glutMouseFunc(mouseClick);
glutPassiveMotionFunc(mouseControl);
glutSpecialFunc(specialKeyHandler);
glutMainLoop(); // go into a perpetual loop
return 1;
}
void timer(int t)
{
//CarX + cos(someangle)*(distance from car)
if (fire == true)
{
bx = 0;
bz = 415-bombX;
dx = 400 - 605-bombX;
dy = 50 - 3;
dz = 400 +bz;
float distance = sqrt(dx*dx + dy*dy + dz*dz);
printf("DISTANCE IS %f",distance);
// distance=floor(distance);
if (distance <=12)
{
printf("Collision Occur");
}
if (distance <= (12))// radius is the radus of our bounding sphere for each object
{
printf("Collision Occur");
}
bombX++;
}
else
{
rorate++;
}
for (int i = 0; i < allPendulum.size(); i++)
{
allPendulum[i].changeDirection();
}
glutTimerFunc(10, timer, t);
zaxis++;
glutPostRedisplay();
}
void drawHook()
{
//glColor3f(1.0f, 0.0f, 0.0f); // drawing color is black
glPointSize(5.0);
}
void drawFlorr()
{
glEnable(GL_TEXTURE_2D);
glColor3ub(255,255,255);
xmin = -100;
zmin = -100;
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
for (x = xmin; x < xmax; x += step)
{
for (z = zmin; z < zmax; z += step)
{
z1 = -z;
glBindTexture(GL_TEXTURE_2D, 2001);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(x, y, z1);
glTexCoord2f(1, 0);
glVertex3f(x, y, z1-step);
glTexCoord2f(0, 1);
glVertex3f(x + step, y, z1 - step);
glTexCoord2f(1, 1);
glVertex3f(x+step, y, z1);
glEnd();
}
}
glDisable(GL_TEXTURE_2D);
}
void key(unsigned char key, int x, int y)
{
if (key == 't' || key == 'T')
{
xRotate = 1, yRotate = 0, zRotate = 0;
handlerMove();
}
if (key == 'r' || key == 'R')
{
xRotate = 0, yRotate = 1, zRotate = 0;
handlerMove();
}
if (key == 'x' && up[0] == 0)
{
viewer[0] -= 1.0;
}
if (key == 'X' && up[0] == 0)
{
viewer[0] += 1.0;
}
if (key == 'y' && up[0] == 0)
{
viewer[1] -= 1.0;
}
if (key == 'Y' && up[0] == 0)
{
viewer[1] += 1.0;
}
if (key == 'z' && up[0] == 0)
{
viewer[2] += 1.0;
}
if (key == 'Z' && up[0] == 0)
{
viewer[2] -= 1.0;
}
// zomm changing
if (key == 'v')
{
fov+=1.0;
if (fov > 180)
{
fov = 180.0;
}
}
if (key == 'V')
{
fov -= 1.0;
if (fov < 0)
{
fov = 0;
}
}
//change near clipping
if (key == 'f')
{
f -= 1.0;
}
if (key == 'F')
{
f += 1.0;
}
if (key == 'l')
{
carX++;
}
if (key == 'k')
{
carX--;
}
if (key == 'o')
{
carY++;
}
if (key == 'm')
{
carY--;
}
glutPostRedisplay();
}
void drawEveryThing()
{
drawFlorr();
drawLine();
glPushMatrix();
//glTranslatef(0, 0, -500);
drawHouse();
glPopMatrix();
glPushMatrix();
glTranslatef(300.0, 0, -500);
drawMountain(96, 150);
glPopMatrix();
glPushMatrix();
glTranslatef(380.0, 0, -500);
drawMountain(90, 100);
glPopMatrix();
glPushMatrix();
glTranslatef(400.0, 0, -300);
drawTrees(3,20);
glPopMatrix();
glPushMatrix();
glTranslatef(525.0, 0, -550);
drawTrees(6, 25);
glPopMatrix();
}
void drawPipe()
{
int circle_points;
float size, angle;
int i;
//House Main Vertices
GLfloat housevert[] = { 400.0, 50.0, -500.0, //0
400.0, 60.0, -500.0, //1
415.0, 25.0, -500.0, //2
410.0, 60, -500.0, //3
410.0, 50.0, -500.0, //4
400.0, 50.0, -300.0, //5
400.0, 60, -300.0, //6
415.0, 25.0, -300.0, //7
410.0, 60, -300.0, //8
410.0, 50.0, -300.0 }; //9
glEnable(GL_TEXTURE_2D);
glLineWidth(2.0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, housevert);
//glColor3f(1.0, 0.0, 0.0);
glBindTexture(GL_TEXTURE_2D, 2002);
// Front Wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glArrayElement(0);
glTexCoord2f(1, 0);
glArrayElement(1);
glTexCoord2f(0, 1);
glArrayElement(3);
glTexCoord2f(1, 1);
glArrayElement(4);
glEnd();
glBindTexture(GL_TEXTURE_2D, 2002);
//Right Wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glArrayElement(4);
glTexCoord2f(1, 0);
glArrayElement(3);
glTexCoord2f(0, 1);
glArrayElement(8);
glTexCoord2f(1, 1);
glArrayElement(9);
glEnd();
glBindTexture(GL_TEXTURE_2D, 2002);
//Left Wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glArrayElement(0);
glTexCoord2f(0, 1);
glArrayElement(1);
glTexCoord2f(1, 0);
glArrayElement(6);
glTexCoord2f(1, 1);
glArrayElement(5);
glEnd();
glBindTexture(GL_TEXTURE_2D, 2002);
//Back Wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glArrayElement(5);
glTexCoord2f(0, 1);
glArrayElement(6);
glTexCoord2f(1, 0);
glArrayElement(8);
glTexCoord2f(1, 1);
glArrayElement(9);
glEnd();
glDisable(GL_TEXTURE_2D);
}
void drawRope()
{
GLUquadricObj *mount;
//glMatrixMode(GL_TEXTURE);
//glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 2003);
mount = gluNewQuadric();
gluQuadricDrawStyle(mount, GL_QUADS);
gluQuadricTexture(mount, true);
glPushMatrix();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glColor3f(0.0, 0.1, 0.3);
glColor3f(0.0, 1.0, 0.0);
//glTranslatef(-100, 20, 0);
glRotatef(rorate, 1, 0, 0);
gluCylinder(mount, 1, 1, 100, 2, 1);
glDisable(GL_TEXTURE_2D);
glTranslatef(0, 0, 100);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 2004);
gluQuadricTexture(mount, true);
gluSphere(mount, 1 * 6, 10, 10);
glDisable(GL_TEXTURE_2D);
//gluQuadricTexture(mount, true);
glPopMatrix();
}
void drawBob()
{
GLUquadricObj *trees;
trees = gluNewQuadric();
gluQuadricDrawStyle(trees, GLU_LINE);
glPushMatrix();
glRotatef(0,0,0,0);
glColor3f(0.0, 1.0, 0.0);
gluSphere(trees, 1 * 10, 20, 2);
glPopMatrix();
}
void initializePendulum()
{
Pendulum.Amplitude = 25;
PendulumThree.Amplitude = 133;
PedulumTwo.Amplitude = 100;
}
void addPendulumInVector()
{
allPendulum.push_back(Pendulum);
allPendulum.push_back(PedulumTwo);
allPendulum.push_back(PendulumThree);
}
void drawWheel()
{
glPushMatrix();
glTranslatef(600, 0, -380);
glRotatef(rorate, 1, 0, 0);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(600, 0, -350);
glRotatef(rorate, 1, 0, 0);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(630, 0, -380);
glRotatef(rorate, 1, 0, 0);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(630, 0, -350);
glRotatef(rorate, 1, 0, 0);
drawBob();
glPopMatrix();
}
void drawCanon()
{
glPushMatrix();
glTranslatef(600, 0, -380);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(600, 0, -410);
glRotatef(rorate, 0, 0, 1);
drawBob();
glPopMatrix();
glPushMatrix();
glTranslatef(300, 0, -40);
//glRotatef(rorate, 0, 0, 0);
drawWheelAttacher();
glPopMatrix();
//canon fire with bomb
glPushMatrix();
glTranslatef(605, 3, -390);
glRotatef(longFire, xRotate, yRotate, zRotate);
//glTranslatef(0, 0, -25);
drawFireHolder();
//printf_s("Long fire is %d", longFire);
glPopMatrix();
glPushMatrix();
glTranslatef(605, 3, -390);
glRotatef(longFire, xRotate, yRotate, zRotate);
glTranslatef(0, 0, bombX);
glTranslatef(0, 0, 25);
drawBomb();
glPopMatrix();
}
void drawWheelAttacher()
{
glPushMatrix();
glTranslatef(300, 0, -380);
//glRotatef(0, 0, 0, 1);
drawLongPipe();
glPopMatrix();
}
void drawLongPipe()
{
GLUquadricObj *trees;
trees = gluNewQuadric();
gluQuadricDrawStyle(trees, GLU_LINE);
glPushMatrix();
glRotatef(0, 0, 0, 0);
glColor3f(0.0, 1.0, 0.0);
gluCylinder(trees, 1, 1, 50, 5, 5);
glPopMatrix();
}
void drawFireHolder()
{
GLUquadricObj *trees;
trees = gluNewQuadric();
gluQuadricDrawStyle(trees, GL_EYE_LINEAR);
glPushMatrix();
glRotatef(0, 0, 0, 1);
glColor3f(0.0, 1.0, 0.0);
gluCylinder(trees, 1, 1, 20, 5, 5);
glPopMatrix();
}
void drawBomb()
{
GLUquadricObj *mount;
//glMatrixMode(GL_TEXTURE);
//glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 2003);
mount = gluNewQuadric();
gluQuadricDrawStyle(mount, GL_QUADS);
gluQuadricTexture(mount, true);
glPushMatrix();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 2004);
gluQuadricTexture(mount, true);
gluSphere(mount, 1 * 6, 10, 10);
glDisable(GL_TEXTURE_2D);
//gluQuadricTexture(mount, true);
glPopMatrix();
}
void mouseClick(int button, int state, int x, int y)
{
fire = true;
}
void mouseControl(int x, int y)
{
// printf_s("mouse x is %d", x);
if (x > 280)
{
check = true;
}
else if (x == 150)
{
check = false;
}
}
void handlerMove()
{
if (check == true && fire == true)
{
}
else if (check == true)
{
longFire--;
}
else
{
longFire++;
}
if (longFire > 280)
{
check = true;
}
else if (longFire == 150)
{
check = false;
}
}
Pendulum Class is here
#pragma once
#include <glut.h>
class pendulum
{
public:
int Amplitude = 0;
bool isCheck = false;
int radius = 6;
void drawRope()
{
GLUquadricObj *mount;
//glMatrixMode(GL_TEXTURE);
//glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 2003);
mount = gluNewQuadric();
gluQuadricDrawStyle(mount, GL_QUADS);
gluQuadricTexture(mount, true);
glPushMatrix();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glColor3f(0.0, 0.1, 0.3);
glColor3f(0.0, 1.0, 0.0);
//glTranslatef(-100, 20, 0);
glRotatef(Amplitude, 1, 0, 0);
gluCylinder(mount, 1, 1, 50, 2, 1);
glDisable(GL_TEXTURE_2D);
//gluQuadricTexture(mount, true);
glPopMatrix();
}
void changeDirection()
{
if (isCheck)
{
Amplitude--;
}
else
{
Amplitude++;
}
if (Amplitude == 150)
{
isCheck = true;
}
else if (Amplitude < 25)
{
isCheck = false;
Amplitude = 25;
}
}
void drawPend()
{
GLUquadricObj *mount;
//glMatrixMode(GL_TEXTURE);
//glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 2003);
mount = gluNewQuadric();
gluQuadricDrawStyle(mount, GL_QUADS);
gluQuadricTexture(mount, true);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glColor3f(0.0, 0.1, 0.3);
//gluQuadricTexture(mount, true);
glPushMatrix();
glRotatef(Amplitude, 1, 0, 0);
glTranslatef(0, 0, 50);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 2004);
gluQuadricTexture(mount, true);
gluSphere(mount, 1 * radius, 10, 10);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
};

your logic works only if the two objects are spheres.
you need to compute the distance between the center of the sphere and the line crossing the centers of the up and down circles of the cylinder; then compare that distance to the sum of the radius of the sphere and the radius of the cylinder.

Related

Texture applied through OpenGL isn't visible when rendering + add image directly in question

I tried to apply a checkerboard styled texture to the model below here using GLubyte and glTexImage2D along with glTexCoord2f.
I previously applied a material to it that works perfectly, but for some reasons my texture won't show up at all. I can't seem to see or figure out why because looking at the examples I'm following everything should be working perfectly.
What I should have
#include <glut.h>
float angle[4];
float LightAngle;
bool LowerFrontLegDown = true;
bool LowerBackLegDown = true;
GLfloat corners[8][3] = { {-0.5,0.5,-0.5},{0.5,0.5,-0.5},
{0.5,-0.5,-0.5},{-0.5,-0.5,-0.5},
{-0.5,0.5,0.5},{0.5,0.5,0.5},
{0.5,-0.5,0.5},{-0.5,-0.5,0.5} };
//Two Dimensional Array for corners
GLfloat normals[][3] = { {0.0,0.0,1.0},
{1.0,0.0,0.0},
{0.0,-1.0,0.0},
{0.0,1.0,0.0},
{0.0,0.0,-1.0},
{-1.0,0.0,0.0} };
typedef struct materialStruct {
GLfloat ambient[4];
GLfloat diffuse[4];
GLfloat specular[4];
GLfloat shininess;
};
materialStruct brassMaterial = {
{ 0.33, 0.22, 0.03, 1.00 },
{ 0.78, 0.57, 0.11, 1.00 },
{ 0.99, 0.91, 0.81, 1.00 },
27.80 };
materialStruct redPlasticMaterial = {
{ 0.30, 0.00, 0.00, 1.00 },
{ 0.60, 0.00, 0.00, 1.00 },
{ 0.80, 0.60, 0.60, 1.00 },
32.00 };
materialStruct* currentMaterial;
void setMaterial(materialStruct* materials) {
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, materials->ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, materials->diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materials->specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, materials->shininess);
}
void drawFace(int a, int b, int c, int d) {
glBegin(GL_POLYGON);
glTexCoord2f(0.0, 0.0);
glVertex3fv(corners[a]);
glTexCoord2f(0.0, 1.0);
glVertex3fv(corners[b]);
glTexCoord2f(1.0, 1.0);
glVertex3fv(corners[c]);
glTexCoord2f(1.0, 0.0);
glVertex3fv(corners[d]);
glEnd();
} //Turns the corners from the two dimensional array into corner pieces for the model, allowing faces to be drawn
void ArrayCube() {
glNormal3fv(normals[0]);
drawFace(0, 3, 2, 1);
glNormal3fv(normals[1]);
drawFace(3, 0, 4, 7);
glNormal3fv(normals[2]);
drawFace(2, 3, 7, 6);
glNormal3fv(normals[3]);
drawFace(1, 2, 6, 5);
glNormal3fv(normals[4]);
drawFace(4, 5, 6, 7);
glNormal3fv(normals[5]);
drawFace(5, 4, 0, 1);
}
//Draws the faces of the model and creates a cube we can call later for the individual parts of the model.
void rotate() {
angle[0] += 1.0;
if (angle[0] > 360) angle[0] -= 360;
if (LowerFrontLegDown) angle[1] -= 0.2;
else angle[1] += 0.2;
if (angle[1] < 315) LowerFrontLegDown = false;
if (angle[1] > 360) LowerFrontLegDown = true;
angle[0] += 1.0;
if (angle[0] > 360) angle[0] -= 360;
if (LowerBackLegDown) angle[1] -= 0.2;
else angle[1] += 0.2;
if (angle[1] < 315) LowerBackLegDown = false;
if (angle[1] > 360) LowerBackLegDown = true;
glutPostRedisplay();
}
void MainBody()
{
glPushMatrix();
glScalef(1.25, 0.25, 0.5);
ArrayCube();
glPopMatrix();
}
void LowerNeck()
{
glPushMatrix();
glTranslatef(0.5, 0.25, 0);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void UpperNeck()
{
glPushMatrix();
glTranslatef(0.5, 0.75, 0);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void Head()
{
glPushMatrix();
glRotatef(90, 0.0, 0.0,1.0);
glTranslatef(1, -0.6, 0);
glScalef(0.1, 0.4, 0.15);
ArrayCube();
glPopMatrix();
}
void RightHorn()
{
glPushMatrix();
glRotatef(0, 0.0, 0.0,1);
glTranslatef(0.5, 1.15, 0.035);
glScalef(0.05, 0.15, 0.05);
ArrayCube();
glPopMatrix();
}
void LeftHorn()
{
glPushMatrix();
glRotatef(0, 0.0, 0.0, 1);
glTranslatef(0.5, 1.15, -0.035);
glScalef(0.05, 0.15, 0.05);
ArrayCube();
glPopMatrix();
}
void FrontUpperRightLeg()
{
glPushMatrix();
glTranslatef(0.5, -0.35, 0.15);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void FrontLowerRightLeg()
{
glPushMatrix();
glTranslatef(0.5, -0.75, 0.15);
glRotatef(angle[1], 0.0, 0.0, 1.0);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void FrontUpperLeftLeg()
{
glPushMatrix();
glTranslatef(0.5, -0.35, -0.15);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void FrontLowerLeftLeg()
{
glPushMatrix();
glTranslatef(0.5, -0.75, -0.15);
glRotatef(angle[1], 0.0, 0.0, 1.0);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void BackUpperRightLeg()
{
glPushMatrix();
glTranslatef(-0.5, -0.35, -0.15);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void BackLowerRightLeg()
{
glPushMatrix();
glTranslatef(-0.5, -0.75, -0.15);
glRotatef(angle[1], 0.0, 0.0, 1.0);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void BackUpperLeftLeg()
{
glPushMatrix();
glTranslatef(-0.5, -0.35, 0.15);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void BackLowerLeftLeg()
{
glPushMatrix();
glTranslatef(-0.5, -0.75, 0.15);
glRotatef(angle[1], 0.0, 0.0, 1.0);
glScalef(0.15, 0.5, 0.15);
ArrayCube();
glPopMatrix();
}
void Tail()
{
glPushMatrix();
glTranslatef(-0.65, -0.25, 0);
glScalef(0.05, 0.75, 0.05);
ArrayCube();
glPopMatrix();
}
//Each of the below functions draws an individual part of the whole model and places those parts where they need to go once the program runs
void DrawGiraffe()
{
MainBody();
LowerNeck();
UpperNeck();
Head();
RightHorn();
LeftHorn();
FrontUpperRightLeg();
FrontLowerRightLeg();
FrontUpperLeftLeg();
FrontLowerLeftLeg();
BackUpperRightLeg();
BackLowerRightLeg();
BackUpperLeftLeg();
BackLowerLeftLeg();
Tail();
}
//Calls the above functions to render the final model
//The rotate function allows the camera to rotate around the model
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.6, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
DrawGiraffe();
glutSwapBuffers();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
currentMaterial = &redPlasticMaterial;
setMaterial(currentMaterial);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 2.5);
GLfloat light_pos[] = {2.0,2.0,2.0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
}
int main(int argc, char** argv)
{
angle[0] = 0;
angle[1] = 360;
angle[2] = 315;
angle[3] = 0;
GLubyte image[64][64][3];
int i, j, r, c;
for(i = 0;i < 64; i++){
for(j = 0;j < 64; j++){
c = ((((i&0x8)== 0)^((j&0x8))==0))*255;
image[i][j][0] = (GLubyte) c;
image[i][j][1] = (GLubyte) c;
image[i][j][2] = (GLubyte) c;
}
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Giraffe");
glutDisplayFunc(display);
glutIdleFunc(rotate);
init();
glutMainLoop();
}
There are many things wrong with your code:
You are using glTexParameterf instead of glTexParameteri.
You are not binding a texture object, which means that calls to your glTexImage2D function will be useless, because glTexImage2D relies on the bounded texture of GL_TEXTURE_2D.
You are initializing the texture before you call the glut initialization functions. This means that any calls to OpenGL functions will be useless.
You should initialize your texture with something like this
// this should be declared as a global variable
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
GLubyte image[64][64][3];
int i, j, r, c;
for(i = 0;i < 64; i++){
for(j = 0;j < 64; j++){
c = ((((i&0x8)== 0)^((j&0x8))==0))*255;
image[i][j][0] = (GLubyte) c;
image[i][j][1] = (GLubyte) c;
image[i][j][2] = (GLubyte) c;
}
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
and move the initialization of the texture to the init function, just after the call to glEnable(GL_TEXTURE_2D);
Of course, you will need to bind this texture when you render by calling glBindTexture(GL_TEXTURE_2D, texture);

How to add texture to this sphere?

I have created a rotating wired sphere. I have done textures to a cube but sphere seems to be a problem.
I want to add world map as a texture to this sphere. Any suggestions?
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <thread>
#include <chrono>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
using namespace std;
GLuint texture;
int start = 1;
GLfloat xRotated, yRotated, zRotated;
GLdouble radius = 1;
void init() {
glOrtho(-1000 / 2, 1000 / 2, -1000 / 2, 1000 / 2, -500, 500);
}
GLuint glInitTexture(char* filename)
{
GLuint t = 0;
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
unsigned char* data = stbi_load(filename, &width, &height, &nrChannels, 0);
glGenTextures(1, &t);
glBindTexture(GL_TEXTURE_2D, t);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//unsigned char data[] = { 255, 0, 0, 255 };
if (data)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
else
std::cout << "fail";
return t;
}
void drawImage(GLuint file, float x, float y, float w, float h)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glPushMatrix();
//glTranslatef(x, y, 0.0);
//glRotatef(angle, 0.0, 0.0, 1.0);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, file);
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.5);
glRotatef(yRotated, 0.0, 1.0, 0.0);
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
glFlush();
yRotated += 0.01;
//glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
//Plots points of both graphs together
//Displays map on screen
void drawMap() {
std::cout << "\nDraw map\n";
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet(GLUT_WINDOW_WIDTH);
const double h = glutGet(GLUT_WINDOW_HEIGHT);
gluPerspective(90.0, w / h, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -15);
for (int i = 0; i < 10000; i++) {
glClear(GL_DEPTH_BUFFER_BIT);
drawImage(texture, 0, 0, 100, 200);
//std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
glutSwapBuffers();
glEnd();
glFlush();
}
void render()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//glFlush();
glPointSize(5);
glColor3f(1, 1, 1);
glBegin(GL_LINES);
glVertex3f(-450, -450, 10);
glVertex3f(-450, -250, 10);
glEnd();
glBegin(GL_LINES);
glVertex3f(-450, -450, 10);
glVertex3f(-250, -450, 10);
glEnd();
drawMap();
//plotPoints();
glFlush();
}
void Kbevent(unsigned char key, int x, int y) {
if (key == 's') {
start = start % 2;
glutPostRedisplay();
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1560, 810);
glutCreateWindow("Applying Textures");
init();
xRotated = yRotated = zRotated = 30.0;
xRotated = 33;
yRotated = 40;
char fn[] = "map.jpg";
texture = glInitTexture(fn);
glutDisplayFunc(render);
//glutReshapeFunc(reshapeFunc);
//glutIdleFunc(idleFunc);
glutKeyboardFunc(Kbevent);
glutMainLoop();
return 0;
}
The problem with applying a 2D texture is that when you wrap a 2D texture onto a sphere, the top and bottom area of the sphere, the texture looks squeezed.
I suggest to use gluSphere and gluQuadricTexture rather than glutSolidSphere. e.g:
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
For an continuously rotation, you have increment the rotation angle and to continuously update the window (glutPostRedisplay). e.g.:
void redisplayFunc(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.5);
glRotatef(yRotated, 0.0, 1.0, 0.0);
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
glFlush();
yRotated += 1;
glutPostRedisplay();
}

OpenGl draw on top of tile map C++

I am new to OpenGL. I have the following code that I am using from a tutorial I followed, what it does is render a tile map. It does this successfully but my problem now is that I want to add a moveable object onto the window however it is not appearing.
#include "stdafx.h"
#include <string>
#include <windows.h>
#include <iostream>
#include <conio.h>
#include <sstream>
#include <math.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include "GL/freeglut.h"
#pragma comment(lib, "OpenGL32.lib")
// window size and update rate (60 fps)
int width = 700;
int height = 700;
int interval = 1000 / 60;
// ball
float ball_pos_x = width / 2;
float ball_pos_y = height / 2;
float ball_dir_x = -1.0f;
float ball_dir_y = 0.0f;
int ball_width = 20;
int ball_height = 20;
int ball_speed = 5;
GLuint texture; //the array for our texture
GLuint texture2; //the array for our second texture
void keyboard() {
if (GetAsyncKeyState(VK_LEFT)) ball_pos_x -= ball_speed;
if (GetAsyncKeyState(VK_RIGHT)) ball_pos_x += ball_speed;
if (GetAsyncKeyState(VK_UP)) ball_pos_y += ball_speed;
if (GetAsyncKeyState(VK_DOWN)) ball_pos_y -= ball_speed;
}
int cMap[30][30] = { //our map
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
void drawRect(float x, float y, float width, float height) {
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x + width, y);
glVertex2f(x + width, y + height);
glVertex2f(x, y + height);
glEnd();
}
GLuint LoadTexture( const char * filename, int width, int height )
{
GLuint texture;
unsigned char * data;
FILE * file;
//The following code will read in our RAW file
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
data = (unsigned char *)malloc( width * height * 3 );
fread( data, width * height * 3, 1, file );
fclose( file );
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_MODULATE ); //set texture environment parameters
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR );
//Here we are setting the parameter to repeat the texture
//instead of clamping the texture
//to the edge of our shape.
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_REPEAT );
//Generate the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, data);
free( data ); //free the texture
return texture; //return whether it was successfull
}
void FreeTexture( GLuint texture )
{
glDeleteTextures( 1, &texture );
}
void drawTiles (void) { //our function to draw the tiles
for (int i = 0; i < 10; i++) //loop through the height of the map
{
for (int j = 0; j < 10; j++) //loop through the width of the map
{
if (cMap[i][j] == 0) //if the map at this position contains a 0
{
glBindTexture( GL_TEXTURE_2D, texture ); //bind our grass texture to our shape
}
else //otherwise
{
glBindTexture( GL_TEXTURE_2D, texture2 ); //bind our dirt texture to our shape
}
glPushMatrix(); //push the matrix so that our translations only affect this tile
glTranslatef(j, -i, 0); //translate the tile to where it should belong
glBegin (GL_QUADS); //begin drawing our quads
glTexCoord2d(0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0); //with our vertices we have to assign a texcoord
glTexCoord2d(1.0, 0.0);
glVertex3f(1.0, 0.0, 0.0); //so that our texture has some points to draw to
glTexCoord2d(1.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);
glTexCoord2d(0.0, 1.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
glPopMatrix(); //pop the matrix
} //end first loop
} //end second loop
}
void draw() {
// clear (has to be done at the beginning)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // ToDo: draw our scene
// draw ball
drawRect(ball_pos_x - ball_width / 2, ball_pos_y - ball_height / 2, ball_width, ball_height);
glEnable( GL_TEXTURE_2D );
glTranslatef(-5, 4, -20); //translate back a bit to view the map correctly
drawTiles(); //draw our tiles
// swap buffers (has to be done at the end)
glutSwapBuffers();
}
void UpdatePlayer(){
// hit by right racket?
if (ball_pos_x < ball_pos_x + ball_width &&
ball_pos_x > enemy_pos_x &&
ball_pos_y < enemy_pos_y + enemy_height &&
ball_pos_y > enemy_pos_y) {
ball_pos_x = ball_pos_x;
ball_pos_y = ball_pos_y;
}
}
void update(int value) { // Call update() again in 'interval' milliseconds
// input handling
keyboard();
UpdatePlayer();
glutTimerFunc(interval, update, 0);
// Redisplay frame
glutPostRedisplay();
}
void enable2D(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, width, 0.0f, height, 0.0f, 1.0f);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
int _tmain(int argc, char** argv)
{
// initialize opengl (via glut)
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(width, height); glutCreateWindow("noobtuts.com Pong");
// Register callback functions
glutDisplayFunc(draw);
glutIdleFunc (draw);
glutReshapeFunc (reshape);
glutTimerFunc(interval, update, 0);
// setup scene to 2d mode and set draw color to white
enable2D(width, height);
glColor3f(1.0f, 1.0f, 1.0f);
//Load our texture
texture = LoadTexture("texture.raw", 256, 256);
texture2 = LoadTexture("texture2.raw", 256, 256);
glutMainLoop ();
//Free our texture
FreeTexture(texture);
FreeTexture(texture2);
return 0;
}
If I was to comment out in the main...
glutIdleFunc (draw);
glutReshapeFunc (reshape);
The tile map will disappear and my moveable square is visible and works...I just can't implement the two together successfully. Again i'm completely new to this so apologise if I am doing something really stupid Any ideas where I am going wrong?
Are you sure you want to draw the tile map with a perspective projection? It seems to me that you should be using an orthographic projection for both the tile map and the ball.
Change your reshape function to simply call enable2D(w, h). Then change your drawTiles function to draw using screen coordinates instead. That should work.
Some additional notes:
Don't forget to disable texturing when drawing your ball (you don't seem to be setting any texture for it, so it will just render with the last texture set).
You could also disable depth testing with glDisable(GL_DEPTH_TEST) since you don't really need it (and use glVertex2f for drawing the tile map instead of glVertex3f)

Why is this quad not rendering? Or if it is why can't I see it?

I am using Visual C++ and GLUT. Am I missing something such a normals? this is the exact code I am using. I tried to insert glNormal3f(0, 0, 1); before the vertex statements but this did not change anything. The glutSolidSphere renders just as I expect it to but not the quad.
#include "stdafx.h"
#include <stdlib.h>
#include <GL/glut.h>
float spin = 0.0f;
float zDir = 0;
GLfloat diffuseIntensity[] = {.75, .75, .75, 1};
GLfloat specularHue[] = {0, 0, .5f, 1};
GLfloat shininess[] = {5};
void moveCamera();
void checkKeys(int, int, int);
void setUpLighting();
void changeSize(int w, int h) {
if (h == 0)
h = 1;
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
}
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
moveCamera();
glTranslatef(0, 0, zDir-5);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_FLAT);
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, specularHue);
glPushMatrix();
glRotatef(90, 1, 0, 0);
glRotatef(spin, 0, 0, 1);
glutSolidSphere(.5f, 24, 24);
glPopMatrix();
spin += .01f;
if(spin > 360) spin -= 360;
glBegin(GL_QUADS);
glVertex3f(-10, 0, -10);
glVertex3f(-10, 0, 10);
glVertex3f(10, 0, 10);
glVertex3f(10, 0, -10);
glEnd();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
glutCreateWindow("Lighthouse3D - GLUT Tutorial");
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutSpecialFunc(checkKeys);
glEnable(GL_DEPTH_TEST);
setUpLighting();
glutMainLoop();
return 1;
}
void moveCamera(){
glTranslatef(0, 0, zDir);
}
void checkKeys(int key, int x, int y){
switch(key){
case GLUT_KEY_UP:
zDir += .1f;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
zDir += -.1f;
glutPostRedisplay();
break;
case GLUT_KEY_END:
exit(0);
}
}
void setUpLighting(){
GLfloat position0[] = {3, 1, 0, 1};
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, position0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseIntensity);
}
Give this a shot:
#include <GL/glut.h>
float zDir = 12;
void checkKeys(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_UP:
zDir += -.5f;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
zDir += .5f;
glutPostRedisplay();
break;
case GLUT_KEY_END:
exit(0);
}
}
float spin = 0;
void renderScene(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(45,w/h,0.1,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -zDir);
// set up light
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat diffuseIntensity[] = {.75, .75, .75, 1};
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseIntensity);
// draw sphere at light position
glDisable( GL_LIGHTING );
glPushMatrix();
// spin light position around the y axis
glRotatef( -spin, 0, 1, 0 );
GLfloat position0[] = {3,3,3, 1};
glLightfv(GL_LIGHT0, GL_POSITION, position0);
glTranslatef( position0[0], position0[1], position0[2] );
glColor3ub(255,255,255);
glutSolidSphere(0.1,8,8);
glPopMatrix();
glEnable( GL_LIGHTING );
// draw sphere
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_FLAT);
GLfloat specularHue[] = {0, 0, .5f, 1};
GLfloat shininess[] = {5};
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, specularHue);
spin += .01f;
if(spin > 360) spin -= 360;
glPushMatrix();
glRotatef(spin, 0, 1, 0);
glutSolidSphere(2, 24, 24);
glPopMatrix();
// draw quad
glColor3ub(255,0,0);
glPushMatrix();
glScalef( 3, 3, 3 );
glBegin(GL_QUADS);
glNormal3f( 0, 0, 1 );
glVertex2f( -1, -1 );
glVertex2f( 1, -1 );
glVertex2f( 1, 1 );
glVertex2f( -1, 1 );
glEnd();
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
glutCreateWindow("Lighthouse3D - GLUT Tutorial");
glutDisplayFunc(renderScene);
glutSpecialFunc(checkKeys);
glutMainLoop();
return 1;
}
The quad is rendered, but you don't see it because it is drawn very much like the surface of a table and your eyes are at the same level of the table. Because of this, the effect is like that of which nothing was drawn at all. That or you'll see a line.
Your rotation above, being wrapped in a PushMatrix/PopMatrix only works with the solid sphere.

OpenGL - Why are my objects transparent?

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.