//----------------------------------------------------------------------------- // Fraktaly v pocitacove grafice // serial na http://www.root.cz // // Ukazkovy priklad cislo 72.1 // Autor: Pavel Tisnovsky // // Program po svem spusteni otevre hlavni okno a vykresli do nej jednorozmernou // Perlinovu sumovou funkci. Blizsi informace o ovladani tohoto programu jsou // uvedeny v 72.casti serialu o fraktalech. //----------------------------------------------------------------------------- #ifdef __BORLANDC__ #include <windows.h> #endif #include <GL/glut.h> // hlavickovy soubor funkci GLUTu a OpenGL #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define WINDOW_TITLE "Fraktaly 72.1" // titulek okna #define WINDOW_WIDTH 512 // pocatecni velikost okna #define WINDOW_HEIGHT 384 double alpha=2.0; double beta=2.0; int n=5; // Perlin pouziva funkci random(), my ji nahradime standardni funkci rand() #define random() rand() #include "perlin.h" // toto sice neni moc koser, ale neni zapotrebi premyslet na linkerem :-) #include "perlin.c" //----------------------------------------------------------------------------- // Prekresleni jednorozmerne Perlinovy sumove funkce //----------------------------------------------------------------------------- void recalcPerlinNoise1D(double alpha, double beta, int n) { int i; double x=-5.0, y; // pocatecni hodnota souradnice x int width=glutGet(GLUT_WINDOW_WIDTH); // sirka okna int height=glutGet(GLUT_WINDOW_HEIGHT); // vyska okna glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINE_STRIP); // zacatek vykreslovani lomene cary (polycary) for (i=0; i<width; i++) { y=PerlinNoise1D(x, alpha, beta, n); // vypocet Perlinovy funkce y*=(double)height/2.0; // zmena amplitudy podle vysky okna y+=height>>1; // posun ve vertikalnim smeru do stredu okna glVertex2f(i, y); // pripojeni dalsi casti lomene cary x+=10.0/(double)width; // prechod na dalsi souradnici v horizontalnim smeru } glEnd(); // konec vykreslovani lomene cary } //----------------------------------------------------------------------------- // Vykresleni retezce na obrazovku //----------------------------------------------------------------------------- void drawString(const int x, const int y, // umisteni retezce const float r, const float g, const float b, // barva pisma char *str) // ukazatel na retezec { char *c; glColor3f(r, g, b); glRasterPos2i(x, y); for (c=str; *c!=0; c++) { glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *c); } } //----------------------------------------------------------------------------- // Vypis informaci o vykreslovane sumove funkci //----------------------------------------------------------------------------- void drawInfo(double alpha, double beta, int n) { char str[100]; sprintf(str, "[1][2] alpha = %4.1f", alpha); drawString(10, 48, 1.0, 1.0, 0.0, str); sprintf(str, "[3][4] beta = %4.1f" , beta); drawString(10, 32, 0.6, 1.0, 0.2, str); sprintf(str, "[5][6] n = %d ", n); drawString(10, 16, 0.2, 1.0, 0.6, str); } //----------------------------------------------------------------------------- // Funkce volana pro inicializaci vykreslovani //----------------------------------------------------------------------------- void onInit(void) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // barva pozadi glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // mod ulozeni pixelu recalcPerlinNoise1D(alpha, beta, n); } //----------------------------------------------------------------------------- // Nastaveni souradneho systemu v zavislosti na velikosti okna //----------------------------------------------------------------------------- void onResize(int w, int h) // argumenty w a h reprezentuji novou velikost okna { glViewport(0, 0, w, h); // viditelna oblast pres cele okno glMatrixMode(GL_PROJECTION); // zacatek modifikace projekcni matice glLoadIdentity(); // vymazani projekcni matice (=identita) glOrtho(0, w, 0, h, -1, 1); // mapovani abstraktnich souradnic do souradnic okna } //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri kazdem prekresleni okna //----------------------------------------------------------------------------- void onDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); // vymazani vsech bitovych rovin barvoveho bufferu glDrawBuffer(GL_FRONT); // pixmapa se bude kreslit do predniho barvoveho bufferu glRasterPos2i(0, 0); // nastaveni souradnic leveho spodniho rohu pixmapy recalcPerlinNoise1D(alpha, beta, n); // prepocet Perlinovy sumove funkce drawInfo(alpha, beta, n); // vypis informaci o diagramu glFlush(); // provedeni a vykresleni vsech zmen } //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri stlaceni ASCII klavesy //----------------------------------------------------------------------------- #ifdef __BORLANDC__ #pragma option -w-par #endif void onKeyboard(unsigned char key, int x, int y) { key=(key>='A' && key<='Z') ? key-'A'+'a': key; switch (key) { case 27: // pokud byla stlacena klavesa ESC, konec programu case 'q': exit(0); break; // totez co klavesa ESC case 'f': glutFullScreen(); break; // prepnuti okna na celou obrazovku case 'w': glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT); break; // prepnuti okna na puvodni velikost case '1': alpha-=0.5; glutPostRedisplay(); break; // zmena parametru alpha case '2': alpha+=0.5; glutPostRedisplay(); break; case '3': beta-=0.5; glutPostRedisplay(); break; // zmena parametru beta case '4': beta+=0.5; glutPostRedisplay(); break; case '5': if (n>0) n--; glutPostRedisplay(); break; // zmena parametru n case '6': n++; glutPostRedisplay(); break; default: break; } } #ifdef __BORLANDC__ #pragma option -w+par #endif //----------------------------------------------------------------------------- // Hlavni funkce konzolove aplikace //----------------------------------------------------------------------------- int main(int argc, char **argv) { glutInit(&argc, argv); // inicializace knihovny GLUT glutCreateWindow(WINDOW_TITLE); // vytvoreni okna pro kresleni glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);// zmena velikosti okna glutPositionWindow(100, 100); // pozice leveho horniho rohu okna glutDisplayFunc(onDisplay); // registrace funkce volane pri prekreslovani okna glutReshapeFunc(onResize); // registrace funkce volane pri zmene velikosti okna glutKeyboardFunc(onKeyboard); // registrace funkce volani pri stlaceni klavesy onInit(); // inicializace vykreslovani glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane funkce return 0; // navratova hodnota vracena operacnimu systemu } //----------------------------------------------------------------------------- // finito //-----------------------------------------------------------------------------