|
Tutorial na pohyb glTranslatef() a rotaci glRotatef(). Načítání objektů ze souboru (*.txt)
|
|
|
Nejdříve si načteme objekt (krychli) ze souboru cube.txt. Soubor má tuto podobu
|
|
Vertices: 8
-1.0 -1.0 1 v0
-1.0 1.0 1 v1
1.0 -1.0 1 v2
1.0 1.0 1 v3
1.0 -1.0 -1 v4
1.0 1.0 -1 v5
-1.0 -1.0 -1 v6
-1.0 1.0 -1 v7
|
Hodnota za Vertices: nám zadává, kolik vertexů obsahuje objekt. Protože jde o krychli,
tak máme 8 vrcholů Další hodnoty jsou
X, Y, Z pozice jednotlivých vrcholů. v0 - v7 je jen informativní text,
který se nenačítá. To samé platí o textu Vertices:.
Pro načítání objektů a jejich vykreslování si vytvoříme tyto datové typy
|
|
type
TPoint3d=record //struktura pro 3D bod
x: TGLFloat; //bod x
y: TGLFloat; //bod y
z: TGLFloat; //bod z
end;
type
TGLObject=record //struktura objektu
vers: integer; //počet vrcholů
points: array of TPoint3d; //vrchol je složen z bodu x, y, z
end;
|
Vytvoříme si objekt typu TGLObject
|
|
var
cube1: TGLObject; //objekt cube1
|
A budeme volat proceduru pro načtení objektu ze souboru cube.txt
|
|
procedure LoadAllObjects; //načti objekty
begin
cube1 := LoadObject('objects/cube.txt', cube1); //načti hodnoty uložené v souboru cube.txt a předej je objektu cube1
end;
|
Funkce pro načítání vypadá takto
|
|
function LoadObject(name: string; k: TGLObject): TGLObject; //načti objekt se souboru (name)
var
i: integer; //cyklus
filein: TextFile; //soubor, který budeme číst
ver: integer; //počet vrcholů objektu, pomocná proměnná
rx,ry,rz: TGLFloat; //X, Y, Z pozice vrcholů objektu, pomocná proměnná
Vertices: string[9]; //string o velikosti 10 znaků (Vertices:)
begin AssignFile(filein, name); //spoj proměnnou filein se souborem name
try //zkus otevřít soubor
Reset(filein); //otevři soubor pro čtení
Readln(filein, Vertices, ver); //přečti první řádku, načti string o délce 10 znaků, aby jsi přeskocil string Vertices: a načti počet vrcholů ver
SetLength(k.points, ver); //nastav velikost dynamického pole bodů points
for i := 0 to ver-1 do begin //cykluj podle počtu vrcholů
Readln(filein, rx, ry, rz); //přečti další řádku a načti hodnoty X, Y, Z
k.points[i].x := rx; //předej bodu X (aktuálního vrcholu) hodnotu rx
k.points[i].y := ry; //předej bodu Y (aktuálního vrcholu) hodnotu ry
k.points[i].z := rz; //předej bodu Z (aktuálního vrcholu) hodnotu rz
end;
finally //a nakonec
CloseFile(filein); //zavři soubor
end;
result := k; //vrať funkci hodnoty všech vrcholů objektu
end;
|
Funkce pro načítání objektů se samozřejmě provádějí jen jednou, při startu aplikace.
Při startu aplikace také musíme zapnout DEPTH buffer glEnable(GL_DEPTH_TEST);.
Pokud bychom nechali vypnutý DEPTH buffer, objekty by se vykreslovali v tom pořadí, v jakém
jsou volány, takže by se stalo, že by se zadní stěna krychle vykreslila před přední.
|
|
procedure TForm1.InitWindow;
begin
...
...
////sem budu zadávat funkce, které se mají provádět jen při startu aplikace////
glEnable(GL_DEPTH_TEST); //zapni hloubkový (DEPTH) buffer, aby objekty blíž ke kameře překrývali vzdálenější
LoadGLTextures; //vytvoř textury
LoadAllObjects; //načti objekty
////konec zadávání funkcí, které se mají provádět jen při startu aplikace////
...
...
end;
|
Ještě, než začneme vykreslovat objekt, vypočítáme si pohyb a rotaci.
|
|
var
angle: TPoint3d; //úhel rotace objektu
translate: TPoint3d; //pozice objektu
direction: TPoint3d; //směr pohybu objektu
start: boolean=true; //pomocná proměnná pro načítání základních hodnot při startu aplikace
procedure TranRotCube;
begin
//začátek výpočtu pohybu objektu
if (start) then //jestliže probíhá první otočka cyklu
begin
direction.x := 1; //nastav směr pohybu objektu v X směru na 1
direction.y := 1; //nastav směr pohybu objektu v Y směru na 1
direction.z := 1; //nastav směr pohybu objektu v Z směru na 1
translate.z := -8; //nastav Z pozici objektu
start := false; //nastav start na false, aby při další otočce cyklu se základní hodnoty nenačítaly
end;
if ((translate.x >= 3) or (translate.x <= -3)) then //jetliže X pozice objektu přesáhne hodnoty 3 nebo -3
begin
direction.x := -direction.x; //otoč směr pohybu X
end;
translate.x := translate.x + (0.01 * direction.x); //přičti 0.01 pozici X, podle směru pohybu X
if ((translate.y >= 2) or (translate.y <= -2)) then //jetlize Y pozice objektu přesáhne hodnoty 2 nebo -2
begin
direction.y := -direction.y; //otoč směr pohybu Y
end;
translate.y := translate.y + (0.01 * direction.y); //přičti 0.01 pozici Y, podle směru pohybu Y
if ((translate.z >= -6) or (translate.z <= -20)) then //jetliže Z pozice objektu přesáhne hodnoty -6 nebo -20
begin
direction.z := -direction.z; //otoč směr pohybu Z
end;
translate.z := translate.z + (0.01 * direction.z); //přičti 0.01 pozici Z, podle směru pohybu Z
//konec výpočtu pohybu objektu
//začátek výpočtu rotace objektu
angle.x := angle.x + 0.5; //přičti úhel X rotace
if (angle.x >= 360) then //jestliže je úhel větší, než 360 stupňů
begin
angle.x := angle.x -360; //odečti 360 stupňů
end;
angle.y := angle.y + 1; //přičti úhel Y rotace
if (angle.y >= 360) then //jestliže je úhel větší, než 360 stupňů
begin
angle.y := angle.y -360; //odečti 360 stupňů
end;
angle.z := angle.z + 1.5; //přičti úhel Z rotace
if (angle.z >= 360) then //jestliže je úhel větší, než 360 stupňů
begin
angle.z := angle.z -360; //odečti 360 stupňů
end;
//konec výpočtu rotace objektu
end;
|
A nakonec budeme vykreslovat objekt v nekonečné smyčce.
|
|
procedure DrawCube; //vykresli krychli
begin
TranRotCube; //vypočítej pohyb a rotaci krychle
//začátek bloku OpenGL příkazu pro vykreslení objektu (krychle)
glEnable(GL_TEXTURE_2D); //zapni 2D texturování
glBindTexture(GL_TEXTURE_2D, Texture[0]); //potáhni následující objekt texturou číslo 0
glPushMatrix; //začátek prostorové matice
//posouvej a rotuj objektem (který je mezi glPushMatrix; a glPopMatrix;) podle vypočtených hodnot
glTranslatef( translate.x, translate.y, translate.z); //pohni celým objektem
glRotatef( angle.x, 1, 0, 0); //rotuj objektem v X směru
glRotatef( angle.y, 0, 1, 0); //rotuj objektem v Y směru
glRotatef( angle.z, 0, 0, 1); //rotuj objektem v Z směru
glBegin(GL_TRIANGLES); //začni vykreslovat trojúhelníky
//------------------------
//přední stěna krychle
//první trojúhelník
glTexCoord2f( 0, 0); glVertex3f( cube1.points[0].x, cube1.points[0].y, cube1.points[0].z); //levý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[1].x, cube1.points[1].y, cube1.points[1].z); //levý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[2].x, cube1.points[2].y, cube1.points[2].z); //pravý dolní vrchol textury a výsledného čtverce
//druhý trojúhelník
glTexCoord2f( 1, 1); glVertex3f( cube1.points[3].x, cube1.points[3].y, cube1.points[3].z); //pravý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[2].x, cube1.points[2].y, cube1.points[2].z); //pravý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[1].x, cube1.points[1].y, cube1.points[1].z); //levý horní vrchol textury a výsledného čtverce
//-------------------------
//pravá stěna krychle
//první trojúhelník
glTexCoord2f( 0, 0); glVertex3f( cube1.points[2].x, cube1.points[2].y, cube1.points[2].z); //levý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[3].x, cube1.points[3].y, cube1.points[3].z); //levý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[4].x, cube1.points[4].y, cube1.points[4].z); //pravý dolní vrchol textury a výsledného čtverce
//druhý trojúhelník
glTexCoord2f( 1, 1); glVertex3f( cube1.points[5].x, cube1.points[5].y, cube1.points[5].z); //pravý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[4].x, cube1.points[4].y, cube1.points[4].z); //pravý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[3].x, cube1.points[3].y, cube1.points[3].z); //levý horní vrchol textury a výsledného čtverce
//-------------------------
//zadní stěna krychle
//první trojúhelník
glTexCoord2f( 0, 0); glVertex3f( cube1.points[4].x, cube1.points[4].y, cube1.points[4].z); //levý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[5].x, cube1.points[5].y, cube1.points[5].z); //levý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[6].x, cube1.points[6].y, cube1.points[6].z); //pravý dolní vrchol textury a výsledného čtverce
//druhý trojúhelník
glTexCoord2f( 1, 1); glVertex3f( cube1.points[7].x, cube1.points[7].y, cube1.points[7].z); //pravý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[6].x, cube1.points[6].y, cube1.points[6].z); //pravý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[5].x, cube1.points[5].y, cube1.points[5].z); //levý horní vrchol textury a výsledného čtverce
//-------------------------
//levá stěna krychle
//první trojúhelník
glTexCoord2f( 0, 0); glVertex3f( cube1.points[6].x, cube1.points[6].y, cube1.points[6].z); //levý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[7].x, cube1.points[7].y, cube1.points[7].z); //levý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[0].x, cube1.points[0].y, cube1.points[0].z); //pravý dolní vrchol textury a výsledného čtverce
//druhý trojúhelník
glTexCoord2f( 1, 1); glVertex3f( cube1.points[1].x, cube1.points[1].y, cube1.points[1].z); //pravý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[0].x, cube1.points[0].y, cube1.points[0].z); //pravý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[7].x, cube1.points[7].y, cube1.points[7].z); //levý horní vrchol textury a výsledného čtverce
//-------------------------
//vrchní stěna krychle
//první trojúhelník
glTexCoord2f( 0, 0); glVertex3f( cube1.points[1].x, cube1.points[1].y, cube1.points[1].z); //levý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[7].x, cube1.points[7].y, cube1.points[7].z); //levý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[3].x, cube1.points[3].y, cube1.points[3].z); //pravý dolní vrchol textury a výsledného čtverce
//druhý trojúhelník
glTexCoord2f( 1, 1); glVertex3f( cube1.points[5].x, cube1.points[5].y, cube1.points[5].z); //pravý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[3].x, cube1.points[3].y, cube1.points[3].z); //pravý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[7].x, cube1.points[7].y, cube1.points[7].z); //levý horní vrchol textury a výsledného čtverce
//-------------------------
//spodní stěna krychle
//první trojúhelník
glTexCoord2f( 0, 0); glVertex3f( cube1.points[6].x, cube1.points[6].y, cube1.points[6].z); //levý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[0].x, cube1.points[0].y, cube1.points[0].z); //levý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[4].x, cube1.points[4].y, cube1.points[4].z); //pravý dolní vrchol textury a výsledného čtverce
//druhý trojúhelník
glTexCoord2f( 1, 1); glVertex3f( cube1.points[2].x, cube1.points[2].y, cube1.points[2].z); //pravý horní vrchol textury a výsledného čtverce
glTexCoord2f( 1, 0); glVertex3f( cube1.points[4].x, cube1.points[4].y, cube1.points[4].z); //pravý dolní vrchol textury a výsledného čtverce
glTexCoord2f( 0, 1); glVertex3f( cube1.points[0].x, cube1.points[0].y, cube1.points[0].z); //levý horní vrchol textury a výsledného čtverce
//-------------------------
glEnd(); //ukonči vykreslování trojúhelníků
glPopMatrix; //konec prostorové matice
//konec bloku OpenGL příkazu pro vykreslení objektu (krychle)
end;
|
V této proceduře DrawCube konečně používáme OpenGL příkazy. Všechny předešlé funkce nemají s OpenGL nic
společného. Provádějí jen náčítání hodnot ze souboru cube.txt a výpočet pohybu a rotace.
glTranslatef( translate.x, translate.y, translate.z); - pohybuje objektem v X,Y,Z směru, podle předem vypočtených hodnot translate.x, translate.y, translate.z
glRotatef( angle.x, 1, 0, 0);
glRotatef( angle.y, 0, 1, 0);
glRotatef( angle.z, 0, 0, 1); - rotují objektem v X,Y,Z směru, podle předem vypočtených hodnot angle.x, angle.y, angle.z
glVertex3f( cube1.points[0].x, cube1.points[0].y, cube1.points[0].z);
glVertex3f( cube1.points[1].x, cube1.points[1].y, cube1.points[1].z);
glVertex3f( cube1.points[2].x, cube1.points[2].y, cube1.points[2].z);
glVertex3f( cube1.points[3].x, cube1.points[3].y, cube1.points[3].z);
glVertex3f( cube1.points[4].x, cube1.points[4].y, cube1.points[4].z);
glVertex3f( cube1.points[5].x, cube1.points[5].y, cube1.points[5].z);
glVertex3f( cube1.points[6].x, cube1.points[6].y, cube1.points[6].z);
glVertex3f( cube1.points[7].x, cube1.points[7].y, cube1.points[7].z);
- vykreslí krychli z trojúhelníků, podle načtených hodnot cube1.points[ ], ze souboru cube.txt
|
|
Home