Tuesday, May 24, 2011

CAR Game part-1




Hi,
Here I come with yet another game.
This one came out rather too quickly as I had most of the functions already written and tested. :-) This is the game which i used to play in the video parlour, that was fun back then. well, Now there is fun in developing it.






#include "stdafx.h"

#include <iostream>
#include <stdlib.h>

#include <GL/glut.h>

#include "imageloader.h"
#include "math.h"

using namespace std;

const int MAX_X=1200;
const int MAX_Y=900;
const int MIN_X=0;
const int MIN_Y=0;

int car_x = MAX_X/4;
int car_y = MAX_Y;


int car_width=100;
int car_length=200;
int rx = MAX_X/4;
int ry = MAX_Y;
int road_width = 420;
int path_width = 20;
int lane_distance = car_width+40;
int car_max_x = (car_x+path_width) + lane_distance;
int car_min_x = MAX_X/4;

int car_cnt = 1;
GLuint _textureId; //The id of the texture
GLuint _textureId1; //The id of the texture
GLuint _textureId2; //The id of the texture
GLuint _textureId3; //The id of the texture

GLuint current_textureId; //The id of the texture

int timedelay = 100;
void draw_car(int length,int width,int x, int y);

int move_cnt=0;

typedef struct vehicle {
int x,y;
int length,width;
int texture_id;
struct vehicle* next;
}VEHICLE;

VEHICLE *head=NULL;
int current_y=0;

void create_vehicles() {
int rand_x = 0;

if(current_y>car_length) {
current_y = -200;
} else {
return;
}
// Create a new vehicle;
VEHICLE* temp = new VEHICLE;
temp->length = car_length;
temp->width = car_width;
temp->next = NULL;
temp->x = car_x+path_width;
temp->y = current_y;
if(car_cnt==1) {
temp->texture_id = _textureId1;
} else if(car_cnt==2) {
temp->texture_id = _textureId2;
} else if(car_cnt==3) {
temp->texture_id = _textureId3;
}

car_cnt++;
if(car_cnt==4) car_cnt = 1;

// Add it to the list
if(!head) {
head = temp;
} else {
VEHICLE* t = head;
while(t->next) {
t = t->next;
}
t->next = temp;
}
}

void draw_vehicles() {

VEHICLE* temp = head;
while(temp) {

int car_width = temp->width;
int car_length = temp->length;
int car_x = temp->x;
int car_y = temp->y;
current_textureId = temp->texture_id;
draw_car(car_width,car_length,car_x,car_y);

temp = temp->next;
}
}

void move_vehicles() {
VEHICLE* temp = head;
while(temp) {
temp->y = temp->y+10;
temp = temp->next;
}
current_y+=10;
}
void drawScene();

void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};


void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if(timedelay>0){
timedelay-=10;
}

break;
case 103: //DOWN arrow key
if(timedelay<500){
timedelay+=10;
}
break;

case 100: //LEFT arrow key
if(car_x>MAX_X/4){
car_x-=car_width;
}
break;

case 102: //RIGHT arrow key
if(car_x<(MAX_X/4-car_width+400)){
car_x+=car_width;
}
break;

}
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId); //Make room for our texture
glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D
0, //0 for now
GL_RGB, //Format OpenGL uses for image
image->width, image->height, //Width and height
0, //The border of the image
GL_RGB, //GL_RGB, because pixels are stored in RGB format
GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
//as unsigned numbers
image->pixels); //The actual pixel data
return textureId; //Returns the id of the texture
}



void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LINE_STIPPLE);
glLineWidth(4);
Image* image = loadBMP("car3.bmp");
_textureId = loadTexture(image);
delete image;

image = loadBMP("car4.bmp");
_textureId1 = loadTexture(image);
delete image;

image = loadBMP("car5.bmp");
_textureId2 = loadTexture(image);
delete image;

image = loadBMP("car6.bmp");
_textureId3 = loadTexture(image);
delete image;

}

void handleResize(int w, int h) {
/*glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);*/

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

void draw_lanes() {

glLineStipple(1,0x00ff);
glBegin(GL_LINES);

for(int i=1; i<=3;i++) {
glVertex3f(rx+path_width+car_width*i, MAX_Y, 0);
glVertex3f(rx+path_width+car_width*i, 0, 0);
}

glEnd();

glLineStipple(1,0xffff);
}

void draw_footpath(int x,int y,int path_width) {
int cnt=25;
int bwidth = path_width-2;
int bheight = 40;
int yy=y;
int xx=x+2;

// Blocks on the foot path
for(int i=0; i<cnt; i++) {
glBegin(GL_POLYGON);
glVertex3f(xx,yy,0);
glVertex3f(xx+bwidth,yy,0);
glVertex3f(xx+bwidth,yy+bheight,0);
glVertex3f(xx,yy+bheight,0);
glEnd();
yy+=2*bheight;
}
}

void create_road() {

glColor3f(1.0f, 1.0f, 1.0f);

ry = MAX_Y;
// Lines on the side
glBegin(GL_LINES);
glVertex3f(rx, ry, 0);
glVertex3f(rx, 0, 0);
glVertex3f(rx+path_width, ry, 0);
glVertex3f(rx+path_width, 0, 0);

glVertex3f(rx+road_width, ry, 0);
glVertex3f(rx+road_width, 0, 0);
glVertex3f(rx+path_width+road_width, ry, 0);
glVertex3f(rx+path_width+road_width, 0, 0);

glEnd();

ry=-200;
move_cnt ++;
if (move_cnt==8) {
move_cnt = 0;
}
ry = ry + 10*move_cnt;

// Draw footpath on both the sides of the road
draw_footpath(rx,ry,path_width);
draw_footpath(rx+road_width,ry,path_width);

// Draw the lanes in the road
draw_lanes();

}

void draw_car(int length,int width,int x, int y) {

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, current_textureId);

//Bottom
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glColor3f(0.0f, 0.1f, 0.1f);

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(x, y, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(x+length,y,0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x+length,y-width,0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x,y-width,0);

glEnd();

glBindTexture(GL_TEXTURE_2D,0);
}

void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

GLfloat directedLight[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat directedLightPos[] = {-10.0f, 15.0f, 20.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, directedLight);
glLightfv(GL_LIGHT0, GL_POSITION, directedLightPos);

// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);

// Draw the main racing
current_textureId = _textureId;
draw_car(car_width,car_length,car_x+path_width,car_y);

// Create a road
create_road();

// Create new vehicle
create_vehicles();

// Move vehicles
move_vehicles();

// Draw the vehicles
draw_vehicles();

glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {

drawScene();

glutPostRedisplay();
glutTimerFunc(timedelay, update, 0);
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(MAX_X, MAX_Y);

glutCreateWindow("Car Game");
initRendering();

glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutSpecialFunc(specialKey);

glutReshapeFunc(handleResize);
glutTimerFunc(timedelay , update, 0);

glutMainLoop();
return 0;
}


Monday, May 23, 2011

Bouncing Ball

Hi, I was having trouble with my half accomplished game. The problem was that I couldnt increase the speed of the moving ball. Even if I put absolutely no timer then also ball was moving with very less speed. I asked my friends on the lunch table and they gave me the solution that I should be increasing the step count OR i should always draw the ball in the origin space and translate it. SO I tried BOTH :-) Increasing step count did help and it doesn't look bad. I was expecting that I will get a little discrete moves but that didnt happen. I still get enough smooth output. Now I went for divide and conquer apporach and decided to get the ball properly rolling first. :-) So here is my program which will show the ball bouncing on the edges of the windows. User can resize the window. He can increase and decrease the speed of moving ball by using the UP and DOWN arrow keys. thanks :-)
#include "stdafx.h"

#include <iostream>
#include <stdlib.h>

#include <GL/glut.h>

#include "math.h"

using namespace std;

int MAX_X=1200;
int MAX_Y=900;
const int MIN_X=0;
const int MIN_Y=0;
int m_x=0;
int m_y=0;

int ball_x=500;
int ball_y=500;
int radius = 30;
int poly_circle[20][2];
int circle_segments = 0;


// BY default ball will go up
int x_dir = 1;
int y_dir = -1;
int base_y;
int base_x;
float move_mag = 5.0;

void init_circle() {
int x1=0;
int y1=0;
int cnt=0;
float angle = 0;
float x2,y2;
for (angle = 0; angle < 360; angle+=25.0,cnt++) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
poly_circle[cnt][0] = x2;
poly_circle[cnt][1] = y2;
}
poly_circle[cnt][0]=poly_circle[0][0];
poly_circle[cnt][1]=poly_circle[0][1];
circle_segments = cnt;
}



void drawScene();

void move_ball() {
ball_x = ball_x + (move_mag*x_dir);
ball_y = ball_y + (move_mag*y_dir);
}

void change_y_dir() {
y_dir = -y_dir;
}
void change_x_dir() {
x_dir = -x_dir;
}
void change_both_dir() {
change_y_dir();
change_x_dir();
}

int crossed_x_limits() {
if((ball_x-radius)<=MIN_X) {
return 1;
}
if((ball_x+radius)>=MAX_X) {
return 1;
}
return 0;
}


int crossed_y_limits() {
if(ball_y-radius<=MIN_Y) {
return 1;
}
if(ball_y+radius>=MAX_Y) {
return 1;
}
return 0;
}


// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;

drawScene();
}


void handleResize(int w, int h) {

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
MAX_X = w;
MAX_Y = h;
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}


void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;

glPushMatrix();//(NEW) Create a new matrix
glTranslatef(x1,y1,0);//(NEW) Rotate the triangle on z axis based on how much time has passed

glBegin(GL_LINES);
for(int i=0; i<circle_segments;++i) {
glVertex2f(poly_circle[i][0],poly_circle[i][1]);
glVertex2f(poly_circle[i+1][0],poly_circle[i+1][1]);
}
glEnd();

glPopMatrix();//(NEW) stops current transformations to the matrix
}

void play_ball() {
move_ball();

if (crossed_x_limits()) {
change_x_dir();
} else if (crossed_y_limits()) {
change_y_dir();
} else {
// Do nothing
}
}

void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glLineWidth(4);
// Draw the ball
play_ball();
drawCircle(radius,ball_x,ball_y);

glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {

drawScene();

glutPostRedisplay();
glutTimerFunc(25, update, 0);
}

void idle_func(void) {
drawScene();
}

void initRendering() {
glEnable(GL_DEPTH_TEST);

}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);

}
}

void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if (move_mag<radius-1) {
move_mag+=0.5;
}
break;
case 103: //DOWN arrow key
if (move_mag>1) {
move_mag-=0.5;
}
break;
}
}


int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(MAX_X, MAX_Y);

glutCreateWindow("Bouncing Ball");
initRendering();
init_circle();

glutDisplayFunc(drawScene);
glutSpecialFunc(specialKey);
glutReshapeFunc(handleResize);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);
glutTimerFunc(25 , update, 0);
//glutIdleFunc(idle_func);

glutMainLoop();
return 0;
}

Sunday, May 22, 2011

Brick Game part1

Hi, Here I am uploading game which i developed in openGL (motive was to kill the time on boring friday) This is very novice and still in the early in its life. This is work of just 4-5 hours. I wasted some of time just to figure out that the Image which I used for texture mapping needs to be of size 256X256 or some multiple of it. It's only after Kapil(one of my colleague) came for my rescue and we figured out the flaw. thanks Kapil! :) Once I could draw the wall of bricks i developed the logic on weekend and implemented it as first thing on monday morning. All I can say is it works! :) it can be made more efficient and more cool but I will leave that for some other day. You can download the code and make your own amendments to it. Its all free. thanks. :)


#include <iostream>
#include <stdlib.h>

#include <GL/glut.h>

#include "imageloader.h"
#include "math.h"

using namespace std;

const int MAX_X=1200;
const int MAX_Y=900;
const int MIN_X=0;
const int MIN_Y=0;
int m_x=0;
int m_y=0;
int brick_length=100,brick_width=30;

int ball_x=500;
int ball_y=500;
int radius = 20;

// BY default ball will go up
int x_dir = 1;
int y_dir = -1;
int base_y;
int base_x;
float move_mag = 5.0;

typedef struct brick {
int x;
int y;
int visible;
}BRICK;

BRICK BR[10][10];

void drawScene();

void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void init_bricks() {

// Initialise the bricks
int x=100,y=50;

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
BRICK temp;
temp.visible = 1;
temp.x = (brick_length*column)+x;
temp.y = (brick_width*row)+y;
BR[row][column] = temp;
}
}

}

void move_ball() {
ball_x = ball_x + (move_mag*x_dir);
ball_y = ball_y + (move_mag*y_dir);
}

void change_y_dir() {
y_dir = -y_dir;
}
void change_x_dir() {
x_dir = -x_dir;
}
void change_both_dir() {
change_y_dir();
change_x_dir();
}

int crossed_x_limits() {
if((ball_x-radius)<=MIN_X) {
ball_x = MIN_X+radius;
return 1;
}
if((ball_x+radius)>=MAX_X) {
ball_x = MAX_X-radius;
return 1;
}
return 0;
}


int crossed_y_limits() {
if(ball_y-radius<=MIN_Y) {
ball_y = MIN_Y+radius;
return 1;
}
if(ball_y+radius>=MAX_Y) {
ball_y = MAX_Y-radius;
return 1;
}
return 0;
}
int hit_base() {

if (ball_x>=m_x-brick_length && ball_x<=m_x+brick_length) {
if((ball_y+radius)<=MAX_Y && (ball_y+radius)>=(MAX_Y-brick_width)) {
return 1;
}
}

return 0;
}


// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;

drawScene();
}

void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if (move_mag<radius-1) {
move_mag+=0.5;
}
break;
case 103: //DOWN arrow key
if (move_mag>1) {
move_mag-=0.5;
}
break;
}
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId); //Make room for our texture
glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D
0, //0 for now
GL_RGB, //Format OpenGL uses for image
image->width, image->height, //Width and height
0, //The border of the image
GL_RGB, //GL_RGB, because pixels are stored in RGB format
GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
//as unsigned numbers
image->pixels); //The actual pixel data
return textureId; //Returns the id of the texture
}

GLuint _textureId; //The id of the texture

void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);

Image* image = loadBMP("br.bmp");
_textureId = loadTexture(image);
delete image;
}

void handleResize(int w, int h) {
/*glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);*/

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

void create_brick(int length,int width,int x, int y) {
glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(x, y, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(x+length,y,0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x+length,y-width,0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x,y-width,0);

glEnd();
}



void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=25.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}

void play_ball() {
move_ball();

if (crossed_x_limits()) {
change_x_dir();
} else if (crossed_y_limits()) {
change_y_dir();
} else {
// Do nothing
}
}

void detect_collision() {

if(hit_base()) {
change_y_dir();
return;
}

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
BRICK temp = BR[row][column];
if (temp.visible) {
int min_y = temp.y - brick_width;
int min_x = temp.x;
int max_x = temp.x + brick_length;
int max_y = temp.y ;

if ((ball_x+radius)>=min_x &&
(ball_x-radius)<=max_x &&
(ball_y+radius)>=min_y &&
(ball_y-radius)<=max_y) {
BR[row][column].visible = 0;
change_both_dir();
return;
}

}
}
}
}


void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


/*GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

GLfloat directedLight[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat directedLightPos[] = {-10.0f, 15.0f, 20.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, directedLight);
glLightfv(GL_LIGHT0, GL_POSITION, directedLightPos);*/

// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);

//Bottom
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor3f(1.0f, 0.2f, 0.2f);

// Draw the wall of bricks
int x=100,y=50;

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
if (BR[row][column].visible ==1) {
create_brick(
brick_length,
brick_width,
(brick_length*column)+x,
(brick_width*row)+y);
}
}
}

// Draw the moving support base
{
int x=m_x-brick_length,y=MAX_Y;
for(int row=0;row<1;row++) {
for(int column=0;column<2;column++) {
create_brick(
brick_length,
brick_width,
(brick_length*column)+x,
y-(brick_width*row));
}
}
}

// Draw the ball
play_ball();
drawCircle(radius,ball_x,ball_y);
detect_collision();

glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {

drawScene();

glutPostRedisplay();
glutTimerFunc(5, update, 0);
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(MAX_X, MAX_Y);

glutCreateWindow("Texture demo");
initRendering();

init_bricks();
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutSpecialFunc(specialKey);

glutReshapeFunc(handleResize);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);
glutTimerFunc(5 , update, 0);

glutMainLoop();
return 0;
}


Thursday, May 19, 2011

Using styles of lines and letting user control it



Hi,
This one you would definitely like.
A small but cute program. It lets user draw the lines and also lets user control the styles of the lines. Colors would have been even better, But for some other time.
:-)

// This program is for line drawing using opengl 
// User cn draw the lines by clicking the points in the opengl window
// User can remove the lines by pressing the right mouse button

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>
#include "math.h"

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
int poi_pattern[100];
int m_x = 0;
int m_y = 0;

int m_pattern = 0;
const int max_x = 1000;
const int max_y = 800;

int rubber_band_on = 0;
int pattern=0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}

int get_pattern(int cx,int cy) {
float y = max_y-10;
float x = max_x-10;

for(int cnt=0;cnt<7;cnt++) {
if (cx<x && cx>(x-120) && cy<y && cy>(y-30)) {
return cnt+1;
}
y-=30;
}
return 0;
}

void set_pattern(int pattern) {
switch(pattern) {
case 0: glLineStipple(1,0xffff); break;
case 1: glLineStipple(1,0x00ff); break;
case 2: glLineStipple(1,0xffff); break;
case 3: glLineStipple(1,0x0c0f); break;
case 4: glLineStipple(2,0x0c0f); break;
case 5: glLineStipple(1,0xaaaa); break;
case 6: glLineStipple(3,0xaaaa); break;
default: glLineStipple(2,0xaaaa); break;
}
}

void draw_pallet() {
float y = max_y-10;
float x = max_x-10;
glLineStipple(1,0xffff);

// two vertical lines
glBegin(GL_LINES);
glVertex2f(x,y);
glVertex2f(x,y-180);
glVertex2f(x-120,y);
glVertex2f(x-120,y-180);

glEnd();
// several horizontal lines
for(int cnt=0;cnt<7;cnt++) {
glLineStipple(1,0xffff);
glBegin(GL_LINES);
glVertex2f(x,y);
glVertex2f(x-120,y);
glEnd();

if(cnt!=6) {
set_pattern(cnt+1);
glBegin(GL_LINES);
glVertex2f(x-20,y-10);
glVertex2f(x-100,y-10);
glEnd();
}
y-=30;
}

}

void myinit() {
glEnable(GL_LINE_STIPPLE);

}

void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=1.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}


void tick(void)
{
//glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}


void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

draw_pallet();

// Draw the lines created by user
int i=0;
for(i=0; i<poi_size-1; i+=2) {
set_pattern(poi_pattern[i]);
glBegin(GL_LINES);
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
glVertex2f(poi_arr[i+1][0],poi_arr[i+1][1]);
glEnd();
}
if (rubber_band_on && (poi_size%2==1)) {
set_pattern(m_pattern);
glBegin(GL_LINES);
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
glVertex2f(m_x,m_y);
glEnd();
}

glEnd();

set_pattern(0);
// Draw small circles at the line start ane end point
for(int i=0; i<poi_size; i++) {
drawCircle(2,poi_arr[i][0],poi_arr[i][1]);
}
glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
if (poi_size>0) {
poi_size-=2;
}
rubber_band_on = 0;
glutIdleFunc(NULL);
}
break;

case GLUT_LEFT_BUTTON:
rubber_band_on = 1;
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
int pattern = get_pattern(x,y);
if (pattern) {
m_pattern = pattern;
} else {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_pattern[poi_size] = m_pattern;
poi_size++;
}
down_flag = 0;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("OPENGL LINE DRAWING");
glClearColor(0.0, 0.0, 0.0, 1.0);

myinit();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Interactive circle drawing




Below program will let you draw the circle wherever you want and of whatever radius you want it to be.


// This program is for line drawing using opengl 
// User cn draw the lines by clicking the points in the opengl window
// User can remove the lines by pressing the right mouse button

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>
#include "math.h"

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
float rad_arr[50];
int m_x = 0;
int m_y = 0;

int rubber_band_on = 0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}

void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=1.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}


void tick(void)
{
//glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

float calculate_radius(int x1,int y1) {
int x_diff = m_x - x1;
int y_diff = m_y - y1;
if(x_diff<0) {
x_diff *= -1;
}
if(y_diff<0) {
y_diff *= -1;
}
float mag = x_diff*x_diff + y_diff*y_diff;
float rad = sqrt(mag);
return rad;
}

void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

// Draw the circles at the existing positions
for(int i=0; i<poi_size; i+=2) {
int rad_index = (int)(i/2);
float rad = rad_arr[rad_index];
if (rad>1) {
drawCircle(rad,poi_arr[i][0],poi_arr[i][1]);
}
}

glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
if (rubber_band_on) {
float rd = calculate_radius(poi_arr[poi_size-1][0],poi_arr[poi_size-1][1]);
rad_arr[poi_size/2] = rd;
}
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
glutIdleFunc(NULL);
}
break;
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_size++;
down_flag = 0;
rubber_band_on = !rubber_band_on;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}

if (rubber_band_on && poi_size>0) {
float rd = calculate_radius(poi_arr[poi_size-1][0],poi_arr[poi_size-1][1]);
rad_arr[poi_size/2] = rd;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("OPENGL CIRCLE DRAWING");
glClearColor(0.0, 0.0, 0.0, 1.0);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Interactive Line drawing in openGL



This is simple program based on the mouse inputs.
Using mouse inputs user can draw the lines in the opengl window.
Since the world space is same as that of the device space we dont have to worry about the
convertion here and that makes this program simple.

Still in the 2D world. :-)

// This program is for line drawing using opengl 
// User cn draw the lines by clicking the points in the opengl window
// User can remove the lines by pressing the right mouse button

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>
#include "math.h"

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
int m_x = 0;
int m_y = 0;

int rubber_band_on = 0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}

void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=1.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}


void tick(void)
{
glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

// Draw the lines created by user
glBegin(GL_LINES);
for(int i=0; i<poi_size; i++) {
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
}
if (rubber_band_on && (poi_size%2==1)) {
glVertex2f(m_x,m_y);
}

glEnd();

// Draw small circles at the line start ane end point
for(int i=0; i<poi_size; i++) {
drawCircle(2,poi_arr[i][0],poi_arr[i][1]);
}
glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
if (poi_size>0) {
poi_size-=2;
}
rubber_band_on = 0;
glutIdleFunc(NULL);
}
break;
case GLUT_LEFT_BUTTON:
rubber_band_on = 1;
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_size++;
down_flag = 0;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("OPENGL LINE DRAWING");
glClearColor(0.0, 0.0, 0.0, 1.0);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Wednesday, May 18, 2011

Mouse programming in opengl


Hushh.. Finally I could get the mouse working in my opengl programs.
Here is the program which will let you use the mouse to enter the coordinates in opengl window. This is very useful template program to do various graphics assignment.


// text1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
int m_x = 0;
int m_y = 0;

int rubber_band_on = 0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}


void selectColor(int color)
{
switch (color) {
case 1:
glColor3f(0.0, 1.0, 0.0);
break;
case 2:
glColor3f(1.0, 0.0, 0.0);
break;
case 3:
glColor3f(1.0, 1.0, 1.0);
break;
}
glutPostRedisplay();
}

void tick(void)
{
glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

// Draw the lines created by user
glBegin(GL_LINE_STRIP);
for(int i=0; i<poi_size; i++) {
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
}
if (rubber_band_on) {
glVertex2f(m_x,m_y);
}

glEnd();

glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
if (rubber_band_on == 0) {
poi_size--;
}
rubber_band_on = 0;
glutIdleFunc(NULL);
}
break;
case GLUT_LEFT_BUTTON:
rubber_band_on = 1;
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_size++;
down_flag = 0;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("GLUT Mouse example");
glClearColor(0.0, 0.0, 0.0, 1.0);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}