//-----------------------------------------------------------------------------
// Fraktaly v pocitacove grafice
// Autor: Pavel Tisnovsky
//
// Vykresleni trojrozmernych fraktalnich obrazcu pomoci algoritmu pro tvorbu
// systemu iterovanych funkci IFS. Pomoci mysi je mozne vytvorenym trojrozmernym
// modelem natacet a pohybovat s nim. Klavesove zkratky urcene k ovladani
// tohoto programu jsou popsany primo v clanku.
// Ukonceni aplikace se provede klavesou [Esc] nebo klavesou [Q].
//-----------------------------------------------------------------------------
#ifdef __BORLANDC__
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <GL/glut.h>
#define SURFEL_LIST_FLOAT 1
#define FONT GLUT_BITMAP_8_BY_13
#define WINDOW_WIDTH 620
#define WINDOW_HEIGHT 460
#define WINDOW_LEFT 10
#define WINDOW_TOP 10
#define WINDOW_TITLE "Fraktaly 40.1 - trojrozmerne IFS author: Pavel Tisnovsky"
#define MIN(A,B) ((A)<(B))?(A):(B)
#define MAX(A,B) ((A)>(B))?(A):(B)
#define PI 3.14159279
#define PI2 PI*2.0
#define MINX 0.0
#define MAXX 100.0
#define MINY 0.0
#define MAXY 100.0
#define MINZ 0.0
#define MAXZ 100.0
#define ORIGIN_X (MINX+MAXX)/2.0
#define ORIGIN_Y (MINY+MAXY)/2.0
#define ORIGIN_Z (MINZ+MAXZ)/2.0
#define RANGE_X (MAXX-MINX)
#define RANGE_Y (MAXY-MINY)
#define RANGE_Z (MAXZ-MINZ)
#define RADIUS_X (RANGE_X)/2.0
#define RADIUS_Y (RANGE_Y)/2.0
#define RADIUS_Z (RANGE_Z)/2.0
#define RADIUS_T 16
#ifdef HOTKEYS
#define _ "&"
#else
#define _
#endif
#ifdef nil
#undef nil
#endif
#define nil NULL
#ifndef __cplusplus
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#endif
// typedefs {{{
typedef struct TagGpeMenu {
char *caption;
int id;
struct TagGpeMenu *subMenu;
} GpeMenu;
typedef struct Mouse {
int xnew, ynew, znew;
int xold, yold, zold;
int x1, y1, z1;
int status;
int xtran0, ytran0;
int xtran1, ytran1;
int xtran2, ytran2;
} Mouse;
typedef struct View {
float fov;
float nearPlane;
float farPlane;
int windowWidth;
int windowHeight;
int surfelsSize;
int help;
int info;
int axis;
int shading;
int zBuffer;
} View;
typedef struct Object {
int type;
int size;
float colorR;
float colorG;
float colorB;
float alpha;
int blending;
int surfelList;
} Object;
typedef struct ScrollBar{
int xmin;
int xmax;
int ymin;
int ymax;
int position;
} Scrollbar;
typedef struct ButtonStruct {
void (*callback)(void);
int menu;
int xmin;
int xmax;
int ymin;
int ymax;
} ButtonStruct;
typedef enum Commands {
CommandNone=0,
CommandModelPyramid=0,
CommandModelTetrahedron1,
CommandModelTetrahedron2,
CommandModelHexahedron,
CommandModelCube,
CommandModelOctahedron,
CommandModelDuodecahedron,
CommandModelFern,
CommandModelWing,
CommandModelLeaf,
CommandModelBush,
CommandModelFlash,
CommandModelTower,
CommandModelArtefact1,
CommandModelArtefact2,
CommandModelArtefact3,
CommandModelArtefact4,
CommandModelArtefact5,
CommandModelArtefact6,
CommandModelArtefact7,
CommandSurfelCount100,
CommandSurfelCount400,
CommandSurfelCount625,
CommandSurfelCount2500,
CommandSurfelCount10000,
CommandSurfelCount22500,
CommandSurfelCount40000,
CommandSurfelCount62500,
CommandSurfelSize1,
CommandSurfelSize2,
CommandSurfelSize3,
CommandSurfelSize4,
CommandSurfelSize5,
CommandSurfelSize6,
CommandSurfelSize7,
CommandSurfelSize8,
CommandSurfelSize9,
CommandBlendingEnable,
CommandBlendingDisable,
CommandBlending01,
CommandBlending02,
CommandBlending03,
CommandBlending04,
CommandBlending05,
CommandBlending06,
CommandBlending07,
CommandBlending08,
CommandBlending09,
CommandBlending10,
CommandSavePositions,
CommandSavePositionsSize,
CommandShadingNone,
CommandShadingX,
CommandShadingY,
CommandShadingZ,
CommandShadingFog,
CommandZBufferEnable,
CommandZBufferDisable,
CommandRedraw,
CommandShowAxis,
CommandHideAxis,
CommandShowHelp,
CommandHideHelp,
CommandShowInfo,
CommandHideInfo,
CommandViewOriginal,
CommandViewTop,
CommandViewBottom,
CommandViewLeft,
CommandViewRight,
CommandSettingsReset,
CommandSettingsLoad,
CommandSettingsSave,
CommandSettingsSurfelsCount,
CommandSettingsModelForeground,
CommandSettingsModelBackground,
CommandSettingsFogColor,
CommandSettingsAxesColor,
CommandSettingsActiveItemColor,
CommandSettingsHelpForeground,
CommandSettingsHelpBackground,
CommandSettingsInfoForeground,
CommandSettingsInfoBackground,
CommandSettingsScrollBarColor,
CommandQuitYes,
CommandQuitNo
} MenuCommands;
typedef struct Vector3f {
float x;
float y;
float z;
} Vector3f;
typedef struct SurfelF {
Vector3f position;
Vector3f normal;
unsigned char size;
unsigned int color;
} SurfelF;
typedef struct SurfelList {
int type;
int itemsCount;
int currentItem;
union {
SurfelF *itemsF;
} items;
} SurfelList;
// }}}
// function headers {{{
void confInit(View *view, Scrollbar *scrollbar, Mouse *mouse, int *settings, int *activeItem);
int inButton(const ButtonStruct buttons[], const int i, const int x, const int y);
int inMainMenuButton(int x, int y);
int inScrollbar(Scrollbar *s, int x, int y);
void setMenuForButton(const ButtonStruct buttons[], const int x, const int y);
void setMenuForMainButton(int x, int y);
void processScrollbars(int x, int y);
void processLeftMouseButton(const ButtonStruct buttons[], const int state, const int x, const int y);
void processRightMouseButton(int state, int x, int y);
GLfloat *getAxisColor(void);
GLfloat *getHelpColor(void);
GLfloat *getInfoColor(void);
GLfloat *getModelColor(void);
GLfloat *getActiveItemColor(void);
GLfloat *getScrollBarColor(void);
GLfloat *getHelpBackground(void);
GLfloat *getInfoBackground(void);
GLfloat *getModelBackground(void);
GLfloat *getFogColor(void);
void setModelAlpha(GLfloat alpha);
void getCurrentColor(GLfloat *r, GLfloat *g, GLfloat *b, GLfloat *a);
void setCurrentColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
void settingsReset(void);
void settingsLoad(void);
void settingsSave(void);
float arandom(float max);
void objectInit(Object *o);
void objectCreate(Object *o, int type, int grid);
void objectDestroy(Object *o);
void objectSizeMove(Object *o);
void objectSave(Object *o);
void objectSaveSize(Object *o, View *v);
void drawObject(Object *o, View *v);
void drawObjectNoShading(Object *o);
void drawObjectXShading(Object *o);
void drawObjectYShading(Object *o);
void drawObjectZShading(Object *o);
void drawObjectFogShading(Object *o);
void drawString(char *string, int x, int y, int z);
void drawAxis(void);
void drawScrollbar(View *v, Scrollbar *s);
void drawInfo(Object *o, View *v, char *objectType, int activeItem);
void drawSurfelsInfo(Object *o, View *v, Mouse *m, int activeItem);
void drawColorScrollbars(View *v, int settings, int activeItem);
void drawHelp(View *v);
void drawMainMenu(View *v, int activeItem);
void onInit(void);
void onResize(int w, int h);
void onDisplay(void);
void onKeyboard(unsigned char key, int x, int y);
void onSpecialKeyboard(int key, int x, int y);
void onMouseButton(int button, int state, int x, int y);
void onMouseMotion(int x, int y);
void onPassiveMotion(int x, int y);
void onMenu(int command);
void mouseInit(Mouse *m);
void viewInit(View *v);
void updateScrollbar(Scrollbar *s, int x, int y);
void buttonsInit(void);
void buttonObjectClick(void);
void buttonSurfelsSizeClick(void);
void buttonShadingClick(void);
void buttonZBufferClick(void);
void buttonSurfelsCountClick(void);
void buttonBlendingClick(void);
void buttonSettingsClick(void);
void createMenu(void);
int surfelInit(void);
int surfelListInit(int type);
int surfelListDone(int surfelList);
int surfelListAlloc(int surfelList, int itemCount);
int surfelListDestroy(int surfelList);
int surfelListSetSurfelF(int surfelList, SurfelF *surfel);
int surfelListGetSurfelF(int surfelList, SurfelF *surfel);
int surfelListFirst(int surfelList);
int surfelListNext(int surfelList);
int surfelListIsLast(int surfelList);
int surfelGetCount(int surfelList);
int surfelListSaveP(int surfelList, const char * fileName);
int surfelListSavePS(int surfelList, const char * fileName);
int gpeCreateMenuFromData(GpeMenu *menu, void (*f)(int command));
int gpeCreateMenu(GpeMenu *menu, void (*f)(int command));
int main(int argc, char *argv[]);
// }}}
// variables {{{
Object o;
int modelMenu;
int surfelMenu;
int shadingMenu;
int zBufferMenu;
int surfelCountMenu;
int blendingMenu;
int settingsMenu;
int mainMenu;
const int CommandModelFirst=CommandModelPyramid;
const int CommandModelLast=CommandModelArtefact7;
static Mouse m;
static View v;
static Scrollbar s={230, 480, 55, 68, 100};
static float rotX=0.0f;
static float rotY=0.0f;
static float rotXd=0.0f;
static float rotYd=0.0f;
static int settings=CommandSettingsSurfelsCount;
static int activeItem=0;
View *v_conf=nil;
Scrollbar *s_conf=nil;
Mouse *m_conf=nil;
int *set=nil;
int *active=0;
GLfloat axisColor[4];
GLfloat helpColor[4];
GLfloat infoColor[4];
GLfloat modelColor[4];
GLfloat scrollBarColor[4];
GLfloat activeItemColor[4];
GLfloat helpBackground[4];
GLfloat infoBackground[4];
GLfloat modelBackground[4];
GLfloat fogColor[4];
// }}}
// ButtonStruct buttons[] {{{
ButtonStruct buttons[]={
{buttonObjectClick, 0, 10, 200, 70, 85},
{buttonSurfelsSizeClick, 0, 10, 200, 55, 70},
{buttonShadingClick, 0, 10, 200, 40, 55},
{buttonZBufferClick, 0, 10, 200, 25, 40},
{buttonSurfelsCountClick,0, 220, 556, 40, 54},
{buttonBlendingClick, 0, 10, 200, 10, 25},
{buttonSettingsClick, 0, 230, 556, 69, 85},
{nil, 0, 0, 0, 0, 0}
};
// }}}
// char *modelString() {{{
char *modelString[]={
"Pyramid",
"Tetrahedron1",
"Tetrahedron2",
"Hexahedron",
"Cube",
"Octahedron",
"Duodecahedron",
"Fern",
"Wing",
"Leaf",
"Bush",
"Flash",
"Tower",
"Artefact 1",
"Artefact 2",
"Artefact 3",
"Artefact 4",
"Artefact 5",
"Artefact 6",
"Artefact 7"
};
// }}}
// char *shadingString[] {{{
char *shadingString[]={
"none",
"X-axis",
"Y-axis",
"Z-axis",
"fog"
};
// }}}
// menuModel1[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuModel1[]={
{_"Pyramid", CommandModelPyramid, nil},
{_"Tetrahedron 1", CommandModelTetrahedron1, nil},
{"Tetrahedron "_"2", CommandModelTetrahedron2, nil},
{_"Hexahedron", CommandModelHexahedron, nil},
{_"Cube", CommandModelCube, nil},
{_"Octahedron", CommandModelOctahedron, nil},
{_"Duodecahedron", CommandModelDuodecahedron, nil},
{nil, CommandNone, nil}
};
// }}}
// menuModel2[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuModel2[]={
{_"Fern", CommandModelFern, nil},
{_"Wing", CommandModelWing, nil},
{_"Leaf", CommandModelLeaf, nil},
{_"Bush", CommandModelBush, nil},
{"Fl"_"ash", CommandModelFlash, nil},
{nil, CommandNone, nil}
};
// }}}
// menuModel3[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuModel3[]={
{_"Tower", CommandModelTower, nil},
{"Artefact "_"1", CommandModelArtefact1, nil},
{"Artefact "_"2", CommandModelArtefact2, nil},
{"Artefact "_"3", CommandModelArtefact3, nil},
{"Artefact "_"4", CommandModelArtefact4, nil},
{"Artefact "_"5", CommandModelArtefact5, nil},
{"Artefact "_"6", CommandModelArtefact6, nil},
{"Artefact "_"7", CommandModelArtefact7, nil},
{nil, CommandNone, nil}
};
// }}}
// menuModel[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuModel[]={
{_"Geometric models", CommandNone, menuModel1},
{_"Nature models", CommandNone, menuModel2},
{_"Artifical structures", CommandNone, menuModel3},
{nil, CommandNone, nil}
};
// }}}
// menuSurfelCount[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuSurfelCount[]={
{_"100", CommandSurfelCount100, nil},
{_"400", CommandSurfelCount400, nil},
{_"625", CommandSurfelCount625, nil},
{_"2500", CommandSurfelCount2500, nil},
{"1"_"0000", CommandSurfelCount10000, nil},
{"22"_"500", CommandSurfelCount22500, nil},
{"40000", CommandSurfelCount40000, nil},
{_"62500", CommandSurfelCount62500, nil},
{nil, CommandNone, nil}
};
// }}}
// menuSurfelSize[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuSurfelSize[]={
{"Surfel size "_"1", CommandSurfelSize1, nil},
{"Surfel size "_"2", CommandSurfelSize2, nil},
{"Surfel size "_"3", CommandSurfelSize3, nil},
{"Surfel size "_"4", CommandSurfelSize4, nil},
{"Surfel size "_"5", CommandSurfelSize5, nil},
{"Surfel size "_"6", CommandSurfelSize6, nil},
{"Surfel size "_"7", CommandSurfelSize7, nil},
{"Surfel size "_"8", CommandSurfelSize8, nil},
{"Surfel size "_"9", CommandSurfelSize9, nil},
{nil, CommandNone, nil}
};
// }}}
// menuShading[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuShading[]={
{_"None\tN", CommandShadingNone, nil},
{"Along "_"X-axis\tX", CommandShadingX, nil},
{"Along "_"Y-axis\tY", CommandShadingY, nil},
{"Along "_"Z-axis\tZ", CommandShadingZ, nil},
{"F"_"og\tO", CommandShadingFog, nil},
{nil, CommandNone, nil}
};
// }}}
// menuBlendFactor[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuBlendFactor[]={
{"0."_"1\tF1", CommandBlending01, nil},
{"0."_"2\tF2", CommandBlending02, nil},
{"0."_"3\tF3", CommandBlending03, nil},
{"0."_"4\tF4", CommandBlending04, nil},
{"0."_"5\tF5", CommandBlending05, nil},
{"0."_"6\tF6", CommandBlending06, nil},
{"0."_"7\tF7", CommandBlending07, nil},
{"0."_"8\tF8", CommandBlending08, nil},
{"0."_"9\tF9", CommandBlending09, nil},
{"1."_"0\tF10", CommandBlending10, nil},
{nil, CommandNone, nil}
};
// }}}
// menuBlending[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuBlending[]={
{_"Enable blending", CommandBlendingEnable, nil},
{_"Disable blending", CommandBlendingDisable, nil},
{"Blend "_"factor", CommandNone, menuBlendFactor},
{nil, CommandNone, nil}
};
// }}}
// menuZBuffer[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuZBuffer[]={
{_"Enable depth buffer", CommandZBufferEnable, nil},
{_"Disable depth buffer", CommandZBufferDisable, nil},
{nil, CommandNone, nil}
};
// }}}
// menuSave[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuSave[]={
{_"Position only\tP", CommandSavePositions, nil},
{"Position and "_"size\tS", CommandSavePositionsSize, nil},
{nil, CommandNone, nil}
};
// }}}
// menuAxis[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuAxis[]={
{_"Show axes", CommandShowAxis, nil},
{_"Hide axes", CommandHideAxis, nil},
{nil, CommandNone, nil}
};
// }}}
// menuHelp[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuHelp[]={
{_"Show help", CommandShowHelp, nil},
{_"Hide help", CommandHideHelp, nil},
{nil, CommandNone, nil}
};
// }}}
// menuInfo[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuInfo[]={
{_"Show info", CommandShowInfo, nil},
{_"Hide info", CommandHideInfo, nil},
{nil, CommandNone, nil}
};
// }}}
// menuQuit[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuQuit[]={
{_"Quit now", CommandQuitYes, nil},
{_"Not yet", CommandQuitNo, nil},
{nil, CommandNone, nil}
};
// }}}
// menuView[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuView[]={
{_"Original view\tInsert", CommandViewOriginal, nil},
{"View from "_"top\tPage Up", CommandViewTop, nil},
{"View from "_"bottom\tPage Down", CommandViewBottom, nil},
{"View from "_"left\tHome", CommandViewLeft, nil},
{"View from "_"right\tEnd", CommandViewRight, nil},
{nil, CommandNone, nil}
};
// }}}
// menuSettings[] {{{
// ----------------------------------------------------------------------------
// submenu definition
// ----------------------------------------------------------------------------
GpeMenu menuSettings[]={
{_"Surfels count", CommandSettingsSurfelsCount, nil},
{"", CommandNone, nil},
{_"Model foreground", CommandSettingsModelForeground, nil},
{"Model "_"background", CommandSettingsModelBackground, nil},
{_"Fog color", CommandSettingsFogColor, nil},
{_"Axes color", CommandSettingsAxesColor, nil},
{"", CommandNone, nil},
{"Active item color", CommandSettingsActiveItemColor, nil},
{_"Help foreground", CommandSettingsHelpForeground, nil},
{"H"_"elp background", CommandSettingsHelpBackground, nil},
{_"Info foreground", CommandSettingsInfoForeground, nil},
{"I"_"nfo background", CommandSettingsInfoBackground, nil},
{"", CommandNone, nil},
{_"Reset settings\t^R", CommandSettingsReset, nil},
{_"Load settings\t^L", CommandSettingsLoad, nil},
{_"Save settings\t^S", CommandSettingsSave, nil},
{nil, CommandNone, nil}
};
// }}}
// menuMain[] {{{
// ----------------------------------------------------------------------------
// main menu definition
// ----------------------------------------------------------------------------
GpeMenu menuMain[]={
{_"Model type", CommandNone, menuModel},
{"Surfel count\tC", CommandNone, menuSurfelCount},
{_"Redraw\tR", CommandRedraw, nil},
{_"Save", CommandNone, menuSave},
{"", CommandNone, nil},
{_"View", CommandNone, menuView},
{"S"_"urfel size\t1-9", CommandNone, menuSurfelSize},
{"Sha"_"ding", CommandNone, menuShading},
{_"Blending\tB", CommandNone, menuBlending},
{_"Depth buffer\tD", CommandNone, menuZBuffer},
{"", CommandNone, nil},
{_"Axes\tA", CommandNone, menuAxis},
{_"Help\tH", CommandNone, menuHelp},
{_"Info\tI", CommandNone, menuInfo},
{"", CommandNone, nil},
{"S"_"ettings", CommandNone, menuSettings},
{_"Quit\tQ", CommandNone, menuQuit},
{nil, CommandNone, nil}
};
// }}}
// ifs_artefact1[][] {{{
float ifs_artefact1[][13]={
{-0.101858f,-0.150842f, 0.308003f,-0.481334f, 0.166339f,-0.579352f, 0.044036f,-0.514029f, 0.164516f, 0.492382f, 0.146172f, 0.064375f, -0.225623f},
{-0.022852f, 0.296328f, 0.814079f,-0.746566f,-0.254458f, 0.766551f,-0.297938f, 0.454955f,-0.947957f,-0.212907f, 0.060350f,-1.015431f, 1.000000f}
};
// }}}
// ifs_artefact2[][] {{{
float ifs_artefact2[][13]={
{-0.071315f, 0.200444f,-0.210993f, 0.308965f,-0.258325f,-0.059292f, 0.008314f,-0.599626f,-0.017553f, 0.058221f, 0.734876f,-0.583363f, -0.267495f},
{-0.198031f, 0.444311f,-0.710999f, 0.611886f, 0.584716f,-0.338408f,-0.473771f, 0.949758f,-0.500297f,-0.571381f,-0.272282f,-0.087467f, 0.809442f},
{ 0.328285f, 0.149096f,-0.492353f,-0.100800f, 0.207878f, 0.073338f, 0.864173f, 0.175989f, 0.339481f,-0.189086f,-0.053052f, 1.111021f, 0.989044f},
{-0.501541f,-0.532668f,-0.115721f,-0.198741f, 0.118444f,-0.628877f, 0.263749f, 0.964651f,-0.406249f, 0.474261f, 0.219763f,-0.686276f, 1.000000f}
};
// }}}
// ifs_artefact3[][] {{{
float ifs_artefact3[][13]={
{-0.149219f,-0.218931f,-0.076128f,-0.176103f, 0.119121f,-0.149684f, 0.491947f,-0.820411f, 0.134988f,-0.109922f,-0.518273f, 0.132760f, -0.073428f},
{ 0.887463f,-0.026903f,-0.067110f,-0.148618f, 0.130967f,-0.538636f, 0.174685f,-0.248019f,-0.193720f,-0.487402f,-0.189343f, 0.704726f, 0.400433f},
{-0.894439f,-0.336771f, 0.024013f,-0.434810f, 0.081183f,-0.514214f,-0.139469f,-0.340855f, 0.365726f,-0.709481f, 0.089686f, 0.706895f, 0.891415f},
{ 0.075945f,-0.080308f,-0.207685f, 0.178539f,-0.315027f, 0.237405f,-0.052465f, 0.850269f,-0.120275f,-0.672524f, 0.006280f, 0.122273f, 1.000000f}
};
// }}}
// ifs_artefact4[][] {{{
float ifs_artefact4[][13]={
{ 0.364565f, 0.038670f, 0.008728f, 0.394244f, 0.338922f,-0.050364f, 0.005845f,-0.428889f,-0.596382f,-0.004983f, 0.008657f,-1.043205f, -0.010163f},
{-0.243982f,-0.465263f,-0.424944f, 0.456958f, 0.076742f, 0.739098f,-0.369429f,-0.000908f, 0.412581f,-0.412611f,-0.182578f,-0.889257f, 0.032746f},
{ 0.099827f, 0.140258f,-0.312280f,-0.525080f, 0.185134f, 0.376114f, 0.122140f, 0.772410f, 0.578573f,-0.144551f, 0.014798f,-1.088071f, 0.129276f},
{ 0.059707f, 0.522051f,-0.160214f,-0.187567f, 0.516023f,-0.140507f,-0.005455f, 0.919340f,-0.078583f,-0.526006f,-0.157552f, 0.819254f, 0.207984f},
{ 0.250889f,-0.030707f, 0.890280f,-0.180622f, 0.586237f, 0.306830f,-0.171777f,-1.132464f, 0.513647f,-0.335193f,-0.238801f, 0.232543f, 0.563189f},
{-0.769092f, 0.011206f, 0.444428f, 0.870842f, 0.082195f,-0.147360f, 0.177503f,-0.338234f,-0.565983f,-0.036628f,-0.578138f, 0.185934f, 0.587542f},
{-0.009563f,-0.485699f,-0.086817f, 0.690251f, 0.006773f, 0.439292f,-0.104347f, 0.384353f, 0.016006f,-0.476090f,-0.007712f,-0.282015f, 0.873501f},
{-0.144162f, 0.017065f, 0.848653f,-0.640743f, 0.331367f, 0.063816f, 0.066138f,-0.681175f, 0.316759f,-0.058992f, 0.317047f,-0.268826f, 1.000000f}
};
// }}}
// ifs_artefact5[][] {{{
float ifs_artefact5[][13]={
{-0.014308f,-0.028272f, 0.916465f, 0.792812f,-0.010415f, 0.421076f,-0.042898f, 0.848069f,-0.033863f,-0.117565f,-0.374037f, 0.320556f, -0.333811f},
{-0.382406f,-0.083106f, 0.146682f,-0.587406f,-0.294822f, 0.855944f,-0.007971f, 0.041135f,-0.789595f,-0.279347f,-0.068063f, 0.858230f, 0.511887f},
{-0.467792f, 0.235933f,-0.073547f,-0.870659f,-0.156239f,-0.730864f, 0.192101f, 0.145745f, 0.010314f,-0.370541f,-0.425734f, 0.950115f, 1.000000f}
};
// }}}
// ifs_artefact6[][] {{{
float ifs_artefact6[][13]={
{ 0.088555f,-0.326833f,-0.211715f,-0.475499f, 0.056903f, 0.576230f, 0.288616f, 0.572544f,-0.006163f, 0.624204f,-0.377288f,-0.179581f,-0.441847f},
{-0.242021f, 0.059674f, 0.805669f,-0.445266f,-0.704437f, 0.107637f,-0.279418f,-0.452460f,-0.096128f,-0.939020f, 0.019171f,-0.526309f, 1.000000f}
};
// }}}
// ifs_artefact7[][] {{{
float ifs_artefact7[][13]={
{ 0.118002f,-0.367313f,-0.082903f, 0.432253f,-0.391844f, 0.012465f,-0.390282f,-0.042140f,-0.519441f,-0.092846f, 0.275579f, 1.331511f,-0.264534f},
{-0.192128f,-0.237729f, 0.644365f,-0.236597f,-0.622120f, 0.312954f, 0.225223f, 0.411871f,-0.689610f,-0.216094f,-0.382704f,-0.759115f, 1.000000f}
};
// }}}
// ifs_tower[][] {{{
float ifs_tower[][13]={
{-0.972522f, 0.035970f, 0.055638f, 0.712389f,-0.057478f,-0.836075f,-0.384403f,-0.326122f,-0.035977f, 0.363412f,-0.889874f, 0.681205f,-0.966287f},
{ 0.245092f,-0.498526f,-0.160138f,-0.375638f, 0.473636f, 0.395872f,-0.091942f,-0.649507f, 0.352847f,-0.185108f, 0.234650f, 0.442588f, 0.200000f}
};
// }}}
// ifs_fern[][] {{{
float ifs_fern[][13]={
{ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.180000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.010000f},
{ 0.850000f, 0.000000f, 0.000000f, 0.000000f, 0.850000f, 0.100000f, 0.000000f,-0.100000f, 0.850000f, 0.000000f, 1.600000f, 0.000000f, 0.850000f},
{ 0.200000f,-0.200000f, 0.000000f, 0.200000f, 0.200000f, 0.000000f, 0.000000f, 0.000000f, 0.300000f, 0.000000f, 0.800000f, 0.000000f, 0.070000f},
{-0.200000f, 0.200000f, 0.000000f, 0.200000f, 0.200000f, 0.000000f, 0.000000f, 0.000000f, 0.300000f, 0.000000f, 0.800000f, 0.000000f, 0.070000f},
};
// }}}
// ifs_bush[][] {{{
float ifs_bush[][13]={
{-0.373749f, 0.184692f, 0.105947f,-0.832341f,-0.453663f,-0.152631f, 0.124736f, 0.460184f, 0.197566f,-0.001087f, 0.486855f, 0.378884f,-0.020051f},
{ 0.166209f,-0.133945f,-0.080310f, 0.495707f,-0.797325f,-0.134969f,-0.012847f,-0.015179f, 0.145659f,-0.585965f, 0.021317f, 0.128416f, 0.161809f},
{-0.648603f, 0.270537f, 0.003552f, 0.794061f,-0.293407f,-0.643705f,-0.003235f,-0.441188f, 0.077220f,-0.173481f, 0.017543f,-0.928678f, 0.506607f},
{ 0.292940f, 0.142934f,-0.216388f, 0.393835f,-0.063308f,-0.879776f,-0.043157f,-0.004582f,-0.916890f, 0.106412f,-0.066155f,-0.670893f, 1.000000f}
};
// }}}
// ifs_wing[][] {{{
float ifs_wing[][13]={
{-0.863301f, 0.015541f, 0.106781f,-0.233617f, 0.098683f, 0.547759f, 0.401727f,-0.492123f,-0.098135f, 0.414103f,-0.535395f, 0.254419f, -0.496811f},
{-0.510493f, 0.370321f,-0.285759f, 0.295526f,-0.107999f,-0.794018f,-0.174678f, 0.809436f, 0.719463f, 0.143569f,-0.228981f,-0.054059f, 1.000000f}
};
// }}}
// ifs_leaf[][] {{{
float ifs_leaf[][13]={
{-0.492737f,-0.010404f, 0.180206f, 0.351519f,-0.530563f, 0.570329f,-0.108801f, 1.057364f,-0.380220f,-0.782360f,-0.081711f,-0.458607f, -0.217750f},
{-0.856946f,-0.299423f, 0.035138f, 0.708119f,-0.322467f, 0.841126f,-0.041265f, 0.669464f, 0.073766f, 0.198542f, 0.227810f, 0.531253f, 1.000000f}
};
// }}}
// ifs_flash[][] {{{
float ifs_flash[][13]={
{-0.009669f, 0.031249f, 0.794159f,-0.190141f, 0.035952f, 0.572048f, 0.123748f, 0.045626f, 0.026162f,-0.774558f, 0.123434f,-0.211259f, -0.228614f},
{ 0.067100f, 0.338221f,-0.383701f, 0.483533f,-0.052567f, 0.242058f,-0.618321f,-0.859729f, 0.015527f,-0.642140f,-0.435178f,-0.834466f, 1.000000f}
};
// }}}
// ifs_pyramid[][] {{{
float ifs_pyramid[][13]={
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 1.000000f, 0.000000f, 0.200000f},
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.500000f, 0.000000f, 0.500000f, 0.200000f},
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f,-0.500000f, 0.000000f, 0.500000f, 0.200000f},
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f,-0.500000f, 0.000000f,-0.500000f, 0.200000f},
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.500000f, 0.000000f,-0.500000f, 0.200000f}
};
// }}}
// ifs_tetrahedron1[][] {{{
float ifs_tetrahedron1[][13]={
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 1.000000f, 0.250000f},
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.870000f,-0.500000f, 0.250000f},
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f,-0.870000f,-0.500000f,-0.500000f, 0.250000f},
{ 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.000000f, 0.000000f, 0.000000f, 0.500000f, 0.870000f,-0.500000f,-0.500000f, 0.250000f},
};
// }}}
// ifs_tetrahedron2[][] {{{
float ifs_tetrahedron2[][13]={
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 1.000000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.870000f,-0.500000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f,-0.870000f,-0.500000f,-0.500000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.870000f,-0.500000f,-0.500000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.200000f},
};
// }}}
// ifs_hexahedron[][] {{{
float ifs_hexahedron[][13]={
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.900000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.870000f,-0.500000f, 0.000000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f,-0.870000f,-0.500000f, 0.000000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 1.000000f, 0.000000f, 0.200000f},
{ 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f, 0.000000f, 0.440000f, 0.000000f, 0.000000f,-0.900000f, 0.200000f},
};
// }}}
// ifs_cube[][] {{{
float ifs_cube[][13]={
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 1.000000f, 1.000000f, 1.000000f, 0.120000f},
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 1.000000f, 1.000000f,-1.000000f, 0.130000f},
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 1.000000f,-1.000000f, 1.000000f, 0.120000f},
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 1.000000f,-1.000000f,-1.000000f, 0.130000f},
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f,-1.000000f, 1.000000f, 1.000000f, 0.120000f},
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f,-1.000000f, 1.000000f,-1.000000f, 0.130000f},
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f,-1.000000f,-1.000000f, 1.000000f, 0.120000f},
{ 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f, 0.000000f, 0.000000f, 0.000000f, 0.350000f,-1.000000f,-1.000000f,-1.000000f, 0.130000f},
};
// }}}
// ifs_octahedron[][] {{{
float ifs_octahedron[][13]={
{ 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f, 1.000000f, 0.170000f},
{ 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 1.000000f, 0.000000f, 0.000000f, 0.160000f},
{ 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 1.000000f, 0.000000f, 0.170000f},
{ 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f,-1.000000f, 0.000000f, 0.000000f, 0.170000f},
{ 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f,-1.000000f, 0.000000f, 0.160000f},
{ 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f, 0.000000f, 0.400000f, 0.000000f, 0.000000f,-1.000000f, 0.170000f},
};
// }}}
// ifs_duodecahedron[][] {{{
float ifs_duodecahedron[][13]={
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.960000f, 0.090000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.850000f, 0.430000f, 0.080000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.810000f, 0.260000f, 0.430000f, 0.080000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f,-0.810000f, 0.260000f, 0.430000f, 0.090000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.500000f,-0.690000f, 0.430000f, 0.080000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f,-0.500000f,-0.690000f, 0.430000f, 0.080000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.500000f, 0.690000f,-0.430000f, 0.090000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f,-0.500000f, 0.690000f,-0.430000f, 0.080000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.810000f,-0.260000f,-0.430000f, 0.080000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f,-0.810000f,-0.260000f,-0.430000f, 0.090000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f,-0.850000f,-0.430000f, 0.080000f},
{ 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f, 0.000000f, 0.280000f, 0.000000f, 0.000000f,-0.960000f, 0.080000f},
};
// }}}
// surfelInit() {{{
int surfelInit(void)
{
return false;
}
// }}}
// surfelListSaveP() {{{
int surfelListSaveP(int surfelList, const char * fileName)
{
FILE *fout;
int i;
SurfelList *sl=(SurfelList *)surfelList;
fout=fopen(fileName, "wt");
if (fout) {
fprintf(fout, "pf\n"); // p-position n-normal c-color s-size o-object
fprintf(fout, "%d\n", sl->itemsCount);
for (i=0; i<sl->itemsCount; i++)
fprintf(fout, "%6.3f %6.3f %6.3f\n",
sl->items.itemsF[i].position.x,
sl->items.itemsF[i].position.y,
sl->items.itemsF[i].position.z);
fclose(fout);
return true;
}
else {
return false;
}
}
// }}}
// surfelListSavePS() {{{
int surfelListSavePS(int surfelList, const char * fileName)
{
FILE *fout;
int i;
SurfelList *sl=(SurfelList *)surfelList;
fout=fopen(fileName, "wt");
if (fout) {
fprintf(fout, "pfsb\n"); // p-position n-normal c-color s-size o-object
fprintf(fout, "%d\n", sl->itemsCount);
for (i=0; i<sl->itemsCount; i++)
fprintf(fout, "%6.3f %6.3f %6.3f %d\n",
sl->items.itemsF[i].position.x,
sl->items.itemsF[i].position.y,
sl->items.itemsF[i].position.z,
(int)sl->items.itemsF[i].size);
fclose(fout);
return true;
}
else {
return false;
}
}
// }}}
// surfelListInit() {{{
int surfelListInit(int type)
{
SurfelList *surfelList;
switch (type) {
case SURFEL_LIST_FLOAT:
surfelList=(SurfelList *)malloc(sizeof(SurfelList));
if (!surfelList) return 0;
surfelList->type=SURFEL_LIST_FLOAT;
surfelList->itemsCount=0;
surfelList->currentItem=-1;
surfelList->items.itemsF=nil;
return (int)surfelList;
default:
return false;
}
}
// }}}
// surfelListDone() {{{
int surfelListDone(int surfelList)
{
SurfelList *sl=(SurfelList *)surfelList;
free(sl);
return true;
}
// }}}
// surfelListDestroy() {{{
int surfelListDestroy(int surfelList)
{
SurfelList *sl=(SurfelList *)surfelList;
switch (sl->type) {
case SURFEL_LIST_FLOAT:
if (sl->items.itemsF) {
free(sl->items.itemsF);
return true;
}
else {
return false;
}
default:
return false;
}
}
// }}}
// surfelListAlloc() {{{
int surfelListAlloc(int surfelList, int itemCount)
{
SurfelList *sl=(SurfelList *)surfelList;
switch (sl->type) {
case SURFEL_LIST_FLOAT:
sl->items.itemsF=(SurfelF*)malloc(sizeof(SurfelF)*itemCount);
sl->itemsCount=itemCount;
if (sl->items.itemsF) return true;
else return false;
default:
return false;
}
}
// }}}
// surfelListSetSurfelF() {{{
int surfelListSetSurfelF(int surfelList, SurfelF *surfel)
{
SurfelList *sl=(SurfelList *)surfelList;
switch (sl->type) {
case SURFEL_LIST_FLOAT:
memcpy(&(sl->items.itemsF[sl->currentItem]), surfel, sizeof(SurfelF));
return true;
default:
return false;
}
}
// }}}
// surfelListGetSurfelF() {{{
int surfelListGetSurfelF(int surfelList, SurfelF *surfel)
{
SurfelList *sl=(SurfelList *)surfelList;
switch (sl->type) {
case SURFEL_LIST_FLOAT:
memcpy(surfel, &(sl->items.itemsF[sl->currentItem]), sizeof(SurfelF));
return true;
default:
return false;
}
}
// }}}
// surfelListFirst() {{{
int surfelListFirst(int surfelList)
{
SurfelList *sl=(SurfelList *)surfelList;
if (sl->itemsCount) sl->currentItem=0;
return true;
}
// }}}
// surfelListNext() {{{
int surfelListNext(int surfelList)
{
SurfelList *sl=(SurfelList *)surfelList;
sl->currentItem++;
return true;
}
// }}}
// surfelListIsLast() {{{
int surfelListIsLast(int surfelList)
{
SurfelList *sl=(SurfelList *)surfelList;
return sl->currentItem==sl->itemsCount;
}
// }}}
// surfelGetCount() {{{
int surfelGetCount(int surfelList)
{
SurfelList *sl=(SurfelList *)surfelList;
return sl->itemsCount;
}
// }}}
// confInit() {{{
// ----------------------------------------------------------------------------
// This function initializes configuration module for this application.
// ----------------------------------------------------------------------------
void confInit(View *view, Scrollbar *scrollbar, Mouse *mouse, int *settings, int *activeItem)
{
v_conf=view;
s_conf=scrollbar;
m_conf=mouse;
set=settings;
active=activeItem;
}
// }}}
// inButton() {{{
// ----------------------------------------------------------------------------
// This function returns "true", if mouse pointer is positioned over some
// button. It returns "false" otherwise.
// ----------------------------------------------------------------------------
int inButton(const ButtonStruct buttons[], const int i, const int x, const int y)
{
return (x>buttons[i].xmin &&
x<buttons[i].xmax &&
(v_conf->windowHeight-y)>buttons[i].ymin &&
(v_conf->windowHeight-y)<buttons[i].ymax);
}
// }}}
// inMainMenuButton() {{{
// ----------------------------------------------------------------------------
// This function returns "true", if mouse pointer is positioned over main menu
// button. It returns "false" otherwise.
// ----------------------------------------------------------------------------
int inMainMenuButton(int x, int y)
{
return (x>=10 && x<=220 && y>=8 && y<=24);
}
// }}}
// inScrollbar() {{{
// ----------------------------------------------------------------------------
// This function returns "true", if mouse pointer is positioned over scrollbar.
// It returns "false" otherwise.
// ----------------------------------------------------------------------------
int inScrollbar(Scrollbar *s_conf, int x, int y)
{
return (x>s_conf->xmin) && (x<s_conf->xmax) && (y>s_conf->ymin) && (y<s_conf->ymax);
}
// }}}
// setMenuForButton() {{{
// ----------------------------------------------------------------------------
// This function sets context menu for button under mouse pointer.
// ----------------------------------------------------------------------------
void setMenuForButton(const ButtonStruct buttons[], const int x, const int y)
{
int i;
int old=*active;
*active=0;
for (i=0; buttons[i].callback; i++) { // check if mouse cursor is in some button
if (*set==CommandSettingsSurfelsCount || i!=4) {
if (inButton(buttons, i, x, y)) {
glutSetMenu(buttons[i].menu);
glutAttachMenu(GLUT_RIGHT_BUTTON); // context menu under right mouse button
*active=buttons[i].menu;
break;
}
}
}
if (*active!=old) glutPostRedisplay();
}
// }}}
// setMenuForMainButton() {{{
// ----------------------------------------------------------------------------
// This function sets context menu for main menu button, but only when mouse
// pointer is positioned over this button.
// ----------------------------------------------------------------------------
void setMenuForMainButton(int x, int y)
{
int old=*active;
if (inMainMenuButton(x, y)) {
glutSetMenu(mainMenu);
glutAttachMenu(GLUT_LEFT_BUTTON);
glutAttachMenu(GLUT_RIGHT_BUTTON);
*active=mainMenu;
}
if (*active!=old) glutPostRedisplay();
}
// }}}
// processScrollbars() {{{
// ----------------------------------------------------------------------------
// This function processes all scrollbar messages.
// ----------------------------------------------------------------------------
void processScrollbars(int x, int y)
{
if (*set==CommandSettingsSurfelsCount) {
if (inScrollbar(s_conf, x, v_conf->windowHeight-y)) { // surfel count scrollbar
updateScrollbar(s_conf, x, y);
glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, s_conf->position);
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
glutPostRedisplay();
}
}
else {
if (x>=340 && x<=540) { // color scrollbars
GLfloat r, g, b, a;
int yy=v_conf->windowHeight-y;
getCurrentColor(&r, &g, &b, &a);
if (yy>=56 && yy<=62) { // red color component
r=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
glutPostRedisplay();
}
if (yy>=41 && yy<=47) { // green color component
g=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
glutPostRedisplay();
}
if (yy>=26 && yy<=32) { // blue color component
b=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
glutPostRedisplay();
}
if (yy>=11 && yy<=17) { // alpha color component
a=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
glutPostRedisplay();
}
}
}
}
// }}}
// processRightMouseButton() {{{
// ----------------------------------------------------------------------------
// This function processes messages for right mouse button press/release.
// ----------------------------------------------------------------------------
#ifdef __BORLANDC__ // avoid compiler warnings
#pragma option -w-par
#endif
void processRightMouseButton(int state, int x, int y)
{
if (state==GLUT_DOWN) { // mouse button press
m_conf->status=2;
m_conf->z1=y;
}
else { // mouse button release
m_conf->status=0;
m_conf->zold=m_conf->znew;
}
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// processLeftMouseButton() {{{
// ----------------------------------------------------------------------------
// This function processes messages for left mouse button press/release.
// ----------------------------------------------------------------------------
void processLeftMouseButton(const ButtonStruct buttons[], const int state, const int x, const int y)
{
int doTransformation=true;
int i;
if (state==GLUT_DOWN) {
if (!v_conf->info) { // rotate fractal object
m_conf->status=1;
m_conf->x1=x;
m_conf->y1=y;
glutPostRedisplay();
return;
}
if (*set==CommandSettingsSurfelsCount) { // change surfels count
if (inScrollbar(s_conf, x, v_conf->windowHeight-y)) {
updateScrollbar(s_conf, x, y);
glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, s_conf->position);
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
doTransformation=false;
}
for (i=0; buttons[i].callback; i++) { // check if mouse pointer
if (inButton(buttons, i, x, y)) { // is in some button
buttons[i].callback();
doTransformation=false;
break;
}
}
}
else {
if (x>=340 && x<=540) { // color scrollbars
GLfloat r, g, b, a;
int yy=v_conf->windowHeight-y;
getCurrentColor(&r, &g, &b, &a);
if (yy>=56 && yy<=62) { // red color component
r=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
doTransformation=false;
}
if (yy>=41 && yy<=47) { // green color component
g=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
doTransformation=false;
}
if (yy>=26 && yy<=32) { // blue color component
b=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
doTransformation=false;
}
if (yy>=11 && yy<=17) { // alpha color component
a=(x-340)/200.0f;
setCurrentColor(r, g, b, a);
doTransformation=false;
}
}
for (i=0; buttons[i].callback; i++) { // check if mouse pointer
if (inButton(buttons, i, x, y) && i!=4) {// is in some button
buttons[i].callback();
doTransformation=false;
break;
}
}
}
if (doTransformation) { // if user wants to do some transformation
if (glutGetModifiers() & GLUT_ACTIVE_CTRL) {
m_conf->xtran1=x;
m_conf->ytran1=y;
m_conf->status=3;
}
else {
m_conf->status=1;
m_conf->x1=x;
m_conf->y1=y;
}
}
}
else { // GLUT_UP
m_conf->status=0;
m_conf->xold=m_conf->xnew;
m_conf->yold=m_conf->ynew;
m_conf->xtran2=m_conf->xtran0;
m_conf->ytran2=m_conf->ytran0;
}
}
// }}}
// getAxisColor() {{{
// ----------------------------------------------------------------------------
// This function returns current axis color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getAxisColor(void)
{
return axisColor;
}
// }}}
// getHelpColor() {{{
// ----------------------------------------------------------------------------
// This function returns current help foreground color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getHelpColor(void)
{
return helpColor;
}
// }}}
// getInfoColor() {{{
// ----------------------------------------------------------------------------
// This function returns current info foreground color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getInfoColor(void)
{
return infoColor;
}
// }}}
// getModelColor() {{{
// ----------------------------------------------------------------------------
// This function returns current model color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getModelColor(void)
{
return modelColor;
}
// }}}
// getScrollBarColor() {{{
// ----------------------------------------------------------------------------
// This function returns current scroll bar color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getScrollBarColor(void)
{
return scrollBarColor;
}
// }}}
// getActiveItemColor() {{{
// ----------------------------------------------------------------------------
// This function returns current active (highlited) item color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getActiveItemColor(void)
{
return activeItemColor;
}
// }}}
// getHelpBackground() {{{
// ----------------------------------------------------------------------------
// This function returns current help background color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getHelpBackground(void)
{
return helpBackground;
}
// }}}
// getInfoBackground() {{{
// ----------------------------------------------------------------------------
// This function returns current info background color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getInfoBackground(void)
{
return infoBackground;
}
// }}}
// getModelBackground() {{{
// ----------------------------------------------------------------------------
// This function returns current model background color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getModelBackground(void)
{
return modelBackground;
}
// }}}
// getFogColor() {{{
// ----------------------------------------------------------------------------
// This function returns current fog color
// (pointer to four color components).
// ----------------------------------------------------------------------------
GLfloat *getFogColor(void)
{
return fogColor;
}
// }}}
// getCurrentColor() {{{
// ----------------------------------------------------------------------------
// This function gets current color for some GUI item.
// ----------------------------------------------------------------------------
void getCurrentColor(GLfloat *r, GLfloat *g, GLfloat *b, GLfloat *a)
{
#ifndef __BORLANDC__
GLfloat *color=nil;
#else
GLfloat *color;
#endif
switch (*set) {
case CommandSettingsModelForeground: color=modelColor; break;
case CommandSettingsModelBackground: color=modelBackground; break;
case CommandSettingsFogColor: color=fogColor; break;
case CommandSettingsAxesColor: color=axisColor; break;
case CommandSettingsActiveItemColor: color=activeItemColor; break;
case CommandSettingsHelpForeground: color=helpColor; break;
case CommandSettingsHelpBackground: color=helpBackground; break;
case CommandSettingsInfoForeground: color=infoColor; break;
case CommandSettingsInfoBackground: color=infoBackground; break;
case CommandSettingsScrollBarColor: color=scrollBarColor; break;
default: color=modelColor; break;
}
if (color) {
*r=color[0];
*g=color[1];
*b=color[2];
*a=color[3];
}
}
// }}}
// setModelAlpha() {{{
// ----------------------------------------------------------------------------
// This function sets alpha color component for blending.
// ----------------------------------------------------------------------------
void setModelAlpha(GLfloat alpha)
{
modelColor[3]=alpha;
}
// }}}
// setCurrentColor() {{{
// ----------------------------------------------------------------------------
// This function sets current color for some GUI item.
// ----------------------------------------------------------------------------
void setCurrentColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
GLfloat *color=nil;
switch (*set) {
case CommandSettingsModelForeground: color=modelColor; break;
case CommandSettingsModelBackground: color=modelBackground; break;
case CommandSettingsFogColor: color=fogColor; break;
case CommandSettingsAxesColor: color=axisColor; break;
case CommandSettingsActiveItemColor: color=activeItemColor; break;
case CommandSettingsHelpForeground: color=helpColor; break;
case CommandSettingsHelpBackground: color=helpBackground; break;
case CommandSettingsInfoForeground: color=infoColor; break;
case CommandSettingsInfoBackground: color=infoBackground; break;
case CommandSettingsScrollBarColor: color=scrollBarColor; break;
}
if (color) {
color[0]=r;
color[1]=g;
color[2]=b;
color[3]=a;
}
}
// }}}
// readOneLine() {{{
// ----------------------------------------------------------------------------
// This function reads one line from config file.
// ----------------------------------------------------------------------------
void readOneLine(FILE *fin, GLfloat (*colorArray)[4])
{
char str[1000];
GLfloat r, g, b, a; // four color components
if (fscanf(fin, "%s%f%f%f%f\n", str, &r, &g, &b, &a)==5) {
(*colorArray)[0]=r;
(*colorArray)[1]=g;
(*colorArray)[2]=b;
(*colorArray)[3]=a;
}
}
// }}}
// settingsReset() {{{
// ----------------------------------------------------------------------------
// This function resets all color settings.
// ----------------------------------------------------------------------------
void settingsReset(void)
{
const GLfloat c_axisColor[]= {0.5f, 0.5f, 1.0f, 1.0f};
const GLfloat c_helpColor[]= {0.2f, 0.9f, 0.9f, 1.0f};
const GLfloat c_infoColor[]= {0.2f, 0.9f, 0.9f, 1.0f};
const GLfloat c_modelColor[]= {1.0f, 1.0f, 1.0f, 0.5f};
const GLfloat c_scrollBarColor[]= {0.5f, 0.5f, 1.0f, 1.0f};
const GLfloat c_activeItemColor[]={1.0f, 1.0f, 0.5f, 1.0f};
const GLfloat c_helpBackground[]= {0.3f, 0.3f, 0.7f, 0.7f};
const GLfloat c_infoBackground[]= {0.3f, 0.3f, 0.7f, 0.7f};
const GLfloat c_modelBackground[]={0.0f, 0.0f, 0.0f, 1.0f};
const GLfloat c_fogColor[]= {0.1f, 0.1f, 0.1f, 0.0f};
// set default colors
memcpy(axisColor, c_axisColor, sizeof(c_axisColor));
memcpy(helpColor, c_helpColor, sizeof(c_helpColor));
memcpy(infoColor, c_infoColor, sizeof(c_infoColor));
memcpy(modelColor, c_modelColor, sizeof(c_modelColor));
memcpy(scrollBarColor, c_scrollBarColor, sizeof(c_scrollBarColor));
memcpy(activeItemColor, c_activeItemColor, sizeof(c_activeItemColor));
memcpy(helpBackground, c_helpBackground, sizeof(c_helpBackground));
memcpy(infoBackground, c_infoBackground, sizeof(c_infoBackground));
memcpy(modelBackground, c_modelBackground, sizeof(c_modelBackground));
memcpy(fogColor, c_fogColor, sizeof(c_fogColor));
}
// }}}
// settingsLoad() {{{
// ----------------------------------------------------------------------------
// This function reads all color settings from config file.
// ----------------------------------------------------------------------------
void settingsLoad(void)
{
FILE *fin;
fin=fopen("surf_ifs.ini", "rt"); // try to open config file for reading
if (fin) {
readOneLine(fin, &axisColor);
readOneLine(fin, &helpColor);
readOneLine(fin, &infoColor);
readOneLine(fin, &modelColor);
readOneLine(fin, &scrollBarColor);
readOneLine(fin, &activeItemColor);
readOneLine(fin, &helpBackground);
readOneLine(fin, &infoBackground);
readOneLine(fin, &modelBackground);
readOneLine(fin, &fogColor);
fclose(fin);
}
else {
settingsReset(); // file could not be opened
}
}
// }}}
// settingsSave() {{{
// ----------------------------------------------------------------------------
// This function writes color settings to config file.
// ----------------------------------------------------------------------------
void settingsSave(void)
{
FILE *fout;
fout=fopen("surf_ifs.ini", "wt"); // try to open config file for writing
if (fout) {
fprintf(fout, "AxisColor\t %5.3f %5.3f %5.3f %5.3f\n",
axisColor[0], axisColor[1], axisColor[2], axisColor[3]);
fprintf(fout, "HelpColor\t %5.3f %5.3f %5.3f %5.3f\n",
helpColor[0], helpColor[1], helpColor[2], helpColor[3]);
fprintf(fout, "InfoColor\t %5.3f %5.3f %5.3f %5.3f\n",
infoColor[0], infoColor[1], infoColor[2], infoColor[3]);
fprintf(fout, "ModelColor\t %5.3f %5.3f %5.3f %5.3f\n",
modelColor[0], modelColor[1], modelColor[2], modelColor[3]);
fprintf(fout, "ScrollBarColor\t %5.3f %5.3f %5.3f %5.3f\n",
scrollBarColor[0], scrollBarColor[1], scrollBarColor[2], scrollBarColor[3]);
fprintf(fout, "ActiveItemColor\t %5.3f %5.3f %5.3f %5.3f\n",
activeItemColor[0], activeItemColor[1], activeItemColor[2], activeItemColor[3]);
fprintf(fout, "HelpBackground\t %5.3f %5.3f %5.3f %5.3f\n",
helpBackground[0], helpBackground[1], helpBackground[2], helpBackground[3]);
fprintf(fout, "InfoBackground\t %5.3f %5.3f %5.3f %5.3f\n",
infoBackground[0], infoBackground[1], infoBackground[2], infoBackground[3]);
fprintf(fout, "ModelBackground\t %5.3f %5.3f %5.3f %5.3f\n",
modelBackground[0], modelBackground[1], modelBackground[2], modelBackground[3]);
fprintf(fout, "FogColor\t %5.3f %5.3f %5.3f %5.3f\n",
fogColor[0], fogColor[1], fogColor[2], fogColor[3]);
fclose(fout);
}
}
// }}}
// arandom() {{{
// ----------------------------------------------------------------------------
// This function works as pseudo-random number generator.
// ----------------------------------------------------------------------------
float arandom(float max)
{
return (float)rand()*max/RAND_MAX;
}
// }}}
// getMinMax() {{{
// ----------------------------------------------------------------------------
// This function returns minimums and maximums coordinates of surfel positions.
// ----------------------------------------------------------------------------
void getMinMax(int surfelList, float *minx, float *maxx,
float *miny, float *maxy,
float *minz, float *maxz)
{
SurfelF surfel;
*minx=*miny=*minz=1.0e9;
*maxx=*maxy=*maxz=-1.0e9;
surfelListFirst(surfelList);
while (!surfelListIsLast(surfelList)) {
surfelListGetSurfelF(surfelList, &surfel);
*minx=MIN(*minx, surfel.position.x);
*maxx=MAX(*maxx, surfel.position.x);
*miny=MIN(*miny, surfel.position.y);
*maxy=MAX(*maxy, surfel.position.y);
*minz=MIN(*minz, surfel.position.z);
*maxz=MAX(*maxz, surfel.position.z);
surfelListNext(surfelList);
}
}
// }}}
// getArray() {{{
// ----------------------------------------------------------------------------
// This function returns pointer to proper data of selected IFS system.
// ----------------------------------------------------------------------------
void getArray(int type, float (**p)[13])
{
switch (type) {
case CommandModelPyramid: *p=ifs_pyramid; break;
case CommandModelTetrahedron1: *p=ifs_tetrahedron1; break;
case CommandModelTetrahedron2: *p=ifs_tetrahedron2; break;
case CommandModelHexahedron: *p=ifs_hexahedron; break;
case CommandModelCube: *p=ifs_cube; break;
case CommandModelOctahedron: *p=ifs_octahedron; break;
case CommandModelDuodecahedron: *p=ifs_duodecahedron; break;
case CommandModelFern: *p=ifs_fern; break;
case CommandModelWing: *p=ifs_wing; break;
case CommandModelLeaf: *p=ifs_leaf; break;
case CommandModelBush: *p=ifs_bush; break;
case CommandModelFlash: *p=ifs_flash; break;
case CommandModelTower: *p=ifs_tower; break;
case CommandModelArtefact1: *p=ifs_artefact1; break;
case CommandModelArtefact2: *p=ifs_artefact2; break;
case CommandModelArtefact3: *p=ifs_artefact3; break;
case CommandModelArtefact4: *p=ifs_artefact4; break;
case CommandModelArtefact5: *p=ifs_artefact5; break;
case CommandModelArtefact6: *p=ifs_artefact6; break;
case CommandModelArtefact7: *p=ifs_artefact7; break;
default: *p=NULL; break;
}
}
// }}}
// centerSurfels() {{{
// ----------------------------------------------------------------------------
// This function centers whole set of surfels.
// ----------------------------------------------------------------------------
void centerSurfels(int surfelList, int midx, int midy, int midz)
{
SurfelF surfel;
surfelListFirst(surfelList);
while (!surfelListIsLast(surfelList)) { // center object around origin
surfelListGetSurfelF(surfelList, &surfel);
surfel.position.x+=ORIGIN_X-midx;
surfel.position.y+=ORIGIN_Y-midy;
surfel.position.z+=ORIGIN_Z-midz;
surfelListSetSurfelF(surfelList, &surfel);
surfelListNext(surfelList);
}
}
// }}}
// scaleAndMoveSurfels() {{{
// ----------------------------------------------------------------------------
// This function scales and moves whole set of surfels to fit to an unit cube.
// ----------------------------------------------------------------------------
void scaleAndMoveSurfels(int surfelList, float scale)
{
SurfelF surfel;
surfelListFirst(surfelList);
while (!surfelListIsLast(surfelList)) { // scale object into unit cube
surfelListGetSurfelF(surfelList, &surfel);
surfel.position.x-=ORIGIN_X;
surfel.position.y-=ORIGIN_Y;
surfel.position.z-=ORIGIN_Z;
surfel.position.x*=scale;
surfel.position.y*=scale;
surfel.position.z*=scale;
surfel.position.x+=ORIGIN_X;
surfel.position.y+=ORIGIN_Y;
surfel.position.z+=ORIGIN_Z;
surfelListSetSurfelF(surfelList, &surfel);
surfelListNext(surfelList);
}
}
// }}}
// objectInit() {{{
// ----------------------------------------------------------------------------
// This function initializes new surfel-based object.
// ----------------------------------------------------------------------------
void objectInit(Object *o)
{
o->type=CommandModelFirst;
o->colorR=1.0; // set initial values
o->colorG=1.0; // for all color components
o->colorB=1.0;
o->blending=0;
o->alpha=0.5f;
o->surfelList=surfelListInit(SURFEL_LIST_FLOAT);
}
// }}}
// objectCreate() {{{
// ----------------------------------------------------------------------------
// This function creates new surfel-based object.
// ----------------------------------------------------------------------------
void objectCreate(Object *o, int type, int grid)
{
int subtype;
int pts=grid*grid;
int i, k;
float x,y,z,x1,y1,z1;
float pp, sum;
SurfelF surfel;
float (*ifs)[13];
o->type=type;
o->size=grid;
getArray(type, &ifs);
if (!ifs) return;
surfelListDestroy(o->surfelList);
surfelListAlloc(o->surfelList, pts);
if (ifs[0][12]<0) { // check object type
subtype=1;
ifs[0][12]=-ifs[0][12];
}
else { // bad object type
subtype=0;
}
x=y=z=0.0;
i=0;
surfelListFirst(o->surfelList);
if (!subtype) { // generate model as normal IFS system
while (!surfelListIsLast(o->surfelList)) {
pp=arandom(999.0)/1000.0;
sum=0;
for (k=0; sum<=pp; k++)
sum+=ifs[k][12];
k--;
x1=ifs[k][0]*x+ifs[k][1]*y+ifs[k][2]*z+ifs[k][9];
y1=ifs[k][3]*x+ifs[k][4]*y+ifs[k][5]*z+ifs[k][10];
z1=ifs[k][6]*x+ifs[k][7]*y+ifs[k][8]*z+ifs[k][11];
x=x1;y=y1;z=z1;
if (i>=100) { // after starting iterations
surfel.position.x=x*20.0; // generate surfel
surfel.position.y=y*20.0;
surfel.position.z=z*20.0;
surfel.size=1;
surfelListSetSurfelF(o->surfelList, &surfel);
surfelListNext(o->surfelList);
}
i++;
}
}
else { // generate model as IFS with alternating coordinates
while (!surfelListIsLast(o->surfelList)) {
pp=arandom(999.0)/1000.0;
sum=0;
for (k=0; sum<=pp; k++)
sum+=ifs[k][12];
k--;
x1=ifs[k][0]*x+ifs[k][1]*y+ifs[k][2]*z+ifs[k][3];
y1=ifs[k][4]*x+ifs[k][5]*y+ifs[k][6]*z+ifs[k][7];
z1=ifs[k][8]*x+ifs[k][9]*y+ifs[k][10]*z+ifs[k][11];
x=-x1;y=-y1;z=-z1;
if (i>=100) { // after starting iterations
surfel.position.x=x*20.0; // generate surfel
surfel.position.y=y*20.0;
surfel.position.z=z*20.0;
surfel.size=1;
surfelListSetSurfelF(o->surfelList, &surfel);
surfelListNext(o->surfelList);
}
i++;
}
ifs[0][12]=-ifs[0][12];
}
}
// }}}
// objectSizeMove() {{{
// ----------------------------------------------------------------------------
// This function centers surfel-based object along origin.
// ----------------------------------------------------------------------------
void objectSizeMove(Object *o)
{
float minx, miny, minz;
float maxx, maxy, maxz;
float midx, midy, midz;
float scale;
getMinMax(o->surfelList, &minx, &maxx, &miny, &maxy, &minz, &maxz);
midx=(minx+maxx)/2.0;
midy=(miny+maxy)/2.0;
midz=(minz+maxz)/2.0;
centerSurfels(o->surfelList, midx, midy, midz);
scale=RANGE_X/(maxx-minx);
scale=MIN(scale, RANGE_Y/(maxy-miny));
scale=MIN(scale, RANGE_Z/(maxz-minz));
scaleAndMoveSurfels(o->surfelList, scale);
}
// }}}
// objectSave() {{{
// ----------------------------------------------------------------------------
// This function saves surfel-based object to an external file.
// ----------------------------------------------------------------------------
void objectSave(Object *o)
{
time_t timer;
struct tm *t;
char fileName[100];
time(&timer);
t=localtime(&timer); // get current date and time
sprintf(fileName, "%04d%02d%02d-%02d%02d%02d.sfl", // prepare file name
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
surfelListSaveP(o->surfelList, fileName); // write surfels to file
}
// }}}
// objectSaveSize() {{{
// ----------------------------------------------------------------------------
// This function saves surfel-based object to file, including surfel' sizes.
// ----------------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par
#endif
void objectSaveSize(Object *o, View *v)
{
time_t timer;
struct tm *t;
char fileName[100];
time(&timer);
t=localtime(&timer); // get current date and time
sprintf(fileName, "%04d%02d%02d-%02d%02d%02d.sfl", // prepare file name
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
surfelListSavePS(o->surfelList, fileName); // write surfels to file
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// drawString() {{{
// ----------------------------------------------------------------------------
// This function draws string at world' specified co-ordinates
// ----------------------------------------------------------------------------
void drawString(char *string, int x, int y, int z)
{
glRasterPos3i(x, y, z);
while (*string) // for all characters in string
glutBitmapCharacter(FONT, *string++); // draw each character
}
// }}}
// drawObjectNoShading() {{{
// ----------------------------------------------------------------------------
// This function draws the surfel object using no shading
// ----------------------------------------------------------------------------
void drawObjectNoShading(Object *o)
{
SurfelF surfel;
if (o->blending) { // if blending is enabled
glEnable(GL_BLEND); // enable it
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glColor4fv(getModelColor()); // constant object color
glBegin(GL_POINTS);
surfelListFirst(o->surfelList); // rewind to first surfel in object
while (!surfelListIsLast(o->surfelList)) { // for all surfels in object
surfelListGetSurfelF(o->surfelList, &surfel);// get surfel
glVertex3f(surfel.position.x, surfel.position.y, surfel.position.z);
surfelListNext(o->surfelList); // move to next surfel in list
}
glEnd();
if (o->blending) { // if blending is enabled
glDisable(GL_BLEND); // disable it (for GUI)
}
}
// }}}
// drawObjectXShading() {{{
// ----------------------------------------------------------------------------
// This function draws the surfel object using shading along x-axis
// ----------------------------------------------------------------------------
void drawObjectXShading(Object *o)
{
GLfloat weight;
GLfloat *color;
GLfloat *fog;
SurfelF surfel;
color=getModelColor();
fog=getFogColor();
if (o->blending) { // if blending is enabled
glEnable(GL_BLEND); // enable it
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glBegin(GL_POINTS);
surfelListFirst(o->surfelList); // rewind to first surfel in object
while (!surfelListIsLast(o->surfelList)) { // for all surfels in object
surfelListGetSurfelF(o->surfelList, &surfel);
weight=(float)surfel.position.x/RANGE_X+0.2;// calculate surfel color
glColor4f(color[0]*weight+fog[0]*(1.0f-weight),
color[1]*weight+fog[1]*(1.0f-weight),
color[2]*weight+fog[2]*(1.0f-weight),
color[3]); // set color and draw surfel
glVertex3f(surfel.position.x, surfel.position.y, surfel.position.z);
surfelListNext(o->surfelList); // goto next surfel in list
}
glEnd();
if (o->blending) { // if blending is enabled
glDisable(GL_BLEND); // disable it (for GUI)
}
}
// }}}
// drawObjectYShading() {{{
// ----------------------------------------------------------------------------
// This function draws the surfel object using shading along y-axis
// ----------------------------------------------------------------------------
void drawObjectYShading(Object *o)
{
GLfloat weight;
GLfloat *color;
GLfloat *fog;
SurfelF surfel;
color=getModelColor();
fog=getFogColor();
if (o->blending) { // if blending is enabled
glEnable(GL_BLEND); // enable it
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glBegin(GL_POINTS);
surfelListFirst(o->surfelList); // rewind to first surfel in object
while (!surfelListIsLast(o->surfelList)) { // for all surfels in object
surfelListGetSurfelF(o->surfelList, &surfel);
weight=(float)surfel.position.y/RANGE_Y+0.2;// calculate surfel color
glColor4f(color[0]*weight+fog[0]*(1.0f-weight),
color[1]*weight+fog[1]*(1.0f-weight),
color[2]*weight+fog[2]*(1.0f-weight),
color[3]); // set color and draw surfel
glVertex3f(surfel.position.x, surfel.position.y, surfel.position.z);
surfelListNext(o->surfelList); // goto next surfel in list
}
glEnd();
if (o->blending) { // if blending is enabled
glDisable(GL_BLEND); // disable it (for GUI)
}
}
// }}}
// drawObjectZShading() {{{
// ----------------------------------------------------------------------------
// This function draws the surfel object using shading along z-axis
// ----------------------------------------------------------------------------
void drawObjectZShading(Object *o)
{
GLfloat weight;
GLfloat *color;
GLfloat *fog;
SurfelF surfel;
color=getModelColor();
fog=getFogColor();
if (o->blending) { // if blending is enabled
glEnable(GL_BLEND); // enable it
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glBegin(GL_POINTS);
surfelListFirst(o->surfelList); // rewind to first surfel in object
while (!surfelListIsLast(o->surfelList)) { // for all surfels in object
surfelListGetSurfelF(o->surfelList, &surfel);
weight=(float)surfel.position.z/RANGE_Z+0.2;// calculate surfel color
glColor4f(color[0]*weight+fog[0]*(1.0f-weight),
color[1]*weight+fog[1]*(1.0f-weight),
color[2]*weight+fog[2]*(1.0f-weight),
color[3]); // set color and draw surfel
glVertex3f(surfel.position.x, surfel.position.y, surfel.position.z);
surfelListNext(o->surfelList); // goto next surfel in list
}
glEnd();
if (o->blending) { // if blending is enabled
glDisable(GL_BLEND); // disable it (for GUI)
}
}
// }}}
// drawObjectFogShading() {{{
// ----------------------------------------------------------------------------
// This function draws the surfel object using fog
// ----------------------------------------------------------------------------
void drawObjectFogShading(Object *o)
{
SurfelF surfel;
GLfloat *fogColor=getFogColor();
glEnable(GL_FOG); // set fog properties
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.1f);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 220.0); // near and far planes
glFogf(GL_FOG_END, 320.0); // fog increases inbetween these planes
if (o->blending) { // if blending is enabled
glEnable(GL_BLEND); // enable it
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glColor4fv(getModelColor());
glBegin(GL_POINTS);
surfelListFirst(o->surfelList);
while (!surfelListIsLast(o->surfelList)) { // for all surfels in object
surfelListGetSurfelF(o->surfelList, &surfel);
glVertex3f(surfel.position.x, surfel.position.y, surfel.position.z);
surfelListNext(o->surfelList); // goto next surfel in list
}
glEnd();
glDisable(GL_FOG);
if (o->blending) { // if blending is enabled
glDisable(GL_BLEND); // disable it (for GUI)
}
}
// }}}
// drawObject() {{{
// ----------------------------------------------------------------------------
// This function draws the surfel object
// ----------------------------------------------------------------------------
void drawObject(Object *o, View *v)
{
if (v->zBuffer)
glEnable(GL_DEPTH_TEST);
switch (v->shading) {
case CommandShadingNone: drawObjectNoShading(o); break;
case CommandShadingX: drawObjectXShading(o); break;
case CommandShadingY: drawObjectYShading(o); break;
case CommandShadingZ: drawObjectZShading(o); break;
case CommandShadingFog: drawObjectFogShading(o); break;
default: break;
}
if (v->zBuffer)
glDisable(GL_DEPTH_TEST);
}
// }}}
// drawAxis() {{{
// ----------------------------------------------------------------------------
// This function draws axes
// ----------------------------------------------------------------------------
void drawAxis(void)
{
glEnable(GL_BLEND);
glColor4fv(getAxisColor());
drawString("origin", MINX+1, MINY+1, MINZ+1); // text labels
drawString("xmax", MAXX+1, MINY+1, MINZ+1);
drawString("ymax", MINX+1, MAXY+1, MINZ+1);
drawString("zmax", MINX+1, MINY+1, MAXZ+1);
glBegin(GL_LINE_STRIP); // bottom side
glVertex3f(MINX, MINY, MINZ);
glVertex3f(MAXX, MINY, MINZ);
glVertex3f(MAXX, MAXY, MINZ);
glVertex3f(MINX, MAXY, MINZ);
glVertex3f(MINX, MINY, MINZ);
glEnd();
glBegin(GL_LINE_STRIP); // top side
glVertex3f(MINX, MINY, MAXZ);
glVertex3f(MAXX, MINY, MAXZ);
glVertex3f(MAXX, MAXY, MAXZ);
glVertex3f(MINX, MAXY, MAXZ);
glVertex3f(MINX, MINY, MAXZ);
glEnd();
glBegin(GL_LINES); // left, right, front and back side
glVertex3f(MINX, MINY, MINZ);
glVertex3f(MINX, MINY, MAXZ);
glVertex3f(MAXX, MINY, MINZ);
glVertex3f(MAXX, MINY, MAXZ);
glVertex3f(MAXX, MAXY, MINZ);
glVertex3f(MAXX, MAXY, MAXZ);
glVertex3f(MINX, MAXY, MINZ);
glVertex3f(MINX, MAXY, MAXZ);
glVertex3f(MINX, MINY, MINZ);
glVertex3f(MINX, MINY, MAXZ);
glEnd();
glDisable(GL_BLEND);
}
// }}}
// drawScrollbar() {{{
// ----------------------------------------------------------------------------
// This function draws scrollbar
// ----------------------------------------------------------------------------
void drawScrollbar(View *v, Scrollbar *s)
{
if (v->windowHeight<120) return; // ensure proper window size
if (v->windowWidth<s->xmax+2) return;
glEnable(GL_BLEND);
glColor4fv(getInfoColor()); // display border
glBegin(GL_LINE_LOOP);
glVertex2i(s->xmin, s->ymin);
glVertex2i(s->xmin, s->ymax);
glVertex2i(s->xmax, s->ymax);
glVertex2i(s->xmax, s->ymin);
glEnd();
glColor4fv(getScrollBarColor()); // display slider
glBegin(GL_QUADS);
glVertex2i(s->xmin+1, s->ymin+2);
glVertex2i(s->xmin+1, s->ymax-1);
glVertex2i(s->xmin+s->position, s->ymax-1);
glVertex2i(s->xmin+s->position, s->ymin+2);
glEnd();
glDisable(GL_BLEND);
}
// }}}
// drawInfo() {{{
// ----------------------------------------------------------------------------
// This function displays informations at window' bottom area
// ----------------------------------------------------------------------------
void drawInfo(Object *o, View *v, char *objectType, int activeItem)
{
char *enableDisableStr[]={"disabled", "enabled"};
char str[100];
if (v->windowHeight<120) return; // ensure proper window size
if (v->windowWidth<189) return;
glEnable(GL_BLEND); // draw background
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4fv(getInfoBackground());
glRecti(0, 0, v->windowWidth, 90);
if (activeItem==modelMenu) // highlight menu if necessary
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
sprintf(str, "Object type: %s", objectType);
drawString(str, 10, 71, 0);
if (activeItem==surfelMenu) // highlight menu if necessary
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
sprintf(str, "Surfels size: %d", v->surfelsSize);
drawString(str, 10, 55, 0);
if (activeItem==shadingMenu)
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
sprintf(str, "Shading: %s", shadingString[v->shading-CommandShadingNone]);
drawString(str, 10, 40, 0);
if (activeItem==zBufferMenu)
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
sprintf(str, "Depth buffer: %s", enableDisableStr[v->zBuffer]);
drawString(str, 10, 25, 0);
if (activeItem==blendingMenu)
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
sprintf(str, "Blending: %s", enableDisableStr[o->blending]);
drawString(str, 10, 10, 0);
glDisable(GL_BLEND);
}
// }}}
// drawSurfelsInfo() {{{
// ----------------------------------------------------------------------------
// This function displays surfels informations at window' bottom area
// ----------------------------------------------------------------------------
void drawSurfelsInfo(Object *o, View *v, Mouse *m, int activeItem)
{
char str[100];
if (v->windowHeight<120) return; // ensure proper window size
if (v->windowWidth<390) return;
glEnable(GL_BLEND);
if (activeItem==settingsMenu) // highlight menu item
glColor4fv(getActiveItemColor()); // if necessary
else
glColor4fv(getInfoColor());
drawString("Model settings", 230, 73, 0);
if (activeItem==surfelCountMenu)
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
sprintf(str, "Surfels count: %d", surfelGetCount(o->surfelList));
drawString(str, 230, 40, 0);
glColor4fv(getInfoColor());
sprintf(str, "Rotation: %d %d", m->ynew, m->xnew);
drawString(str, 230, 25, 0);
sprintf(str, "Translation: %d", m->znew);
drawString(str, 230, 10, 0);
if (v->windowWidth<556) return; // ensure proper window size
if (activeItem==surfelCountMenu)
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
sprintf(str, "sqrt(surfels): %d", o->size);
drawString(str, 410, 40, 0);
glDisable(GL_BLEND);
}
// }}}
// drawColorScrollbars() {{{
// ----------------------------------------------------------------------------
// This function displays RGBA scrollbars
// ----------------------------------------------------------------------------
void drawColorScrollbars(View *v, int settings, int activeItem)
{
char *prompt[]={
"Model foreground",
"Model background",
"Fog color",
"Axes color",
"Active item",
"Help foreground",
"Help background",
"Info foreground",
"Info background",
"Scroll bar color"
};
char str[100];
GLfloat r, g, b, a;
if (v->windowHeight<120) return; // ensure proper window size
if (v->windowWidth<350) return;
glEnable(GL_BLEND);
glColor4fv(getInfoColor());
if (activeItem==settingsMenu)
glColor4fv(getActiveItemColor());
drawString(prompt[settings], 230, 73, 0); // draw title
getCurrentColor(&r, &g, &b, &a);
glColor3f(0.9f, 0.5f, 0.5f); // red scrollbar stuff
sprintf(str, "Red: %3.0f%%", r*100.0f);
drawString(str, 230, 55, 0);
if (v->windowWidth>542) {
glBegin(GL_QUADS);
glVertex2i(340, 58);
glVertex2f(340+r*200.0f, 58.0f);
glVertex2f(340+r*200.0f, 61.0f);
glVertex2i(340, 61);
glEnd();
glColor3f(0.8f, 0.4f, 0.4f);
glBegin(GL_LINE_LOOP);
glVertex2i(340, 56);
glVertex2i(540, 56);
glVertex2i(540, 62);
glVertex2i(340, 62);
glEnd();
}
glColor3f(0.5f, 0.9f, 0.5f); // green scrollbar stuff
sprintf(str, "Green: %3.0f%%", g*100.0f);
drawString(str, 230, 40, 0);
if (v->windowWidth>542) {
glBegin(GL_QUADS);
glVertex2i(340, 43);
glVertex2f(340+g*200.0f, 43.0f);
glVertex2f(340+g*200.0f, 46.0f);
glVertex2i(340, 46);
glEnd();
glColor3f(0.4f, 0.8f, 0.4f);
glBegin(GL_LINE_LOOP);
glVertex2i(340, 41);
glVertex2i(540, 41);
glVertex2i(540, 47);
glVertex2i(340, 47);
glEnd();
}
glColor3f(0.5f, 0.5f, 0.9f); // blue scrollbar stuff
sprintf(str, "Blue: %3.0f%%", b*100.0f);
drawString(str, 230, 25, 0);
if (v->windowWidth>542) {
glBegin(GL_QUADS);
glVertex2i(340, 28);
glVertex2f(340+b*200.0f, 28.0f);
glVertex2f(340+b*200.0f, 31.0f);
glVertex2i(340, 31);
glEnd();
glColor3f(0.4f, 0.4f, 0.8f);
glBegin(GL_LINE_LOOP);
glVertex2i(340, 26);
glVertex2i(540, 26);
glVertex2i(540, 32);
glVertex2i(340, 32);
glEnd();
}
glColor3f(0.7f, 0.7f, 0.7f); // alpha scrollbar stuff
sprintf(str, "Alpha: %3.0f%%", a*100.0f);
drawString(str, 230, 10, 0);
if (v->windowWidth>542) {
glBegin(GL_QUADS);
glVertex2i(340, 13);
glVertex2f(340+a*200.0f, 13.0f);
glVertex2f(340+a*200.0f, 16.0f);
glVertex2i(340, 16);
glEnd();
glColor3f(0.6f, 0.6f, 0.6f);
glBegin(GL_LINE_LOOP);
glVertex2i(340, 11);
glVertex2i(540, 11);
glVertex2i(540, 17);
glVertex2i(340, 17);
glEnd();
}
glDisable(GL_BLEND);
}
// }}}
// drawHelp() {{{
// ----------------------------------------------------------------------------
// This function displays help at window' top area
// ----------------------------------------------------------------------------
void drawHelp(View *v)
{
char *helpStr[]={
"F-full screen",
"W-window",
"R-redraw",
"A-axes on/off",
"I-info on/off",
"H-help on/off",
"D-depth buffer",
"B-blending",
"N-none shading",
"X-ax.x shading",
"Y-ax.y shading",
"Z-ax.z shading",
"O-fog shading",
"P-save pos.",
"S-save size",
"Q-quit",
"ESC-quit",
NULL
};
int i;
if (v->windowHeight<396) return; // ensure proper window size
if (v->windowWidth<140) return;
glEnable(GL_BLEND); // draw background
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4fv(getHelpBackground());
glRecti(0, v->info ? 90:0, 140, v->windowHeight-30);
glColor4fv(getHelpColor()); // get text color from configuration
for (i=0; helpStr[i]; i++) { // print all help-lines
drawString(helpStr[i], 10, v->windowHeight-50-i*15, 0);
}
glDisable(GL_BLEND);
}
// }}}
// drawMainMenu() {{{
// ----------------------------------------------------------------------------
// This function displays area and text for main menu rectangle
// ----------------------------------------------------------------------------
void drawMainMenu(View *v, int activeItem)
{
if (v->windowWidth<230) return; // ensure proper window size
glEnable(GL_BLEND); // draw background
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4fv(getInfoBackground());
glRecti(0, v->windowHeight, 230, v->windowHeight-30);
if (activeItem==mainMenu) // highlight menu when necessary
glColor4fv(getActiveItemColor());
else
glColor4fv(getInfoColor());
drawString("Click here for main menu", 20, v->windowHeight-20, 0);
glColor4fv(getAxisColor());
glBegin(GL_LINE_LOOP);
glVertex2i( 10, v->windowHeight-24);
glVertex2i(220, v->windowHeight-24);
glVertex2i(220, v->windowHeight-8);
glVertex2i( 10, v->windowHeight-8);
glEnd();
glDisable(GL_BLEND);
}
// }}}
// buttonsInit() {{{
// ----------------------------------------------------------------------------
// This function initializes Button structure
// ----------------------------------------------------------------------------
void buttonsInit(void)
{
buttons[0].menu=modelMenu; // fill in all fields
buttons[1].menu=surfelMenu;
buttons[2].menu=shadingMenu;
buttons[3].menu=zBufferMenu;
buttons[4].menu=surfelCountMenu;
buttons[5].menu=blendingMenu;
buttons[6].menu=settingsMenu;
}
// }}}
// buttonObjectClick() {{{
// ----------------------------------------------------------------------------
// This callback function is called when user click on [Object type] button
// ----------------------------------------------------------------------------
void buttonObjectClick(void)
{
o.type++;
if (o.type>CommandModelLast) // check type counter
o.type=CommandModelFirst;
if (o.type<CommandModelFirst)
o.type=CommandModelLast;
glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, s.position); // create and align new object
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
}
// }}}
// buttonSurfelsSizeClick() {{{
// ----------------------------------------------------------------------------
// This callback function is called when user click on [Surfel size] button
// ----------------------------------------------------------------------------
void buttonSurfelsSizeClick(void)
{
v.surfelsSize++; // increase surfel size
v.surfelsSize%=10; // and check ranges
if (!v.surfelsSize)
v.surfelsSize=1;
}
// }}}
// buttonShadingClick() {{{
// ----------------------------------------------------------------------------
// This callback function is called when user click on [Shading] button
// ----------------------------------------------------------------------------
void buttonShadingClick(void)
{
v.shading++;
if (v.shading>CommandShadingFog)
v.shading=CommandShadingNone;
}
// }}}
// buttonZBufferClick() {{{
// ----------------------------------------------------------------------------
// This callback function is called when user click on [Z-buffer] button
// ----------------------------------------------------------------------------
void buttonZBufferClick(void)
{
v.zBuffer=!v.zBuffer; // toggle z-buffer flag
}
// }}}
// buttonBlendingClick() {{{
// ----------------------------------------------------------------------------
// This callback function is called when user click on [Blending] button
// ----------------------------------------------------------------------------
void buttonBlendingClick(void)
{
o.blending=!o.blending; // toggle blending flag
}
// }}}
// buttonSurfelsCountClick() {{{
// ----------------------------------------------------------------------------
// This callback function is called when user click on Surfels Count button
// ----------------------------------------------------------------------------
void buttonSurfelsCountClick(void)
{
int sizes[]={10, 20, 25, 50, 100, 150, 200, 250};
int size=s.position;
int i;
for (i=0; i<8; i++) { // find proper size
if (size<sizes[i]) {
s.position=sizes[i];
break;
}
s.position=sizes[0];
}
glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, s.position); // create and align new object
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
glutPostRedisplay();
}
// }}}
// buttonSettingsClick() {{{
// ----------------------------------------------------------------------------
// This callback function is called when user click on Settings button
// ----------------------------------------------------------------------------
void buttonSettingsClick(void)
{
settings++;
if (settings>CommandSettingsScrollBarColor)
settings=CommandSettingsSurfelsCount;
glutPostRedisplay();
}
// }}}
// updateScrollbar() {{{
// ----------------------------------------------------------------------------
// This function updates scrollbar
// ----------------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par
#endif
void updateScrollbar(Scrollbar *s, int x, int y)
{
s->position=x-s->xmin+1;
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// viewInitMouse() {{{
// ----------------------------------------------------------------------------
// This function initializes mouse structure
// ----------------------------------------------------------------------------
void viewInitMouse(Mouse *m)
{
m->xnew=m->ynew=m->znew=0; // initial mouse cursor
m->xold=m->yold=m->zold=0; // position
m->x1=m->y1=m->z1=0; // and derived values
m->xtran0=m->ytran0=0;
m->xtran1=m->ytran1=0;
m->xtran2=m->ytran2=0;
}
// }}}
// viewInit() {{{
// ----------------------------------------------------------------------------
// This function initializes view structure
// ----------------------------------------------------------------------------
void viewInit(View *v)
{
v->fov=45.0;
v->nearPlane=0.1f;
v->farPlane=1000.0;
v->windowWidth=WINDOW_WIDTH;
v->windowHeight=WINDOW_HEIGHT;
v->surfelsSize=2.0;
v->help=true;
v->info=true;
v->axis=true;
v->shading=CommandShadingNone;
v->zBuffer=false;
}
// }}}
// viewLeft() {{{
// ----------------------------------------------------------------------------
// This function changes camera to left-view
// ----------------------------------------------------------------------------
void viewLeft(Mouse *m)
{
m->xnew=m->xold=m->x1=90;
m->ynew=m->yold=m->y1=0;
m->znew=m->zold=m->z1=0;
glutPostRedisplay();
}
// }}}
// viewRight() {{{
// ----------------------------------------------------------------------------
// This function changes camera to right-view
// ----------------------------------------------------------------------------
void viewRight(Mouse *m)
{
m->xnew=m->xold=m->x1=-90;
m->ynew=m->yold=m->y1=0;
m->znew=m->zold=m->z1=0;
glutPostRedisplay();
}
// }}}
// viewTop() {{{
// ----------------------------------------------------------------------------
// This function changes camera to top-view
// ----------------------------------------------------------------------------
void viewTop(Mouse *m)
{
m->xnew=m->xold=m->x1=0;
m->ynew=m->yold=m->y1=90;
m->znew=m->zold=m->z1=0;
glutPostRedisplay();
}
// }}}
// viewBottom() {{{
// ----------------------------------------------------------------------------
// This function changes camera to bottom-view
// ----------------------------------------------------------------------------
void viewBottom(Mouse *m)
{
m->xnew=m->xold=m->x1=0;
m->ynew=m->yold=m->y1=-90;
m->znew=m->zold=m->z1=0;
glutPostRedisplay();
}
// }}}
// viewOriginal() {{{
// ----------------------------------------------------------------------------
// This function changes camera to original view
// ----------------------------------------------------------------------------
void viewOriginal(Mouse *m)
{
m->xnew=m->xold=m->x1=0;
m->ynew=m->yold=m->y1=0;
m->znew=m->zold=m->z1=0;
glutPostRedisplay();
}
// }}}
// viewRotateByMouse() {{{
// ----------------------------------------------------------------------------
// This function performs object rotation
// ----------------------------------------------------------------------------
void viewRotateByMouse(Mouse *m, int x, int y)
{
m->xnew=m->xold+x-m->x1;
m->ynew=m->yold+y-m->y1;
glutPostRedisplay();
}
// }}}
// viewTranslateByMouse() {{{
// ----------------------------------------------------------------------------
// This function performs translation to back/forward
// ----------------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par
#endif
void viewTranslateByMouse(Mouse *m, int x, int y)
{
m->znew=m->zold+y-m->z1;
glutPostRedisplay();
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// onInit() {{{
// ----------------------------------------------------------------------------
// Callback function called before main loop begins
// ----------------------------------------------------------------------------
void onInit(void)
{
viewInit(&v); // initialize view and mouse
viewInitMouse(&m);
objectInit(&o);
glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, 100); // create and align new object
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
glClearColor(0.0, 0.0, 0.0, 0.0); // set OpenGL state
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glEnable(GL_POINT_SMOOTH);
settingsReset();
}
// }}}
// onResize() {{{
// ----------------------------------------------------------------------------
// Callback function called when system needs to resize window
// ----------------------------------------------------------------------------
void onResize(int w, int h)
{
glViewport(0, 0, w, h);
v.windowWidth=w;
v.windowHeight=h;
}
// }}}
// onDisplay() {{{
// ----------------------------------------------------------------------------
// Callback function called when system needs repaint window
// ----------------------------------------------------------------------------
void onDisplay(void)
{
GLfloat *rgba;
rgba=getModelBackground();
glClearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
if (v.zBuffer) // clear Z-buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(v.surfelsSize);
glMatrixMode(GL_PROJECTION); // set projection matrix
glLoadIdentity();
gluPerspective(v.fov,(double)v.windowWidth/(double)v.windowHeight, v.nearPlane, v.farPlane);
glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity();
glViewport(m.xtran0, -m.ytran0, v.windowWidth, v.windowHeight);
glTranslatef(v.help ? 15.0f:0.0f, v.info ? 15.0f:0.0f, -250.0f); // rotate and
glTranslatef(0.0f,0.0f,m.znew); // translate model
glRotatef(m.ynew+rotX, 1.0, 0.0, 0.0);
glRotatef(m.xnew+rotY, 0.0, 1.0, 0.0);
glTranslatef(-(MINX+MAXX)/2.0, -(MINY+MAXY)/2.0, -(MINZ+MAXZ)/2.0);
if (v.axis) drawAxis();
drawObject(&o, &v);
glViewport(0, 0, v.windowWidth, v.windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, v.windowWidth, 0, v.windowHeight, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
o.size=s.position;
drawMainMenu(&v, activeItem);
if (v.info) {
drawInfo(&o, &v, modelString[o.type-CommandModelFirst], activeItem);
if (settings==CommandSettingsSurfelsCount) {
drawSurfelsInfo(&o, &v, &m, activeItem);
drawScrollbar(&v, &s);
}
else
drawColorScrollbars(&v, settings-CommandSettingsSurfelsCount-1, activeItem);
}
if (v.help) drawHelp(&v);
glFlush();
glutSwapBuffers();
}
// }}}
// onKeyboard() {{{
// ----------------------------------------------------------------------------
// Callback function called when user presses some ASCII key
// ----------------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par
#endif
void onKeyboard(unsigned char key, int x, int y)
{
if (key>='A' && key<='Z') // change letter' case
key+='a'-'A';
if (key>='1' && key<='9') { // set surfel size
v.surfelsSize=key-'0';
glutPostRedisplay();
return;
}
switch (key) {
case 27: exit(0); break;
case 'q': exit(0); break;
case 'f': glutFullScreen(); break;
case 'w': glutReshapeWindow(620, 460); glutPositionWindow(20, 20); break;
case 's': objectSaveSize(&o, &v); break;
case 'p': objectSave(&o); break;
case 'r': glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, s.position);
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
glutPostRedisplay(); break;
case 'h': v.help=!v.help; glutPostRedisplay(); break;
case 'i': v.info=!v.info; glutPostRedisplay(); break;
case 'a': v.axis=!v.axis; glutPostRedisplay(); break;
case 'n': v.shading=CommandShadingNone; glutPostRedisplay(); break;
case 'x': v.shading=CommandShadingX; glutPostRedisplay(); break;
case 'y': v.shading=CommandShadingY; glutPostRedisplay(); break;
case 'z': v.shading=CommandShadingZ; glutPostRedisplay(); break;
case 'o': v.shading=CommandShadingFog; glutPostRedisplay(); break;
case 'd': v.zBuffer=!v.zBuffer; glutPostRedisplay(); break;
case 'b': o.blending=!o.blending; glutPostRedisplay(); break;
case 'c': buttonSurfelsCountClick(); break;
// CTRL+letter
case 'M'-64:rotXd=rotYd=0.0f; break;
case 'R'-64:settingsReset(); glutPostRedisplay(); break; // reset settings
case 'L'-64:settingsLoad(); glutPostRedisplay(); break; // load settings
case 'S'-64:settingsSave(); glutPostRedisplay(); break; // save settings
// non-alphabet keys
case '.':
case '>': buttonObjectClick(); break;
case ',':
case '<': o.type-=2; buttonObjectClick(); break;
default: break;
}
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// onSpecialKeyboard() {{{
// ----------------------------------------------------------------------------
// Callback function called when user presses some non-ASCII key
// ----------------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par
#endif
void onSpecialKeyboard(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_F1: setModelAlpha(0.1f); glutPostRedisplay(); break;
case GLUT_KEY_F2: setModelAlpha(0.2f); glutPostRedisplay(); break;
case GLUT_KEY_F3: setModelAlpha(0.3f); glutPostRedisplay(); break;
case GLUT_KEY_F4: setModelAlpha(0.4f); glutPostRedisplay(); break;
case GLUT_KEY_F5: setModelAlpha(0.5f); glutPostRedisplay(); break;
case GLUT_KEY_F6: setModelAlpha(0.6f); glutPostRedisplay(); break;
case GLUT_KEY_F7: setModelAlpha(0.7f); glutPostRedisplay(); break;
case GLUT_KEY_F8: setModelAlpha(0.8f); glutPostRedisplay(); break;
case GLUT_KEY_F9: setModelAlpha(0.9f); glutPostRedisplay(); break;
case GLUT_KEY_F10: setModelAlpha(1.0f); glutPostRedisplay(); break;
case GLUT_KEY_HOME: viewLeft(&m); break;
case GLUT_KEY_END: viewRight(&m); break;
case GLUT_KEY_PAGE_UP: viewTop(&m); break;
case GLUT_KEY_PAGE_DOWN: viewBottom(&m); break;
case GLUT_KEY_INSERT: viewOriginal(&m); break;
case GLUT_KEY_LEFT: rotXd-=0.5f; break;
case GLUT_KEY_RIGHT: rotXd+=0.5f; break;
case GLUT_KEY_UP: rotYd-=0.5f; break;
case GLUT_KEY_DOWN: rotYd+=0.5f; break;
default: break;
}
}
#ifdef __BORLANDC__
#pragma option -w+par
#endif
// }}}
// onMouseButton() {{{
// ----------------------------------------------------------------------------
// Callback function called on mouse click
// ----------------------------------------------------------------------------
void onMouseButton(int button, int state, int x, int y)
{
if (button==GLUT_LEFT_BUTTON) { // if left mouse button is pressed or released
processLeftMouseButton(buttons, state, x, y);
glutPostRedisplay();
}
if (button==GLUT_RIGHT_BUTTON) { // if right mouse button is pressed or released
processRightMouseButton(state, x, y);
glutPostRedisplay();
}
}
// }}}
// onMouseMotion() {{{
// ----------------------------------------------------------------------------
// Callback function called when user moves mouse pointer with button pressed
// ----------------------------------------------------------------------------
void onMouseMotion(int x, int y)
{
switch (m.status) {
case 1: viewRotateByMouse(&m, x, y); break; // rotate object
case 2: viewTranslateByMouse(&m, x, y); break; // translate object
case 3: // translate camera
m.xtran0=m.xtran2+x-m.xtran1;
m.ytran0=m.ytran2+y-m.ytran1;
glutPostRedisplay();
break;
default:
processScrollbars(x, y);
break;
}
}
// }}}
// onPassiveMotion() {{{
// ----------------------------------------------------------------------------
// Callback function called when user moves mouse pointer without button pressed
// ----------------------------------------------------------------------------
void onPassiveMotion(int x, int y)
{
glutDetachMenu(GLUT_LEFT_BUTTON);
glutDetachMenu(GLUT_RIGHT_BUTTON);
setMenuForButton(buttons, x, y);
setMenuForMainButton(x, y);
}
// }}}
// onTimer() {{{
// ----------------------------------------------------------------------------
// Callback function triggered in a specified number of milliseconds
// ----------------------------------------------------------------------------
void onTimer(int value)
{
rotX+=rotXd; // update rotation angles
rotY+=rotYd;
if (fabs(rotXd)>0.1f || fabs(rotYd)>0.1f)
glutPostRedisplay();
glutTimerFunc(20, onTimer, value);
}
// }}}
// onMenu() {{{
// ----------------------------------------------------------------------------
// Callback function called when user selects command from main menu
// ----------------------------------------------------------------------------
void onMenu(int command)
{
if (command>=CommandModelFirst && command<=CommandModelLast) {
o.type=command;
glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, s.position);
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
glutPostRedisplay();
return;
}
if (command>=CommandSurfelCount100 && command<=CommandSurfelCount62500) {
int sizes[]={10, 20, 25, 50, 100, 150, 200, 250};
s.position=sizes[command-CommandSurfelCount100];
glutSetCursor(GLUT_CURSOR_WAIT);
objectCreate(&o, o.type, s.position);
objectSizeMove(&o);
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
glutPostRedisplay();
return;
}
if (command>=CommandSurfelSize1 && command<=CommandSurfelSize9) {
v.surfelsSize=command-CommandSurfelSize1+1;
glutPostRedisplay();
return;
}
if (command>=CommandBlending01 && command<=CommandBlending10) {
setModelAlpha((command-CommandBlending01)/10.0f+0.1f);
glutPostRedisplay();
}
switch (command) {
case CommandSavePositions: objectSave(&o); break;
case CommandSavePositionsSize: objectSaveSize(&o, &v); break;
case CommandRedraw: glutPostRedisplay(); break;
case CommandViewLeft: viewLeft(&m); break;
case CommandViewRight: viewRight(&m); break;
case CommandViewTop: viewTop(&m); break;
case CommandViewBottom: viewBottom(&m); break;
case CommandViewOriginal: viewOriginal(&m); break;
case CommandShadingNone:
case CommandShadingX:
case CommandShadingY:
case CommandShadingZ:
case CommandShadingFog: v.shading=command; glutPostRedisplay(); break;
case CommandZBufferEnable: v.zBuffer=true; glutPostRedisplay(); break;
case CommandZBufferDisable: v.zBuffer=false; glutPostRedisplay(); break;
case CommandBlendingEnable: o.blending=true; glutPostRedisplay(); break;
case CommandBlendingDisable: o.blending=false; glutPostRedisplay(); break;
case CommandShowHelp: v.help=true; glutPostRedisplay(); break;
case CommandHideHelp: v.help=false; glutPostRedisplay(); break;
case CommandShowInfo: v.info=true; glutPostRedisplay(); break;
case CommandHideInfo: v.info=false; glutPostRedisplay(); break;
case CommandShowAxis: v.axis=true; glutPostRedisplay(); break;
case CommandHideAxis: v.axis=false; glutPostRedisplay(); break;
case CommandSettingsReset: settingsReset(); glutPostRedisplay(); break;
case CommandSettingsLoad: settingsLoad(); glutPostRedisplay(); break;
case CommandSettingsSave: settingsSave(); glutPostRedisplay(); break;
case CommandSettingsSurfelsCount:
case CommandSettingsModelForeground:
case CommandSettingsModelBackground:
case CommandSettingsFogColor:
case CommandSettingsAxesColor:
case CommandSettingsActiveItemColor:
case CommandSettingsHelpForeground:
case CommandSettingsHelpBackground:
case CommandSettingsInfoForeground:
case CommandSettingsInfoBackground:
case CommandSettingsScrollBarColor:
settings=command; glutPostRedisplay(); break;
case CommandQuitYes: exit(0); break;
case CommandQuitNo: break;
default: break;
}
}
// }}}
// createMainWindow() {{{
// ----------------------------------------------------------------------------
// This function creates main window
// ----------------------------------------------------------------------------
void createMainWindow(void)
{
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);// set window properties
glutInitWindowPosition(WINDOW_LEFT, WINDOW_TOP);
glutCreateWindow(WINDOW_TITLE);
glutDisplayFunc(onDisplay); // register all callback functions
glutReshapeFunc(onResize);
glutKeyboardFunc(onKeyboard);
glutSpecialFunc(onSpecialKeyboard);
glutMouseFunc(onMouseButton);
glutMotionFunc(onMouseMotion);
glutPassiveMotionFunc(onPassiveMotion);
glutTimerFunc(20, onTimer, 0x1234);
}
// }}}
// createMenu() {{{
// ----------------------------------------------------------------------------
// This function creates main menu and submenus
// ----------------------------------------------------------------------------
void createMenu(void)
{
modelMenu=gpeCreateMenu(menuModel, onMenu);
surfelMenu=gpeCreateMenu(menuSurfelSize, onMenu);
shadingMenu=gpeCreateMenu(menuShading, onMenu);
zBufferMenu=gpeCreateMenu(menuZBuffer, onMenu);
surfelCountMenu=gpeCreateMenu(menuSurfelCount, onMenu);
blendingMenu=gpeCreateMenu(menuBlending, onMenu);
settingsMenu=gpeCreateMenu(menuSettings, onMenu);
mainMenu=gpeCreateMenu(menuMain, onMenu);
}
// }}}
// gpeCreateMenuFromData() {{{
// ----------------------------------------------------------------------------
// This function creates menu from given data structure
// ----------------------------------------------------------------------------
int gpeCreateMenuFromData(GpeMenu *menu, void (*f)(int command))
{
int i=0;
int menuID;
menuID=glutCreateMenu(f);
glutSetMenu(menuID);
while (menu[i].caption!=NULL) {
if (menu[i].subMenu) {
int subMenu=gpeCreateMenuFromData(menu[i].subMenu, f);
glutSetMenu(menuID);
glutAddSubMenu(menu[i].caption, subMenu);
}
else {
glutAddMenuEntry(menu[i].caption, menu[i].id);
}
i++;
}
return menuID;
}
// }}}
// gpeCreateMenu() {{{
// ----------------------------------------------------------------------------
// This function creates context menu
// ----------------------------------------------------------------------------
int gpeCreateMenu(GpeMenu *menu, void (*f)(int command))
{
int result=gpeCreateMenuFromData(menu, f);
return result;
}
// }}}
// main() {{{
// ----------------------------------------------------------------------------
// Main function
// ----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
glutInit(&argc, argv); // initialize glut
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
createMainWindow(); // create main window
createMenu(); // create main menu and all submenus
buttonsInit(); // initialize buttons
confInit(&v, &s, &m, &settings, &activeItem); // initialize configuration module
onInit(); // initialize OpenGL
glutMainLoop(); // enter main loop
return 0; // return error code
}
// }}}
// ----------------------------------------------------------------------------
// finito
// ----------------------------------------------------------------------------
// vim:expandtab:foldenable:foldmethod=marker:foldclose=:foldmarker={{{,}}}
//