Object doesn't seems to collide using AABB collision method - c++

I am new to opengl. I am doing a simple 2D shooting game and using AABB collision to do collision between objects and bullet. I do the collision for my plane and the square but it doesn't seems to work. Can help me check what's my problem?
#include <iostream>
#include <time.h>
#include <windows.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h>
using namespace std;
#define SPACEBAR 32
class Plane {
public:
GLfloat x = 0.05f;
GLfloat y = 0.95f;
GLfloat width = 0.05f;
GLfloat height = 0.10f;
GLfloat moveX = 0.0f;
GLfloat moveY = 0.0f;
void drawPlane(GLfloat, GLfloat, GLfloat, GLfloat);
};
class Enemy {
public:
GLfloat x, y;
GLfloat width, height;
GLfloat sqrMoveX, sqrMoveY;
void drawEnemySqr(GLfloat, GLfloat, GLfloat, GLfloat);
};
Plane plane;
Enemy enemy;
GLfloat XMax, XMin, YMax, YMin;
GLdouble clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop;
int refreshMills = 30;
float RandomNumberX() {
float Min = -1.0f;
float Max = 1.0f;
return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
}
float RandomNumberY() {
float Min = 0.7f;
float Max = 1.0f;
return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
}
void Timer(int value) {
glutPostRedisplay();
glutTimerFunc(refreshMills, Timer, 0);
}
bool collision(GLfloat x1, GLfloat y1, GLfloat w1, GLfloat h1,
GLfloat x2, GLfloat y2, GLfloat w2, GLfloat h2) {
if ((x1 < (x2 + w2)) &&
((x1 + w1) > x2) &&
(y1 < (y2 + h2)) &&
((h1 + y1) > y2)) {
return true;
}
else {
return false;
}
}
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
void Plane :: drawPlane(GLfloat planeX, GLfloat planeY, GLfloat planeWidth, GLfloat planeHeight) {
glTranslatef(moveX, moveY, 0.0f);
glBegin(GL_POLYGON);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(-(planeX), -(planeY));
glVertex2f(planeX, -(planeY));
glVertex2f(planeX + planeWidth, -(planeY - planeHeight));
glVertex2f(planeX - (planeWidth), -(planeY - (planeHeight + 0.20f)));
glVertex2f(-(planeX + planeWidth), -(planeY - planeHeight));
glEnd();
if (moveX > XMax) {
moveX = XMax;
}
else if (moveX < XMin) {
moveX = XMin;
}
if (moveY > YMax) {
moveY = YMax;
}
else if (moveY < YMin) {
moveY = YMin;
}
}
void Enemy :: drawEnemySqr(GLfloat enemyX, GLfloat enemyY, GLfloat enemyWidth, GLfloat enemyHeight) {
glTranslatef(sqrMoveX, sqrMoveY, 0.0f);
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex2f(enemyX, enemyY);
glVertex2f(enemyX + enemyWidth, enemyY);
glVertex2f(enemyX + enemyWidth, enemyY + enemyHeight);
glVertex2f(enemyX, enemyWidth + enemyY);
glEnd();
sqrMoveY -= 0.0005f;
if (sqrMoveY < -1.8f) {
sqrMoveX = RandomNumberX();
sqrMoveY = RandomNumberY();
}
glutPostRedisplay();
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glPushMatrix();
plane.drawPlane(plane.x, plane.y, plane.width, plane.height);
glPopMatrix();
glPushMatrix();
enemy.drawEnemySqr(0.0f, 0.0f, 0.3f, 0.3f);
glPopMatrix();
if (collision(plane.moveX, plane.moveY, plane.width, plane.height,
enemy.sqrMoveX, enemy.sqrMoveY, enemy.width, enemy.height) == true) {
enemy.sqrMoveY = -2.0f;
}
glutSwapBuffers();
}
void keyButton(int key, int x, int y) {
switch (key) {
case GLUT_KEY_RIGHT:
plane.moveX += 0.05f;
break;
case GLUT_KEY_LEFT:
plane.moveX += -0.05f;
break;
case GLUT_KEY_UP:
plane.moveY += 0.05f;
break;
case GLUT_KEY_DOWN:
plane.moveY += -0.05f;
break;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv) {
srand(time(NULL));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(480, 640);
glutInitWindowPosition(50, 50);
glutCreateWindow("Plane Shooting Game");
glutDisplayFunc(display);
glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutTimerFunc(25, Timer, 0);
glutSpecialFunc(keyButton);
initGL();
glutMainLoop();
return 0;
}

You have a problem in this line:
if (collision(plane.moveX, plane.moveY, plane.width, plane.height,
enemy.sqrMoveX, enemy.sqrMoveY, enemy.width, enemy.height) == true)
You must pass plane.x, plane.y, enemy.x, enemy.y to collision function instead of plane.moveX, plane.moveY, enemy.sqrMoveX, enemy.sqrMoveY.

Related

OpenGL yoyo program troubles

I'm having trouble getting my yoyo program to work; I have a growing and shrinking string to go along with the yoyo moving and spinning, but I've got the string moving along with the yoyo. I need to have the string staying stationary while the yoyo spins up and down.I have to have the string and yoyo's movements allocated onto one button as well. Mind helping me with my code? (also please excuse the lackluster yoyo; I wanted to finish the programming before designing it)
#include "stdafx.h"
#include <GL/glut.h>
#include <GL/gl.h>
#include <math.h>
void firstDisplay();
void secondDisplay();
void movement();
void init();
void drawButton();
void handleButton(int button, int state, int x, int y);
const int Width=720;
const int Height = 480;
static float PI = 3.14159;
static float radius = 25;
static float INC= (PI/30);
static GLfloat spin = 0.0;
static GLfloat deltaz = .001;
static GLfloat deltax = 0.0;
static GLfloat deltay = 0.0;
//######################################################### Main #########################################################
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE | GLUT_DEPTH);
glutInitWindowSize(Width,Height);
glutInitWindowPosition(0,0);
glutCreateWindow("Yoyo");
glutDisplayFunc(firstDisplay);
glutMouseFunc(handleButton);
init();
glutMainLoop();
return;
}
//######################################################### Draw Button #########################################################
void drawButton()
{
glBegin(GL_POLYGON);
float theta;
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(1,0,1);
glVertex2f(40 + radius * cos(theta), 40 + radius*sin(theta));
}
glEnd();
}
//######################################################### Second Display #########################################################
void secondDisplay()
{
float theta;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON); //Here is the yoyo
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(1,1,1);
float radius1 = 75;
glVertex2f(360 + radius1 * cos(theta), 80 + radius1*sin(theta));
}
glEnd();
glBegin(GL_POLYGON); //Here is the yoyo design
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(0,1,1);
float radius1 = 55;
glVertex2f(350 + radius1 * cos(theta), 90 + radius1*sin(theta));
}
glEnd();
glFlush();
return;
}
//######################################################### First Display #########################################################
void firstDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
float theta;
glBegin(GL_POLYGON); //Here is the yoyo
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(1,1,1);
float radius1 = 75;
glVertex2f(360 + radius1 * cos(theta), 80 + radius1*sin(theta));
}
glEnd();
glBegin(GL_POLYGON); //Here is the yoyo
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(0,1,1);
float radius1 = 55;
glVertex2f(350 + radius1 * cos(theta), 90 + radius1*sin(theta));
}
glEnd();
drawButton();
glutSwapBuffers();
glFlush();
return;
}
//######################################################### Draw String #########################################################
void draw_string()
{
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(363, 8.25 - deltay, 0.0);
glVertex3f(357, 8.25 - deltay, 0);
glVertex3f(357, 6, 0);
glVertex3f(363, 6, 0);
glEnd();
}
//######################################################### Button Controls #########################################################
void handleButton(int button, int state, int x, int y)
{
static int index =-1;
if(button == GLUT_LEFT_BUTTON)
{
if(y>= 10 && y<= 100)
{
if (state == GLUT_DOWN)
{
glutIdleFunc(movement);
}
if (state == GLUT_UP)
{
glutIdleFunc(NULL);
}
}
glutSwapBuffers();
}
}
//######################################################### Yoyo Movement #########################################################
void movement()
{
static int goingup = 0;
glClear(GL_COLOR_BUFFER_BIT);
if(goingup==1)
{
deltay -= 6;
if(deltay <= 0)
{
goingup = 0;
}
spin = spin -5;
if(spin < 360)
{
spin = spin + 360;
}
}
if(goingup == 0)
{
deltay += 6;
if (deltay >= 315)
{
goingup = 1;
}
spin = spin +5;
if(spin < 360)
{
spin = spin + 360;
}
}
glPushMatrix();
glTranslatef(360+deltax, 80+deltay, 0.0);
glRotatef(spin,0.0,0.0,1.0);
glTranslatef(-360,-80, 0.0);
secondDisplay();
draw_string();
glPopMatrix();
drawButton();
glutSwapBuffers();
}
//######################################################### Init #########################################################
void init()
{
glClearColor(0, 0, 0, 0.0);
glColor3f(1, 1, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,Width,Height,0);
return;
}
I solved my problem. I went separated the draw_string() and seconddisplay() functions within the movement function like so:
}
glPushMatrix();
glTranslatef(360+deltax, 80+deltay, 0.0);
glRotatef(spin,0.0,0.0,1.0);
glTranslatef(-360,-80, 0.0);
secondDisplay();
glPopMatrix();
glPushMatrix();
glTranslatef(360+deltax, 80+deltay, 0.0);
glRotatef(0,0.0,0.0,1.0);
glTranslatef(-360,-80, 0.0);
draw_string();
glPopMatrix();
drawButton();
glutSwapBuffers();
}
I removed the spin from draw_string()'s glRotatef.

Flickering with Particles in OpenGL C++

I am having trouble with this code. I want it to fire fireworks that explode and fall in front of a static background. Right now the fireworks and background work, but together they cause a flickering and the fireworks don't fall at a regular rate. How do I prevent this flickering and achieve a regular rate of firework's fall?
#include <GL/freeglut.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <iomanip>
#include "Header.h"
using namespace std;
#define M_PI (3.1415926535897932384626433832795)
GLfloat randomNum()
{
return (rand() % 10000) / 10000.0;
}
GLfloat nx = 0;
GLfloat ny = .8;
#define MAX_POINTS 750
GLfloat numPoints;
GLfloat curx, cury;
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
GLfloat red, green, blue;
int step; int length;
GLfloat newRed = 0;
GLfloat newGreen = 0;
GLfloat newBlue = 0;
GLint totPor = 0;
GLint strontiumPor = 0;
GLfloat bariumPor = 0;
GLfloat copperPor = 0;
GLfloat sodiumPor = 0;
GLfloat phosPor = 0;
GLfloat red2;
GLfloat green2;
GLfloat green3;
GLfloat blue2;
void initialize()
{
int j; double temp, temp2;
numPoints = randomNum()*(MAX_POINTS - 1);
curx = nx;
cury = ny;
//Color Mixing
if (totPor != 0)
{
red = newRed * strontiumPor / (totPor - strontiumPor); //s red
green = newGreen * bariumPor / (totPor - bariumPor); //b green
blue = newBlue * copperPor / (totPor - copperPor); //c blue
red2 = newRed * sodiumPor / (totPor - sodiumPor); //d yellow
green2 = newGreen * sodiumPor / (totPor - sodiumPor);
green3 = newGreen * phosPor / (totPor - phosPor); //p blue green
blue2 = newBlue * phosPor / (totPor - phosPor);
red = red + red2;
green = green + green2 + green3;
blue = blue + blue2;
}
else
{
red = newRed;
green = newGreen;
blue = newBlue;
}
glPointSize(1.7);
step = 0;
length = 500 + 300 * randomNum();
/* initialize the blast */
for (j = 0; j<numPoints; j++) {
x[j] = curx;
y[j] = cury;
temp = randomNum();
temp2 = randomNum()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp) / length;
yacc[j] = (sin(temp2) * temp) / length;
}
}
void draw_fireworks(void)
{
int i;
double glow = (length - (step)) / (double)length;
glColor3f(red*glow, green*glow, blue*glow); //glow
glBegin(GL_POINTS);
for (i = 0; i<numPoints; i++) {
x[i] += xacc[i];
y[i] += yacc[i];
glVertex2f(x[i], y[i]);
}
glEnd();
glFlush();
glutSwapBuffers();
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
if (step < 0.9*length) {
for (i = 0; i<numPoints; i++)
yacc[i] -= 0.02 / length; // gravity
draw_fireworks();
}
step++;
if (step > length) initialize();
DrawScene();
glutSwapBuffers();
}
int t = 0;
void idle(void)
{
if (t == 45000)
{
glutPostRedisplay();
t = 0;
}
t++;
}
void SpecialKey(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT:
/* Move fireworks left or right, up or down */
nx = nx + -.025;
break;
case GLUT_KEY_RIGHT:
nx = nx + .025;
break;
case GLUT_KEY_UP:
ny = ny + .025;
break;
case GLUT_KEY_DOWN:
ny = ny + -.025;
break;
}
glutPostRedisplay();
}
void Keyboard(unsigned char key, int x, int y)
{
//Select Chemicals
switch (key)
{
case 's':
newRed = 1;
strontiumPor = strontiumPor + 1;
totPor = totPor + 1;
break;
case 'b':
newGreen = 1;
bariumPor = bariumPor + 1;
totPor = totPor + 1;
break;
case 'c':
newBlue = 1;
copperPor = copperPor + 1;
totPor = totPor + 1;
break;
case 'd':
newRed = 1;
newGreen = 1;
sodiumPor = sodiumPor + 1;
totPor = totPor + 1;
break;
case 'p':
newBlue = 1;
newGreen = 1;
phosPor = phosPor + 1;
totPor = totPor + 1;
break;
case 'R': newRed = newRed + .1;
break;
case 'G': newGreen = newGreen + .1;
break;
case 'B': newBlue = newBlue + .1;
break;
case ' ': //Space bar is Reset or start
newRed = 1;
newGreen = 1;
newBlue = 1;
totPor = 0;
strontiumPor = 0;
bariumPor = 0;
copperPor = 0;
sodiumPor = 0;
phosPor = 0;
break;
case 'm': nx = 0; ny = 0.8; //M resets target to default
break;
case 'q': exit(0); //Q is quit
}
glutPostRedisplay();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0,
-1.0*(GLfloat)h / (GLfloat)w, 1.0*(GLfloat)h / (GLfloat)w,
-1.0, 1.0);
else
glOrtho(-1.0*(GLfloat)w / (GLfloat)h, 1.0*(GLfloat)w / (GLfloat)h,
-1.0, 1.0,
-1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(700, 700);
glutInitWindowPosition(0, 0);
glutCreateWindow("Fireworks Display");
glClearColor(0.0, 0.0, 0.0, 0.0);
initialize();
initText();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(Keyboard);
glutSpecialFunc(SpecialKey);
glutMainLoop();
return 0;
}
And then also this:
#include <GL/freeglut.h>
#include "Soil.h"
GLuint tex_ID;
void LoadTextureMap()
{
int width, height, channels;
unsigned char* image = SOIL_load_image("washington.png", &width, &height, &channels, SOIL_LOAD_AUTO);
glGenTextures(1, &tex_ID);
glBindTexture(GL_TEXTURE_2D, tex_ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
}
void Tree(GLfloat x, GLfloat y, GLfloat z)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_ID);
glPushMatrix();
glRotatef(180, 0.0f, 0.0f, 1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0 + x, -1.0 + y, 1.0 + z);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0 + x, 1.0 + y, 1.0 + z);
glTexCoord2f(1.0, 1.0); glVertex3f(1 + x, 1.0 + y, 1.0 + z);
glTexCoord2f(1.0, 0.0); glVertex3f(1 + x, -1.0 + y, 1.0 + z);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
void DrawScene()
{
Tree(0, 0, 0);
}
void initText()
{
LoadTextureMap();
}
You're calling glutSwapBuffers() in draw_fireworks() and also in display(). You should call it only once per frame.
Btw, if you want to learn OpenGL don't waste your time with this legacy fixed function pipeline stuff. Go with shaders instead.

xzy, to xyz orientation conversion

I've got some code but the matrix orientation does not appeal to my purposes, can someone teach me how to convert it's orientation, it's currently set up as X Z Y, but i would like it to reflect X Y Z, can someone please highlight what must be done?
when i do vertex3f(100, 100, 10); forexample, the 10 value should reflect the Z value on my grid.
Here is my code:
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <Windows.h>
#include <glut.h>
#include <iostream>
using namespace std;
const float sensitivity = 0.005;
const float walk_speed = 0.5;
float cam_pos[3] = { 100.5, 10.0f, 50 };
float cam_view[3] = { -1.0f, 0.0f, 1.0f };
static int old_x, old_y, half_width, half_height;
int width = 1024, height = 768;
void updateKeys()
{
if (GetAsyncKeyState('W')){
cam_pos[0] += cam_view[0] * walk_speed;
cam_pos[1] += cam_view[1] * walk_speed;
cam_pos[2] += cam_view[2] * walk_speed;
}
if (GetAsyncKeyState('S')){
cam_pos[0] -= cam_view[0] * walk_speed;
cam_pos[1] -= cam_view[1] * walk_speed;
cam_pos[2] -= cam_view[2] * walk_speed;
}
if (GetAsyncKeyState('A')){
cam_pos[0] += cam_view[2] * walk_speed;
cam_pos[2] -= cam_view[0] * walk_speed;
}
if (GetAsyncKeyState('D')){
cam_pos[0] -= cam_view[2] * walk_speed;
cam_pos[2] += cam_view[0] * walk_speed;
}
if (GetAsyncKeyState(VK_SPACE)){
cam_pos[1] += walk_speed;
}
}
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//3d camera
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
cam_pos[0], cam_pos[1], cam_pos[2],
cam_pos[0] + cam_view[0], cam_pos[1] + cam_view[1], cam_pos[2] + cam_view[2],
0.0f, 1.0f, 0.0f);
//render grid
glBegin(GL_LINES);
for (int i = 0; i <= 100; i++) {
if (i == 0) { glColor3f(.6, .3, .3); }
else { glColor3f(.25, .25, .25); };
glVertex3f(i, 0, 0);
glVertex3f(i, 0, 100);
if (i == 0) { glColor3f(.3, .3, .6); }
else { glColor3f(.25, .25, .25); };
glVertex3f(0, 0, i);
glVertex3f(100, 0, i);
};
glEnd();
glEnable(GL_POINT_SMOOTH);
glPointSize(50.0f);
glColor3f(1, 0, 0);
glBegin(GL_POINTS);
glVertex3f(0, 0, 0);
//X, Z, Y
glVertex3f(10, -10, 10);
glEnd();
updateKeys();
glutSwapBuffers();
}
void normalize(float *v)
{
float magnitude = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] /= magnitude;
v[1] /= magnitude;
v[2] /= magnitude;
}
void rotate_view(float *view, float angle, float x, float y, float z)
{
float new_x;
float new_y;
float new_z;
float c = cos(angle);
float s = sin(angle);
new_x = (x*x*(1 - c) + c) * view[0];
new_x += (x*y*(1 - c) - z*s) * view[1];
new_x += (x*z*(1 - c) + y*s) * view[2];
new_y = (y*x*(1 - c) + z*s) * view[0];
new_y += (y*y*(1 - c) + c) * view[1];
new_y += (y*z*(1 - c) - x*s) * view[2];
new_z = (x*z*(1 - c) - y*s) * view[0];
new_z += (y*z*(1 - c) + x*s) * view[1];
new_z += (z*z*(1 - c) + c) * view[2];
view[0] = new_x;
view[1] = new_y;
view[2] = new_z;
normalize(view);
}
void motion(int x, int y)
{
float rot_x, rot_y;
float rot_axis[3];
x -= half_width;
y -= half_height;
rot_x = -(float)(x - old_x) * sensitivity;
rot_y = -(float)(y - old_y) * sensitivity;
old_x = x;
old_y = y;
rotate_view(cam_view, rot_x, 0.0f, 1.0f, 0.0f);
rot_axis[0] = -cam_view[2];
rot_axis[1] = 0.0f;
rot_axis[2] = cam_view[0];
normalize(rot_axis);
rotate_view(cam_view, rot_y, rot_axis[0], rot_axis[1], rot_axis[2]);
}
void mouse(int button, int state, int x, int y)
{
old_x = x - half_width;
old_y = y - half_height;
glutPostRedisplay();
}
void idle()
{
glutPostRedisplay();
}
void keys(unsigned char c, int x, int y)
{
glutPostRedisplay();
cout << "camera view: :" << cam_view[0] << "," << cam_view[1] << "," << cam_view[2] << endl;
}
void reshape(int w, int h)
{
width = w;
height = h;
half_height = w / 2;
half_width = h / 2;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 10000.0);
glViewport(0, 0, w, h);
}
//----------------------------------------------------------------------
// Main program
//----------------------------------------------------------------------
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(width, height);
glutCreateWindow("OpenGL");
glutDisplayFunc(renderScene);
glutKeyboardFunc(keys);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutIdleFunc(idle);
// OpenGL init
glEnable(GL_DEPTH_TEST);
// enter GLUT event processing cycle
glutMainLoop();
return 0; // this is just to keep the compiler happy
}
Use a transformation matrix that "remaps" the values. You can push that matrix on your modelview as usual.
The identity matrix is:
(1, 0, 0; 0, 1, 0; 0, 0, 1)
Your matrix would be:
(1, 0, 0; 0, 0, 1; 0, 1, 0)
I guess you can spot the difference. You can extend to a 4D matrix for homogeneous coordinates accordingly.

switch between glOrtho and gluPerspective

I'm working in a little OpenGL - GLUT program (i'm totally noob), and i'm having many problems switching between gluPerspective and glOrtho pressing a key (for example 'p').
I've take some screenhots to illustrate the problem... using gluPerspective and glOrtho
And here's my code...
#if defined(__APPLE__)
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#else
#include <GL/gl.h>
#include <GL/greeglut.h>
#endif
#include <iostream>
#include <math.h>
#include "model.h"
using namespace std;
// actual vector representing the camera\'s direction
float lx = 0.0f,lz = -1.0f;
// XZ position of the camera
float x = 0.0f,z = 5.0f;
// angle for rotating triangle
float angle = 0.0f;
float fov = 45.0;
Model m;
Model m1;
Model m2;
Model m3;
double maxX, maxY, maxZ;
double minX, minY, minZ;
double centX, centY, centZ;
double maxTam;
bool persp = true;
double min(double x, double y) {
if(x < y) return x;
return y;
}
double max(double x, double y) {
if(x > y) return x;
return y;
}
void setMinMaxXYZ(void) {
maxX = minX = m.vertices()[0];
maxY = minY = m.vertices()[1];
maxZ = minZ = m.vertices()[2];
for(int i = 3; i < m.vertices().size(); i += 3) {
maxX = max(maxX,m.vertices()[i]);
minX = min(minX,m.vertices()[i]);
maxY = max(maxY,m.vertices()[i+1]);
minY = min(minY,m.vertices()[i+1]);
maxZ = max(maxZ,m.vertices()[i+2]);
minZ = min(minZ,m.vertices()[i+2]);
}
centX = ((maxX - minX)/2) + minX;
centY = ((maxY - minY)/2) + minY;
centZ = ((maxZ - minZ)/2) + minZ;
}
void changeView(void) {
int w = glutGet(GLUT_WINDOW_WIDTH);
int h = glutGet(GLUT_WINDOW_HEIGHT);
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(persp) gluPerspective(fov, ratio, 0.1f, 100.0f);
else glOrtho(-1,1,-1,1,-0.5,100.0);
glMatrixMode(GL_MODELVIEW);
}
void changeSize(int w, int h) {
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0) h = 1;
if(w == 0) w = 1;
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(persp) gluPerspective(fov, ratio, 0.1f, 100.0f);
else glOrtho(-1,1,-1,1,0.1,100.0);
glViewport(0,0,w,h);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();
// Posicionament de la càmera
gluLookAt( x, 1.0f, z,
x+lx, 1.0f, z+lz,
0.0f, 1.0f, 0.0f);
glClearColor(0.5,0.5,1.0,1.0);
// dibuix terra
glColor3f(0.0f, 255.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-5.0f, 0.0f, -5.0f);
glVertex3f(-5.0f, 0.0f, 5.0f);
glVertex3f( 5.0f, 0.0f, 5.0f);
glVertex3f( 5.0f, 0.0f, -5.0f);
glEnd();
// Models .obj
for (int i = 0; i < 3; ++i) {
float transX, transY, transZ;
if(i == 0) {
m = m1;
transX = -1.25; transY = 0.5; transZ = -2.0;
} else if(i == 1) {
m = m2;
transX = -0.5; transY = 0.5; transZ = 2.5;
} else {
m = m3;
transX = 2.5; transY = 0.25; transZ = -0.5;
}
setMinMaxXYZ();
maxTam = max(max(maxX - minX, maxY - minY), maxZ - minZ);
glPushMatrix();
glTranslated(-(centX / maxTam), -(centY / maxTam), -(centZ / maxTam));
glTranslated(transX,transY,transZ);
glScaled(1.0/maxTam,1.0/maxTam,1.0/maxTam);
glBegin(GL_TRIANGLES);
for(int i = 0; i < m.faces().size(); i++){
const Face &f = m.faces()[i];
glColor3f(Materials[f.mat].diffuse[0],Materials[f.mat].diffuse[1],Materials[f.mat].diffuse[2]);
for(int j = 0; j < 3; j++)
glVertex3dv(&m.vertices()[f.v[j]]);
}
glEnd();
glPopMatrix();
}
glutSwapBuffers();
}
void processKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
else if(key == 'p'){
persp = not persp;
changeView();
}
}
void processSpecialKeys(int key, int xx, int yy) {
float fraction = 0.1f;
switch (key) {
case GLUT_KEY_LEFT :
angle -= 0.01f;
lx = sin(angle);
lz = -cos(angle);
break;
case GLUT_KEY_RIGHT :
angle += 0.01f;
lx = sin(angle);
lz = -cos(angle);
break;
case GLUT_KEY_UP :
x += lx * fraction;
z += lz * fraction;
break;
case GLUT_KEY_DOWN :
x -= lx * fraction;
z -= lz * fraction;
break;
}
}
void idle(void) {
glutPostRedisplay();
}
void iniView(void) {
int w = glutGet(GLUT_WINDOW_WIDTH);
int h = glutGet(GLUT_WINDOW_HEIGHT);
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, ratio, 0.1f, 100.0f);
//glOrtho(-1,1,-1,1,0.01,1000);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
// init GLUT i creació finestra
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,800);
glutCreateWindow("IDI: Bloc 3 - Càmeres i perspectives");
// Carregar models .obj
m1.load("model/legoman-assegut.obj");
m2.load("model/Shaun_Hastings.obj");
m3.load("model/porsche.obj");
// crides
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(idle);
glutKeyboardFunc(processKeys);
glutSpecialFunc(processSpecialKeys);
iniView();
// OpenGL init
glEnable(GL_DEPTH_TEST);
// loop
glutMainLoop();
return 1;
}
It's supposed that i should see the green "floor" in the glOrtho view... what i'm doing wrong??
ps. Model objects are .obj files delivered by the teacher.
edit:
Finally, the glOrtho works properly. But now... i've got another question, how can i do to maximize the window and (in glOrtho mode) the image does not deform??
In changeSize() function... when i'm using gluPerspective it works fine, but not with glOrtho!!
the fact that you don't see the floor with orthographic projection is actually expected given the way you set up your modelview matrix:
it happens because your floor is parallel to the XZ plane - and your view vector is, too.
// Posicionament de la càmera
gluLookAt( x, 1.0f, z,
x+lx, 1.0f, z+lz,
0.0f, 1.0f, 0.0f);
the first 3 arguments of gluLookAt are the xyz-components of the camera position, the next 3 arguments are the xyz of the 'center of interest'. the vector between those 2 points is the view vector, and its y-component is 0, meaning it is parallel to XZ and thus your floor.
if you want to see the floor + orthographic projection, you'll have to tilt the camera so that it looks down.

OpenGL OBJ Loader Error: EXC_BAD_ACCESS code = 1

I've just began learning OpenGL and this program is a mixture of stuff I've put together myself and some stuff straight copied from tutorials to speed up the process (like the whole OBJ loader you will see soon).
I'm having an error on
glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
//draw the faces
glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z);
and that error is EXC_BAD_ACCESS code = 1. I'm completely lost for answers to this issue and I've searched around but couldn't find anything unfortunately. I also know for a fact that it is loading the file as well because that was the first issue I faced but resolved. Below is all my code (which is in one file. I'll be making a whole new project from scratch soon).
Main.cpp
#include <GLUT/GLUT.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cmath>
void init();
void keyboard(unsigned char key, int x, int y);
void reshape(int w, int h);
void display();
void camera();
void cubePositions();
void drawCube();
void enable();
void plane();
// Roation angles.
float xPos = 0;
float yPos = 0;
float zPos = 0;
float xRot = 0;
float yRot = 0;
float angle = 0.0;
float lastx, lasty;
// Cubes position arrays.
float cubePosZ[10];
float cubePozX[10];
// Fog variables.
GLfloat fogAngle = 0.0;
GLfloat density = 0.1;
GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;
void makeCheckImage(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
struct coordinate{
float x,y,z;
coordinate(float a,float b,float c) : x(a),y(b),z(c) {};
};
//for faces, it can contain triangles and quads as well, the four variable contain which is that
struct face{
int facenum;
bool four;
int faces[4];
face(int facen,int f1,int f2,int f3) : facenum(facen){ //constructor for triangle
faces[0]=f1;
faces[1]=f2;
faces[2]=f3;
four=false;
}
face(int facen,int f1,int f2,int f3,int f4) : facenum(facen){ //overloaded constructor for quad
faces[0]=f1;
faces[1]=f2;
faces[2]=f3;
faces[3]=f4;
four=true;
}
};
//we rotate or object with angle degrees
int loadObject(const char* filename)
{
std::vector<std::string*> coord; //read every single line of the obj file as a string
std::vector<coordinate*> vertex;
std::vector<face*> faces;
std::vector<coordinate*> normals; //normal vectors for every face
std::ifstream in(filename); //open the .obj file
if(!in.is_open()) //if not opened, exit with -1
{
std::cout << "Nor oepened" << std::endl;
return -1;
}
char buf[256];
//read in every line to coord
while(!in.eof())
{
in.getline(buf,256);
coord.push_back(new std::string(buf));
}
//go through all of the elements of coord, and decide what kind of element is that
for(int i=0;i<coord.size();i++)
{
if(coord[i]->c_str()[0]=='#') //if it is a comment (the first character is #)
continue; //we don't care about that
else if(coord[i]->c_str()[0]=='v' && coord[i]->c_str()[1]==' ') //if vector
{
float tmpx,tmpy,tmpz;
sscanf(coord[i]->c_str(),"v %f %f %f",&tmpx,&tmpy,&tmpz); //read in the 3 float coordinate to tmpx,tmpy,tmpz
vertex.push_back(new coordinate(tmpx,tmpy,tmpz)); //and then add it to the end of our vertex list
}else if(coord[i]->c_str()[0]=='v' && coord[i]->c_str()[1]=='n') //if normal vector
{
float tmpx,tmpy,tmpz; //do the same thing
sscanf(coord[i]->c_str(),"vn %f %f %f",&tmpx,&tmpy,&tmpz);
normals.push_back(new coordinate(tmpx,tmpy,tmpz));
}else if(coord[i]->c_str()[0]=='f') //if face
{
int a,b,c,d,e;
if(count(coord[i]->begin(),coord[i]->end(),' ')==3) //if it is a triangle (it has 3 space in it)
{
sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b);
faces.push_back(new face(b,a,c,d)); //read in, and add to the end of the face list
}else{
sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b,&e,&b);
faces.push_back(new face(b,a,c,d,e)); //do the same, except we call another constructor, and we use different pattern
}
}
}
//raw
int num; //the id for the list
num=glGenLists(1); //generate a uniqe
glNewList(num,GL_COMPILE); //and create it
for(int i=0;i<faces.size();i++)
{
if(faces[i]->four) //if it's a quad draw a quad
{
glBegin(GL_QUADS);
//basically all I do here, is use the facenum (so the number of the face) as an index for the normal, so the 1st normal owe to the first face
//I subtract 1 because the index start from 0 in C++
glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
//draw the faces
glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z);
glEnd();
}else{
glBegin(GL_TRIANGLES);
glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
glEnd();
}
}
glEndList();
//delete everything to avoid memory leaks
for(int i=0;i<coord.size();i++)
delete coord[i];
for(int i=0;i<faces.size();i++)
delete faces[i];
for(int i=0;i<normals.size();i++)
delete normals[i];
for(int i=0;i<vertex.size();i++)
delete vertex[i];
return num; //return with the id
}
// Sets the position of the cubes randomly. Can later be used for more purposeful placements.
void cubePositions()
{
for (int i = 0; i < 10; i++)
{
cubePosZ[i] = rand() % 5 + 5;
cubePozX[i] = rand() % 5 + 5;
}
}
void drawCube()
{
for (int i = 0; i < 10; i++)
{
glPushMatrix();
//glTranslated(-cubePozX[i + 1] * 10, -1, -cubePosZ[i + 1] * 10);
glTranslated((i + 4), 0, (i - 5));
glTranslatef(i, 0, 5 * i);
glScalef(2, 2, 2);
glBegin(GL_QUADS);
glTexCoord2f(1, 0);
glVertex3f(-1, -1, 0);
glNormal3f(1, 1, 1);
glTexCoord2f(1, 1);
glVertex3f(-1, 1, 0);
glTexCoord2f(0, 1);
glVertex3f(1, 1, 0);
glTexCoord2f(0, 0);
glVertex3f(1, -1, 0);
glVertex3f(-1, -1, -1);
glVertex3f(-1, 1, -1);
glEnd();
glPopMatrix();
}
}
void plane()
{
glPushMatrix();
glColor4f(1.0, 0.0, 1.0, 1.0);
glTranslatef(0, -2.5, 0.0);
glScalef(100, 2, 100);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1, 0, 1);
glTexCoord2f(1.0, 0.0);
glVertex3f(-1, 0, -0.5);
glTexCoord2f(1.0, 1.0);
glVertex3f(1, 0, -0.5);
glTexCoord2f(0.0, 1.0);
glVertex3f(1, 0, 1);
glEnd();
glPopMatrix();
}
int cube;
void init()
{
cubePositions();
cube = loadObject("/Users/Admin/test.obj");
}
void enable()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
float col[] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, col);
}
void camera()
{
glRotatef(xRot, 1.0, 0.0, 0.0);
glRotatef(yRot, 0.0, 1.0, 0.0);
glTranslated(-xPos, -yPos, -zPos);
}
void display()
{
glClearColor(0.8, 0.8, 0.8, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
enable();
drawCube();
plane();
glCallList(cube);
glTranslated(-2, 0, 0);
glutSwapBuffers();
angle++;
}
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, 1000.0);
glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
if (key == 27)
{
exit(0);
}
if (key == 'q')
{
xRot += 0.5;
if (xRot > 360)
{
xRot -= 360;
}
}
if (key == 'z')
{
xRot -= 0.5;
if (xRot < - 360)
{
xRot += 360;
}
}
if (key == 'w')
{
float xRotRad;
float yRotRad;
xRotRad = (xRot / 180 * 3.14159f);
yRotRad = (yRot / 180 * 3.14159f);
xPos += float(sin(yRotRad));
zPos -= float(cos(yRotRad));
yPos -= float(sin(xRotRad));
}
if (key == 's')
{
float xRotRad;
float yRotRad;
xRotRad = (xRot / 180 * 3.14159f);
yRotRad = (yRot / 180 * 3.14159f);
xPos -= float(sin(yRotRad));
zPos += float(cos(yRotRad));
yPos += float(sin(xRotRad));
}
if (key == 'd')
{
yRot += 1;
if (yRot > 360)
{
yRot -= 360;
}
}
if (key == 'a')
{
yRot -= 1;
if (yRot < -360)
{
yRot += 360;
}
}
if (key == 'x')
{
yPos -= 1;
}
if (key == 'c')
{
yPos += 1;
}
}
void mouseMovement(int x, int y)
{
int diffX = x - lastx;
int diffY = y - lasty;
lastx = x;
lasty = y;
xRot += (float)diffY;
yRot += (float)diffX;
}
int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(1000, 1000);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL GLUT Computing - Taylor Moore");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(mouseMovement);
glutMainLoop();
return 0;
}
EXC_BAD_ACCESS usually means you are trying to access a chunk of memory that has been released or dealloc'ed. Here's the first response to a Google search on the term EXC_BAD_ACCESS that explains two strategies for tracking down the cause.