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. */
}


No comments:

Post a Comment