//-----------------------------------------------------------------------------
// Velmi jednoduchy prohlizec souboru typu DXF upraveny pro zobrazeni
// zakladnich 3D entit - 3DFACE
//
// Autor: Pavel Tisnovsky
//
//-----------------------------------------------------------------------------
#ifdef __BORLANDC__
#include <windows.h>
#endif
#include <GL/glut.h> // hlavickovy soubor funkci GLUTu a OpenGL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#define WINDOW_TITLE "simple DXF 3D viewer" // titulek okna
#define WINDOW_WIDTH 800 // pocatecni velikost okna
#define WINDOW_HEIGHT 600
#define MAX_LINE_LENGTH 1024
#define MAX_TEXT_LENGTH 256
void callback_begin_header(char *input);
void callback_end_header(char *input);
void callback_begin_blocks(char *input);
void callback_end_blocks(char *input);
void callback_begin_entities(char *input);
void callback_end_entities(char *input);
void callback_3dface_setcolor(char *input);
void callback_3dface_setlayer(char *input);
void callback_3dface_set_x1(char *input);
void callback_3dface_set_y1(char *input);
void callback_3dface_set_z1(char *input);
void callback_3dface_set_x2(char *input);
void callback_3dface_set_y2(char *input);
void callback_3dface_set_z2(char *input);
void callback_3dface_set_x3(char *input);
void callback_3dface_set_y3(char *input);
void callback_3dface_set_z3(char *input);
void callback_3dface_set_x4(char *input);
void callback_3dface_set_y4(char *input);
void callback_3dface_set_z4(char *input);
void callback_3dface_color(char *input);
void callback_3dface_layer(char *input);
void callback_3dface_x1(char *input);
void callback_3dface_y1(char *input);
void callback_3dface_z1(char *input);
void callback_3dface_x2(char *input);
void callback_3dface_y2(char *input);
void callback_3dface_z2(char *input);
void callback_3dface_x3(char *input);
void callback_3dface_y3(char *input);
void callback_3dface_z3(char *input);
void callback_3dface_x4(char *input);
void callback_3dface_y4(char *input);
void callback_3dface_z4(char *input);
void callback_3dface_store(char *input);
// graficke entity {{{
typedef struct Gfx3Dface {
int color;
int layer;
double x1;
double y1;
double z1;
double x2;
double y2;
double z2;
double x3;
double y3;
double z3;
double x4;
double y4;
double z4;
} Gfx3Dface;
// }}}
// linearni seznam s entitami {{{
typedef struct Item {
Gfx3Dface *entity;
struct Item *next; // vazba v linearnim seznamu
} Item;
// }}}
// stavy KA {{{
typedef enum t_dxf_status {
Unknown,
Delimiter,
Section,
SecName,
Header,
Blocks,
Entities,
Face,
FaceLayer,
FaceColor,
FaceX1,
FaceY1,
FaceZ1,
FaceX2,
FaceY2,
FaceZ2,
FaceX3,
FaceY3,
FaceZ3,
FaceX4,
FaceY4,
FaceZ4,
End
} t_dxf_status;
// }}}
// prechod mezi stavy KA {{{
typedef struct t_transition {
t_dxf_status status;
char *input;
t_dxf_status newStatus;
void (*fce)(char *input);
} t_transition;
// }}}
// vlastni konfigurace KA {{{
static const t_transition transitions[]={
{Unknown, " 0", Delimiter, NULL},
{Delimiter, "SECTION", Section, NULL},
{Section, " 2", SecName, NULL},
{SecName, "HEADER", Header, callback_begin_header},
{SecName, "BLOCKS", Blocks, callback_begin_blocks},
{SecName, "ENTITIES", Entities, callback_begin_entities},
{Header, " 0", Header, NULL},
{Header, "ENDSEC", Unknown, callback_end_header},
{Blocks, " 0", Blocks, NULL},
{Blocks, "ENDSEC", Unknown, callback_end_blocks},
{Entities, " 0", Entities, NULL},
{Entities, "ENDSEC", Unknown, callback_end_entities},
{Entities, "3DFACE", Face, NULL},
{Face, " 8", FaceLayer, callback_3dface_layer},
{Face, " 62", FaceColor, callback_3dface_color},
{Face, " 10", FaceX1, callback_3dface_x1},
{Face, " 20", FaceY1, callback_3dface_y1},
{Face, " 30", FaceZ1, callback_3dface_z1},
{Face, " 11", FaceX2, callback_3dface_x2},
{Face, " 21", FaceY2, callback_3dface_y2},
{Face, " 31", FaceZ2, callback_3dface_z2},
{Face, " 12", FaceX3, callback_3dface_x3},
{Face, " 22", FaceY3, callback_3dface_y3},
{Face, " 32", FaceZ3, callback_3dface_z3},
{Face, " 13", FaceX4, callback_3dface_x4},
{Face, " 23", FaceY4, callback_3dface_y4},
{Face, " 33", FaceZ4, callback_3dface_z4},
{Face, " 0", Entities, callback_3dface_store},
{End, "", End, NULL} // jen ukonceni pro pruchod stavy KA
};
// }}}
// informace o okne {{{
struct {
int width;
int height;
} window={WINDOW_WIDTH, WINDOW_HEIGHT};
// }}}
// informace o mysi {{{
enum { // operace, ktere se mohou provadet s mysi:
ROTATE, // rotace objektu
TRANSLATE, // posun objektu
} operation=ROTATE;
int xnew=0, ynew=0, znew=20; // soucasna pozice mysi, ze ktere se pocitaji rotace a posuvy
int xold=0, yold=0, zold=20; // minula pozice mysi, ze ktere se pocitaji rotace a posuvy
int xx, yy, zz; // bod, ve kterem se nachazi kurzor mysi
// }}}
// globalni promenne {{{
// parametry, ktere ovlivnuji osvetleni
GLfloat materialAmbient[]={0.4f, 0.4f, 0.4f, 1.0f}; // ambientni slozka barvy materialu
GLfloat materialDiffuse[]={0.8f, 0.4f, 0.4f, 1.0f}; // difuzni slozka barvy materialu
GLfloat materialSpecular[]={1.0f, 1.0f, 1.0f, 1.0f}; // barva odlesku
GLfloat materialShininess[]={50.0f}; // faktor odlesku
GLfloat light_position1[]={1.0f, 0.0f, 1.0f, 1.0f}; // pozice prvniho svetla
GLfloat light_position2[]={0.0f, 1.0f,100.0f, 1.0f}; // pozice druheho svetla
GLfloat light_color1[]={1.0f, 1.0f, 1.0f}; // barva prvniho svetla
GLfloat light_color2[]={1.0f, 1.0f, 0.0f}; // barva druheho svetla
int redraw=1;
void (*special_callback)(char *input)=NULL;
t_dxf_status status=Unknown; // inicializace KA
Item *p_first; // ukazatele v linearnim seznamu
Item *p_last;
Gfx3Dface g_face; // pomocne entity pro postupne naplnovani
int colorStyle=1;
// }}}
// initItem() {{{
//-----------------------------------------------------------------------------
// Inicializace linearniho seznamu
//-----------------------------------------------------------------------------
void initItem(void)
{
p_first=NULL;
p_last=NULL;
}
// }}}
// addItem() {{{
//-----------------------------------------------------------------------------
// Vlozeni polozky do linearniho seznamu
//-----------------------------------------------------------------------------
void addItem(Gfx3Dface *entity)
{
Item *item=(Item*)malloc(sizeof(Item));
item->entity=entity;
item->next=NULL; // prvek bude umisten na konci seznamu
// seznam je prazdny
if (p_first==NULL) {
p_first=item; // prvni i posledni prvek
p_last=item; // seznamu jsou shodne
}
// pridani polozky do neprazdneho seznamu
else {
p_last->next=item; // zretezeni prvku na konec seznamu
p_last=item; // aktualizace ukazatele na posledni prvek
/*
Item *p=p_first;
while (p->next !=NULL)
p=p->next;
p->next=item;
*/
}
}
// }}}
// callback_begin_header() {{{
void callback_begin_header(char *input)
{
puts(" begin header");
}
// }}}
// callback_end_header() {{{
void callback_end_header(char *input)
{
puts(" end header");
}
// }}}
// callback_begin_blocks() {{{
void callback_begin_blocks(char *input)
{
puts(" begin blocks");
}
// }}}
// callback_end_blocks() {{{
void callback_end_blocks(char *input)
{
puts(" end blocks");
}
// }}}
// callback_begin_entities() {{{
void callback_begin_entities(char *input)
{
puts(" begin entities");
}
// }}}
// callback_end_entities() {{{
void callback_end_entities(char *input)
{
puts(" end entities");
}
// }}}
// callback_3dface_setcolor() {{{
void callback_3dface_setcolor(char *input)
{
g_face.color=atoi(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_setlayer() {{{
void callback_3dface_setlayer(char *input)
{
int i, j;
// velmi primitivni vypocet hashe
for (i=0, j=0; input[i]; i++)
j+=input[i];
g_face.layer=j;
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_x1() {{{
void callback_3dface_set_x1(char *input)
{
g_face.x1=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_y1() {{{
void callback_3dface_set_y1(char *input)
{
g_face.y1=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_z1() {{{
void callback_3dface_set_z1(char *input)
{
g_face.z1=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_x2() {{{
void callback_3dface_set_x2(char *input)
{
g_face.x2=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_y2() {{{
void callback_3dface_set_y2(char *input)
{
g_face.y2=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_z2() {{{
void callback_3dface_set_z2(char *input)
{
g_face.z2=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_x3() {{{
void callback_3dface_set_x3(char *input)
{
g_face.x3=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_y3() {{{
void callback_3dface_set_y3(char *input)
{
g_face.y3=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_z3() {{{
void callback_3dface_set_z3(char *input)
{
g_face.z3=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_x4() {{{
void callback_3dface_set_x4(char *input)
{
g_face.x4=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_y4() {{{
void callback_3dface_set_y4(char *input)
{
g_face.y4=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_set_z4() {{{
void callback_3dface_set_z4(char *input)
{
g_face.z4=atof(input);
special_callback=NULL;
status=Face;
}
// }}}
// callback_3dface_color() {{{
void callback_3dface_color(char *input)
{
special_callback=callback_3dface_setcolor;
}
// }}}
// callback_3dface_layer() {{{
void callback_3dface_layer(char *input)
{
special_callback=callback_3dface_setlayer;
}
// }}}
// callback_3dface_x1() {{{
void callback_3dface_x1(char *input)
{
special_callback=callback_3dface_set_x1;
}
// }}}
// callback_3dface_y1() {{{
void callback_3dface_y1(char *input)
{
special_callback=callback_3dface_set_y1;
}
// }}}
// callback_3dface_z1() {{{
void callback_3dface_z1(char *input)
{
special_callback=callback_3dface_set_z1;
}
// }}}
// callback_3dface_x2() {{{
void callback_3dface_x2(char *input)
{
special_callback=callback_3dface_set_x2;
}
// }}}
// callback_3dface_y2() {{{
void callback_3dface_y2(char *input)
{
special_callback=callback_3dface_set_y2;
}
// }}}
// callback_3dface_z2() {{{
void callback_3dface_z2(char *input)
{
special_callback=callback_3dface_set_z2;
}
// }}}
// callback_3dface_x3() {{{
void callback_3dface_x3(char *input)
{
special_callback=callback_3dface_set_x3;
}
// }}}
// callback_3dface_y3() {{{
void callback_3dface_y3(char *input)
{
special_callback=callback_3dface_set_y3;
}
// }}}
// callback_3dface_z3() {{{
void callback_3dface_z3(char *input)
{
special_callback=callback_3dface_set_z3;
}
// }}}
// callback_3dface_x4() {{{
void callback_3dface_x4(char *input)
{
special_callback=callback_3dface_set_x4;
}
// }}}
// callback_3dface_y4() {{{
void callback_3dface_y4(char *input)
{
special_callback=callback_3dface_set_y4;
}
// }}}
// callback_3dface_z4() {{{
void callback_3dface_z4(char *input)
{
special_callback=callback_3dface_set_z4;
}
// }}}
// callback_3dface_store() {{{
void callback_3dface_store(char *input)
{
Gfx3Dface *g=(Gfx3Dface *)malloc(sizeof(Gfx3Dface));
g->x1=g_face.x1;
g->y1=g_face.y1;
g->z1=g_face.z1;
g->x2=g_face.x2;
g->y2=g_face.y2;
g->z2=g_face.z2;
g->x3=g_face.x3;
g->y3=g_face.y3;
g->z3=g_face.z3;
g->x4=g_face.x4;
g->y4=g_face.y4;
g->z4=g_face.z4;
g->color=g_face.color;
g->layer=g_face.layer;
addItem(g);
}
// }}}
// doConvert() {{{
// ---------------------------------------------------------------------
// Nacteni obsahu souboru DXF a konverze do internich datovych struktur
// ---------------------------------------------------------------------
int doConvert(char *fileName)
{
#define MIN 1e-10
#define MAX 1e+10
// makra pro zjisteni maxima a minima
#define SET_MIN(a, min) if ((a)<(min)) (min)=(a)
#define SET_MAX(a, max) if ((a)>(max)) (max)=(a)
FILE *fin;
char line[MAX_LINE_LENGTH];
int lines=0;
int t;
Item *item;
double xmin=MAX, xmax=MIN, ymin=MAX, ymax=MIN, zmin=MAX, zmax=MIN;
double x0, y0, z0;
fin=fopen(fileName, "rt"); // otevreni vstupniho souboru
if (!fin) return 0;
while (fgets(line, MAX_LINE_LENGTH, fin)) { // projit vsechny radky
lines++;
line[strlen(line)-1]=0; // oriznout <CR>
if (special_callback!=NULL) { // specialni callback funkce -> nacteni atributu
special_callback(line);
}
else { // normalni callback funkce -> prechod KA
for (t=0; transitions[t].status!=End; t++) {
if ((status==transitions[t].status) && (!strcmp(transitions[t].input, line))) {
if (transitions[t].fce!=NULL) transitions[t].fce(line);
status=transitions[t].newStatus;
break;
}
}
}
}
printf("done %d lines\n", lines);
fclose(fin);
// uprava stredu 3D modelu
item=p_first;
while (item!=NULL) {
SET_MIN(item->entity->x1, xmin); SET_MAX(item->entity->x1, xmax);
SET_MIN(item->entity->x2, xmin); SET_MAX(item->entity->x2, xmax);
SET_MIN(item->entity->x3, xmin); SET_MAX(item->entity->x3, xmax);
SET_MIN(item->entity->x4, xmin); SET_MAX(item->entity->x4, xmax);
SET_MIN(item->entity->y1, ymin); SET_MAX(item->entity->y1, ymax);
SET_MIN(item->entity->y2, ymin); SET_MAX(item->entity->y2, ymax);
SET_MIN(item->entity->y3, ymin); SET_MAX(item->entity->y3, ymax);
SET_MIN(item->entity->y4, ymin); SET_MAX(item->entity->y4, ymax);
SET_MIN(item->entity->z1, zmin); SET_MAX(item->entity->z1, zmax);
SET_MIN(item->entity->z2, zmin); SET_MAX(item->entity->z2, zmax);
SET_MIN(item->entity->z3, zmin); SET_MAX(item->entity->z3, zmax);
SET_MIN(item->entity->z4, zmin); SET_MAX(item->entity->z4, zmax);
item=item->next;
}
printf("Boundary: [%f, %f, %f] - [%f, %f, %f]\n", xmin, ymin, zmin, xmax, ymax, zmax);
// vypocet stredu objektu
x0=(xmax+xmin)/2.0;
y0=(ymax+ymin)/2.0;
z0=(zmax+zmin)/2.0;
printf("Center: [%f, %f, %f]\n", x0, y0, z0);
// vycentrovani obrazku
item=p_first;
while (item!=NULL) {
item->entity->x1-=x0;
item->entity->x2-=x0;
item->entity->x3-=x0;
item->entity->x4-=x0;
item->entity->y1-=y0;
item->entity->y2-=y0;
item->entity->y3-=y0;
item->entity->y4-=y0;
item->entity->z1-=z0;
item->entity->z2-=z0;
item->entity->z3-=z0;
item->entity->z4-=z0;
item=item->next;
}
return 1;
}
// }}}
// setColor() {{{
//-----------------------------------------------------------------------------
// nastaveni barvy vykreslovani
//-----------------------------------------------------------------------------
void setColor(int color)
{
// velmi zjednodusena paleta
static float palette[][3]={
{1.0, 1.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 1.0, 0.0},
{0.0, 1.0, 1.0},
{1.0, 0.0, 0.0},
{1.0, 0.0, 1.0},
{1.0, 1.0, 0.0},
{0.5, 0.5, 0.5},
};
float r, g, b;
r=palette[color & 0x07][0];
g=palette[color & 0x07][1];
b=palette[color & 0x07][2];
glColor3f(r, g, b);
}
// }}}
// setPerspectiveProjection() {{{
//---------------------------------------------------------------------
// Nastaveni perspektivni projekce
//---------------------------------------------------------------------
void setPerspectiveProjection(void)
{
glMatrixMode(GL_PROJECTION); // zacatek modifikace projekcni matice
glLoadIdentity(); // vymazani projekcni matice (=identita)
gluPerspective(70.0, (double)window.width/(double)window.height, 0.1f, 10000.0f);// nastaveni perspektivni kamery
glMatrixMode(GL_MODELVIEW); // bude se menit modelova matice
glLoadIdentity(); // nahrat jednotkovou matici
}
// }}}
// drawFace() {{{
//-----------------------------------------------------------------------------
// vykresleni entity 3D face
//-----------------------------------------------------------------------------
void drawFace(Gfx3Dface *g)
{
if (colorStyle)
setColor(g->color);
else
setColor(g->layer);
glBegin(GL_TRIANGLES);
glVertex3d(g->x1, g->y1, g->z1);
glVertex3d(g->x2, g->y2, g->z2);
glVertex3d(g->x3, g->y3, g->z3);
glVertex3d(g->x1, g->y1, g->z1);
glVertex3d(g->x3, g->y3, g->z3);
glVertex3d(g->x4, g->y4, g->z4);
glEnd();
}
// }}}
// redrawDrawing() {{{
//-----------------------------------------------------------------------------
// Prekresleni vektorove kresby
//-----------------------------------------------------------------------------
void redrawDrawing()
{
Item *item=p_first;
// projit celym seznamem a aplikovat v nem ulozene prikazy
while (item!=NULL) {
drawFace(item->entity);
item=item->next;
}
}
// }}}
// onInit() {{{
//-----------------------------------------------------------------------------
// Funkce volana pro inicializaci vykreslovani
//-----------------------------------------------------------------------------
void onInit(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // barva pozadi obrazku
glClearDepth(1.0f); // implicitni hloubka ulozena v pameti hloubky
glDepthFunc(GL_LESS); // funkce pro testovani fragmentu
glShadeModel(GL_SMOOTH); // nastaveni stinovaciho rezimu
glPolygonMode(GL_FRONT, GL_FILL); // nastaveni rezimu vykresleni modelu
glPolygonMode(GL_BACK, GL_FILL); // jak pro predni tak pro zadni steny
glDisable(GL_CULL_FACE); // zadne hrany ani steny se nebudou odstranovat
glMaterialfv(GL_FRONT, GL_AMBIENT, materialAmbient); // nastaveni ambientni slozky barvy materialu
glMaterialfv(GL_FRONT, GL_DIFFUSE, materialDiffuse); // nastaveni difuzni slozky barvy materialu
glMaterialfv(GL_FRONT, GL_SPECULAR, materialSpecular); // nastaveni barvy odlesku
glMaterialfv(GL_FRONT, GL_SHININESS, materialShininess);// nastaveni faktoru odlesku
glLightfv(GL_LIGHT0, GL_POSITION, light_position1); // nastaveni pozice prvniho svetla
glLightfv(GL_LIGHT1, GL_POSITION, light_position2); // nastaveni pozice druheho svetla
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color1); // nastaveni barvy prvniho svetla
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_color2); // nastaveni barvy druheho svetla
glEnable(GL_LIGHTING); // globalni povoleni stinovani
glEnable(GL_LIGHT0); // povoleni prvniho svetla
glEnable(GL_LIGHT1); // povoleni prvniho svetla
}
// }}}
// onResize() {{{
//-----------------------------------------------------------------------------
// Nastaveni souradneho systemu v zavislosti na velikosti okna
//-----------------------------------------------------------------------------
void onResize(int w, int h) // argumenty w a h reprezentuji novou velikost okna
{
glViewport(0, 0, w, h); // viditelna oblast pres cele okno
window.width=w;
window.height=h;
}
// }}}
// onDisplay() {{{
//-----------------------------------------------------------------------------
// Tato callback funkce je zavolana pri kazdem prekresleni okna
//-----------------------------------------------------------------------------
void onDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // vymazani vsech bitovych rovin barvoveho bufferu
setPerspectiveProjection(); // nastaveni perspektivni kamery
glTranslatef(0.0f, 0.0f, -50.0f); // posun objektu dale od kamery
glTranslatef(0.0f, 0.0f, znew); // priblizeni ci vzdaleni objektu podle pohybu kurzoru mysi
glRotatef(ynew, 1.0f, 0.0f, 0.0f); // rotace objektu podle pohybu kurzoru mysi
glRotatef(xnew, 0.0f, 1.0f, 0.0f);
// glScalef(0.1, 0.1, 0.1);
//glPushMatrix(); // ulozeni matice na zasobnik a zmena pozice druheho svetla
//glLightfv(GL_LIGHT1, GL_POSITION, light_position2);
//glPopMatrix();
redrawDrawing(); // vykresleni objektu
glFlush(); // provedeni a vykresleni vsech zmen
glutSwapBuffers(); // a prohozeni predniho a zadniho bufferu
}
// }}}
// onKeyboard() {{{
//-----------------------------------------------------------------------------
// Tato callback funkce je zavolana pri stlaceni ASCII klavesy
//-----------------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par
#endif
void onKeyboard(unsigned char key, int x, int y)
{
key=(key>='A' && key<='Z') ? key-'A'+'a': key;
if (key>='0' && key<='9') { glutPostRedisplay(); } // nastaveni barvove palety
switch (key) {
case 27: // pokud byla stlacena klavesa ESC, konec programu
case 'q': exit(0); break; // totez co klavesa ESC
case 'l': colorStyle=0; glutPostRedisplay(); break; // barvy podle hashe hladiny
case 'c': colorStyle=1; glutPostRedisplay(); break; // barvy podle informaci z DXF
case '1': glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); glutPostRedisplay(); break;
case '2': glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glutPostRedisplay(); break;
case '3': glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glutPostRedisplay(); break;
case '4': glEnable(GL_DEPTH_TEST); glutPostRedisplay(); break;
case '5': glDisable(GL_DEPTH_TEST); glutPostRedisplay(); break;
case '6': glEnable(GL_LIGHTING); glutPostRedisplay(); break;
case '7': glDisable(GL_LIGHTING); glutPostRedisplay(); break;
default: break;
}
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// onSpecial() {{{
//-----------------------------------------------------------------------------
// Tato callback funkce je zavolana pri stlaceni non-ASCII klavesy
//-----------------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par
#endif
void onSpecial(int key, int x, int y)
{
// posun kresby a zmena meritka
switch (key) {
/*
case GLUT_KEY_LEFT: xpos-=25; redraw=1; glutPostRedisplay(); break;
case GLUT_KEY_RIGHT: xpos+=25; redraw=1; glutPostRedisplay(); break;
case GLUT_KEY_UP: ypos+=25; redraw=1; glutPostRedisplay(); break;
case GLUT_KEY_DOWN: ypos-=25; redraw=1; glutPostRedisplay(); break;
case GLUT_KEY_PAGE_UP: scale*=1.1; redraw=1; glutPostRedisplay(); break;
case GLUT_KEY_PAGE_DOWN: scale/=1.1; redraw=1; glutPostRedisplay(); break;*/
default: break;
}
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// onMouse() {{{
//-----------------------------------------------------------------------------
// Tato callback funkce je zavolana pri stlaceni ci pusteni tlacitka mysi
//-----------------------------------------------------------------------------
void onMouse(int button, int state, int x, int y)
{
if (button==GLUT_LEFT_BUTTON) { // pri zmene stavu leveho tlacitka
operation=ROTATE;
if (state==GLUT_DOWN) { // pri stlaceni tlacitka
xx=x; // zapamatovat pozici kurzoru mysi
yy=y;
}
else { // pri pusteni tlacitka
xold=xnew; // zapamatovat novy pocatek
yold=ynew;
}
glutPostRedisplay(); // prekresleni sceny
}
if (button==GLUT_RIGHT_BUTTON) {
operation=TRANSLATE;
if (state==GLUT_DOWN) zz=y; // pri stlaceni tlacitka zapamatovat polohu kurzoru mysi
else zold=znew; // pri pusteni tlacitka zapamatovat novy pocatek
glutPostRedisplay(); // prekresleni sceny
}
}
// }}}
// onMouseMotion() {{{
//-----------------------------------------------------------------------------
// Tato callback funkce je zavolana pri posunu kurzoru mysi
//-----------------------------------------------------------------------------
void onMouseMotion(int x, int y)
{
switch (operation) {
case ROTATE: // stav rotace objektu
xnew=xold+x-xx; // vypocitat novou pozici
ynew=yold+y-yy;
glutPostRedisplay(); // a prekreslit scenu
break;
case TRANSLATE: // stav priblizeni/oddaleni objektu
znew=zold+y-zz; // vypocitat novou pozici
glutPostRedisplay(); // a prekreslit scenu
break;
}
}
// }}}
// main() {{{
//-----------------------------------------------------------------------------
// Hlavni funkce konzolove aplikace
//-----------------------------------------------------------------------------
int main(int argc, char **argv)
{
glutInit(&argc, argv); // inicializace knihovny GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow(WINDOW_TITLE); // vytvoreni okna pro kresleni
glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);// zmena velikosti okna
glutPositionWindow(100, 100); // pozice leveho horniho rohu okna
glutDisplayFunc(onDisplay); // registrace funkce volane pri prekreslovani okna
glutReshapeFunc(onResize); // registrace funkce volane pri zmene velikosti okna
glutKeyboardFunc(onKeyboard); // registrace funkce volane pri stlaceni klavesy
glutSpecialFunc(onSpecial); // registrace funkce volane pri stlaceni specialni klavesy
glutMouseFunc(onMouse); // funkce volana pri stlaceni tlacitka mysi
glutMotionFunc(onMouseMotion); // funkce volana pri posunu mysi
onInit(); // inicializace vykreslovani
if (!doConvert(argv[1])) { // nacteni celeho souboru s kresbou
puts("Nacteni souboru selhalo!\nUkonceni prohlizece...\n");
return 0;
}
glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane funkce
return 0; // navratova hodnota vracena operacnimu systemu
}
// }}}
//-----------------------------------------------------------------------------
// finito
//-----------------------------------------------------------------------------
// vim: foldmethod=marker