//---------------------------------------------------------------------
// Ukazkovy priklad k serii clanku OpenGL a GLU
//
// Autor: Pavel Tisnovsky
// Cislo clanku: 10
// Cislo prikladu: 4
//
// Zobrazeni prubehu funkce b3() pomoci lomene cary.
// Pomoci klavesy 'f' lze provest prepnuti do celeho okna, klavesou 'w'
// se provede nastaveni puvodni velikosti okna, tj. 450x450 pixelu.
// Klavesou ESC je mozne program ukoncit.
//---------------------------------------------------------------------
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#define WINDOW_WIDTH 450 // velikost okna
#define WINDOW_HEIGHT 700
#define WINDOW_TITLE "OpenGL a GLU, priklad 10.4" // titulek okna
// bazove funkce
float b0(const float t, const int i);
float b1(const float t, const int i);
float b2(const float t, const int i);
float b3(const float t, const int i);
#define MAX 6
// x-ove souradnice ridicich bodu
float x[MAX]={000,000,100,100,200,300};
// y-ove souradnice ridicich bodu
float y[MAX]={000,100,100,000,000,100};
// uzlovy vektor
float knot[]={0,0,0,0,1,2,3,4,4,4,4};
//---------------------------------------------------------------------
// Bazova funkce b0()
//---------------------------------------------------------------------
float b0(const float t, const int i)
{
float p;
if ((knot[i]<=t)&&(t<knot[i+1])) p=1.0;
else p=0.0;
return p;
}
//---------------------------------------------------------------------
// Bazova funkce b1()
//---------------------------------------------------------------------
float b1(const float t, const int i)
{
float p,a,b;
a=(t-knot[i]);
b=(knot[i+1]-knot[i]);
if (b==0) p=0.0;
else p=b0(t,i)*a/b;
a=(knot[i+2]-t);
b=(knot[i+2]-knot[i+1]);
if (b==0) p+=0.0;
else p+=b0(t,i+1)*a/b;
return p;
}
//---------------------------------------------------------------------
// Bazova funkce b2()
//---------------------------------------------------------------------
float b2(const float t, const int i)
{
float p,a,b;
a=(t-knot[i]);
b=(knot[i+2]-knot[i]);
if (b==0) p=0.0;
else p=b1(t,i)*a/b;
a=(knot[i+3]-t);
b=(knot[i+3]-knot[i+1]);
if (b==0) p+=0.0;
else p+=b1(t,i+1)*a/b;
return p;
}
//---------------------------------------------------------------------
// Bazova funkce b3()
//---------------------------------------------------------------------
float b3(const float t, const int i)
{
float p,a,b;
a=(t-knot[i]);
b=(knot[i+3]-knot[i]);
if (b==0) p=0.0;
else p=b2(t,i)*a/b;
a=(knot[i+4]-t);
b=(knot[i+4]-knot[i+1]);
if (b==0) p+=0.0;
else p+=b2(t,i+1)*a/b;
return p;
}
//---------------------------------------------------------------------
// Funkce pro inicializaci vykreslovani
//---------------------------------------------------------------------
void onInit(void)
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glEnable(GL_LINE_SMOOTH);
}
//--------------------------------------------------------------------
// Tato funkce je volana pri kazdem prekresleni okna
//--------------------------------------------------------------------
void onDisplay(void)
{
float d,f,x,y;
int i,j;
glClear(GL_COLOR_BUFFER_BIT);
// vykresleni prubehu bazove funkce b0()
for (i=0; i<7; i++) { // ctyri ruzne prubehu pro ctyri pozice v uzlovem vektoru
glBegin(GL_LINE_STRIP);
for (d=0; d<4; d+=0.05) { // smycka pro vypocet bodu na krivce
x=50+80.0*d;
f=b3(d, i); // vypocet hodnoty funkce b3()
y=100*i+80-60.0*f;
glVertex2f(x,y); // vykresleni dalsiho vrcholu lomene cary
}
glEnd();
}
glFlush();
}
//---------------------------------------------------------------------
// Nastaveni souradneho systemu v zavislosti na velikosti okna
//---------------------------------------------------------------------
void onResize(GLsizei w, GLsizei h)
{
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
glScalef(1, -1, 1); // inverze y-ove osy, aby se y zvetsovalo smerem dolu
glTranslatef(0, -h, 0); // posun pocatku do leveho horniho rohu
}
//---------------------------------------------------------------------
// Tato funkce je volana pri stlaceni ASCII klavesy
//---------------------------------------------------------------------
#ifdef __BORLANDC__
#pragma option -w-par // zabranit warningum pri prekladu
#endif // u borlandskych prekladacu
void onKeyboard(unsigned char key, int x, int y)
{
if (key>='A' && key<='Z') // uprava velkych pismen na mala
key+=(unsigned char)('a'-'A'); // pro zjednoduseni prikazu switch
switch (key) {
case 27: exit(0); break; // ukonceni aplikace
case 'q': exit(0); break; // ukonceni aplikace
case 'f': glutFullScreen(); break; // prepnuti na celou obrazovku
case 'w': glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT); 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
glutInitDisplayMode(GLUT_RGB); // nastaveni dvou barvovych bufferu a pameti hloubky
glutInitWindowPosition(30, 30); // pocatecni pozice leveho horniho rohu okna
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);// pocatecni velikost okna
glutCreateWindow(WINDOW_TITLE); // vytvoreni okna pro kresleni
glutDisplayFunc(onDisplay); // registrace funkce volane pri prekreslovani okna
glutReshapeFunc(onResize); // registrace funkce volane pri zmene velikosti okna
glutKeyboardFunc(onKeyboard); // registrace funkce volane pri stlaceni klavesy
onInit(); // inicializace vykreslovani
glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane funkce
return 0; // navratova hodnota vracena operacnimu systemu
}
//---------------------------------------------------------------------
// Konec zdrojoveho souboru
//---------------------------------------------------------------------