Hlavne menu We are sorry, but magazine AMMO is suspended. Here is just read-only access to the articles archive. Some features are removed because they were outdated, pointless in read-only (voting and pools), or it was missused by spammers (comments) etc. Now the webpages aren't maintained so when something will get broken most probably it won't be fixed at all. If you liked our magazine then please make donation with paypal so we can pay for traffic on this server.

TOP Výuka
01 Maľované krížovky 103 bodov
02 OpenGL, lákadlo 38 bodov
03 MySQL (+ použitie Visual C++ a PHP) 28 bodov
04 OpenGL, časť 1 21 bodov
05 Huffmanove kódovanie 19 bodov
06 Pascal, časť 1 18 bodov
07 Ako tlačiť s HP 16 bodov
08 Základy HTML časť 2 16 bodov
09 Základy HTML časť 3 13 bodov
10 Hry pre nenáročných + zdrojáky 10 bodov
11 OpenGL, úvod 8 bodov
12 Faktúrka v4.0 + zdrojáky v MS Visual C++ 6.0 7 bodov
13 OpenGL – Intermezzo 1 7 bodov
14 OpenGL povinná literatúra 6 bodov
15 Základy HTML časť 1 6 bodov
Najnovsie clanky
Kvalitné služby podľa skúseností iných - TopSlužby.sk
LOTR - Dve veže - Parodia - Scénka 2. časť
Neverwinter nights
Children Of Bodom-Hatebreeder
Kult Duny - 6. časť (Bonus)
Kult Duny - 5. časť (Filmy, Hry)
Dobré ráno. (morc certa, hora incerta...)
Kult Duny - 4. časť (Knihy 2/2)
Stretnutie Spoločenstva Tolkiena
GRAVE DIGGER – Knights Of The Cross
Kult Duny - 3. časť (Knihy 1/2)
Kult Duny - 2. časť (Pojmy)
Kult Duny - 1. časť (Úvod)
LOTR - Dve veže - Parodia - Scénka
Jackass
Vsetky clanky
Airsoft - Specnaz [4 clanky]
Básne [6 clankov]
Fantázia [4 clanky]
Filmy a DVD [51 clankov]
Hardware [10 clankov]
Hry [170 clankov]
Hry, návody [6 clankov]
Hudba [8 clankov]
Internet [7 clankov]
Knihy [6 clankov]
O AMME [4 clanky]
Pandemonium [10 clankov]
Poviedky [14 clankov]
Programy [18 clankov]
Rôzne [8 clankov]
Technické [3 clanky]
Úvahy [8 clankov]
Výuka [50 clankov]
Ako tlačiť s HP
Algoritmy v grafoch
Fake2
Faktúrka
Faktúrka v4.0 + zdrojáky v MS Visual C++ 6.0
Fract
HLSaver
Hry pre nenáročných + zdrojáky
Huffmanove kódovanie
IPicture2 & aggresiveoptimize.h
Maľované krížovky
MySQL (+ použitie Visual C++ a PHP)
OpenGL - GLWnd
OpenGL AMMO Saver
OpenGL povinná literatúra
OpenGL – Intermezzo 1
OpenGL, časť 10
OpenGL, časť 11
OpenGL, časť 12
OpenGL, časť 13
OpenGL, časť 14
OpenGL, časť 15
OpenGL, časť 16
OpenGL, časť 17
OpenGL, časť 18
OpenGL, časť 8
OpenGL, časť 9
Opengl – Cloth Simulation
RenameR
SkinMagic
WinSocket Communication via VC++
Údajové štruktúry
viac...
Zábava [5 clankov]
Zdravie [15 clankov]
Celkovy pocet clankov: 407
OpenGL, časť 7 
Výuka | Dna 3.4.2002 | Johny | 5 znamok, priemer 3.00 | 6411 videni | 921 WAP videni

V tejto časti sa naučíme používať tri rôzne tipy textúrovacích filtrov. A tiež pridáme nejaké to ovládanie objektu na klávesnicu. Naším objektom bude ako zvyčajne kocka. Tá sa bude točiť, budeme môcť cez klávesnicu meniť rýchlosť otáčania okolo jednotlivých osí a tiež ju približovať a vzďaľovať od kamery. A trošku už zájdeme aj do svetiel.
Ako vidíte, táto časť pokrýva dosť veľkú časť nových informácií, takže ak si v niečom nie ste istí, radšej sa ešte pozrite na predchádzajúce časti.

A môžeme ísť na to.
Na začiatok programu pridáme ešte pár premenných.


#include <windows.h>
#include <stdio.h>
#include <glgl.h>
#include <glglu.h>
#include <glglaux.h>

HDC hDC=NULL; // GDI Device Context
HGLRC hRC=NULL; // Rendering Context
HWND hWnd=NULL; // Window Handle
HINSTANCE hInstance; // Instance aplikácie

bool keys[256];
bool active=TRUE;
bool fullscreen=TRUE;

Riadok pod si spravíme premennú light, ktorá nám bude hovoriť, či je svetlo zapnuté alebo nie. BOOL je premenná ako v pascale boolean, nadobúda hodnoty true a false. A ešte premennú, ktorá nám bude hovoriť, či bol stlačený kláves L. A takú istú premennú pre kláves F.


BOOL light; // Lighting ON / OFF
BOOL lp; // L stlačené?
BOOL fp; // F stlačené?


Teraz prídu premenné, ktoré budú sledovať rotáciu objektu.


GLfloat xrot;
GLfloat yrot;
GLfloat xspeed;
GLfloat yspeed;
GLfloat z=-5.0f; // ako hlboko

Ďalej pridáme polia, ktoré budú použité pri tvorbe svetla. Budeme používať 2 rôzne typy svetiel. Ambient a diffuse. Ambient je svetlo, ktoré neprichádza z nijakého smeru., osvetľuje všetky objekty. Diffuse je tvorené z nejakého zdroja svetla a odráža a „rozpíja“ sa na povrchu objektov. Skúste si s hodnotami zaexperimentovať, tak najlepšie uvidíte, ako toto svetlo pôsobí na povrchy objektov.

Svetlo sa tvorí presne takou istou cestou ako farby. Teda ideme po poradí farieb RGB a nakoniec pridáme intenzitu.


GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; // Ambient

GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; // Diffuse

A nakoniec si uložíme pozíciu svetla. Prvé tri parametre sú presne také ako pri glTranslate. Prvé číslo je posun na x, druhé y a tretie z. My chceme, aby svetlo svietilo priamo na kocku, takže nebudeme ho posúvať ani po x ani po y. A chceme ho otršku dozadu, takže nastavíme posledný parameter na 2.0 na osi z.
Posledné číslo hovorí Opengl, že naše súradnice sú pozícia zdroja svetla. Viacej o tomto bude v inej časti.

GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };

Ďalej si urobíme premennú pre 3 typy textúr. Prvá bude používať gl_nearest (žiadne vyhladzovanie). Druhá bude gl_linear, ktorá už trošku zahladí obrázok. A tretia bude používať mipmappovanú textúru, ktorá už bude vyzerať fakt pekne.


GLuint filter; // číslo filtru
GLuint texture[3]; // miesto pre 3 textúry

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc

Teraz ideme nahrať textúry. Veľmi veľa sa toho nezmenilo.

AUX_RGBImageRec *LoadBMP(char *Filename)
{
FILE *File=NULL;

if (!Filename)
{
return NULL;
}

File=fopen(Filename,"r");

if (File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}
return NULL;
}


int LoadGLTextures()
{
int Status=FALSE;

AUX_RGBImageRec *TextureImage[1];

memset(TextureImage,0,sizeof(void *)*1);

if (TextureImage[0]=LoadBMP("Data/Crate.bmp"))
{
Status=TRUE;

glGenTextures(3, &texture[0]); // vytvor 3 textúry


// Nearest Filtered
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); ( NEW )
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); ( NEW )
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);


// Linear Filtered
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

Mipmapping... funguje asi tak, že si vytvorí viacej textúr pre jeden obrázok. V rôznej kvalite. A keď sa rozhodnete niečo textúrovať, tak Opengl zvolí najlepšie vyzerajúcu textúru. Isteže, môžete si povedať, že najlepšia je vždy tá, ktorá je najväčšia. Ale to nie je pravda. Keď máte textúru 512x512 a chcete ju zobraziť na maličkú plochu, tak ju tam zobrazíte, ale pri pohybe sa bude zdať, ako keby tam niečo „šumelo“. Proste vidno, že sem-tam niečo zazrní. To je tým, že niektoré pixely nie sú zobrazované pri inom pohľade, iné zase pri inom a ani lineárne filtrovanie tomu nepomôže. Ak ste si pozerali Opengl lákadlo, tak aj tam sa to dalo zbadať. Vľavo hore rotoval obrázok loga amma. A vždy, keď už bol takmer kolmo hranou na obrazovku, tak bolo vidno, ako to „zazrnilo“.



// MipMapped
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); ( NEW )

Tu už tvoríme mipmappované textúry. Hovoríme opengl, že chceme 2D textúry, budeme používať 3 farby, povieme rozmer obrázka, typ dát, a kde sú dáta.

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}


if (TextureImage[0])
{
if (TextureImage[0]->data)
{
free(TextureImage[0]->data);
}

free(TextureImage[0]);
}


return Status;
}



int InitGL(GLvoid)
{
if (!LoadGLTextures())
{
return FALSE;
}

glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

A teraz nastavíme svetlo pre Ambient a diffuse.

glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); //

glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);

A bude svetlo...

glEnable(GL_LIGHT1);
return TRUE;
}


int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity();



glTranslatef(0.0f,0.0f,z);

glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);


Vyberáme textúru vždy podľa filtra.
glBindTexture(GL_TEXTURE_2D, texture[filter]);

glBegin(GL_QUADS);


glNormal3f je pre vás nové. Hovorí o normále, teda o kolmici na plochu. Je to potrebné pre opengl, aby vedelo, ako má vypočítať napríklad svetlo alebo, ktorá strana je predná, ktorá zadná.


// predná strana
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// zadná strana
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// vrchná strana
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// spodná strana
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// pravá strana
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// ľavá strana
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();


xrot+=xspeed;
yrot+=yspeed;
return TRUE;
}



Ešte pridáme, čo sa má udiať pri stlačení L a F a už to máme celé hotové.


SwapBuffers(hDC);
if (keys['L'] && !lp)
{

lp=TRUE;
light=!light;


if (!light)
{
glDisable(GL_LIGHTING); //vypneme
}
else
{
glEnable(GL_LIGHTING); // zapneme }
}



if (!keys['L'])
{
lp=FALSE;
}


if (keys['F'] && !fp) {
fp=TRUE;
filter+=1;
if (filter>2)
{
filter=0;
}
}
if (!keys['F'])
{
fp=FALSE;
}


if (keys[VK_PRIOR]) //PgUp
{
z-=0.02f;
}


if (keys[VK_NEXT]) //PgDown
{
z+=0.02f;
}

if (keys[VK_UP])
{
xspeed-=0.01f;
}
if (keys[VK_DOWN])
{
xspeed+=0.01f;
}
if (keys[VK_RIGHT])
{
yspeed+=0.01f;
}
if (keys[VK_LEFT])
{
yspeed-=0.01f;
}

Ďalej je už všetko po starom.

if (keys[VK_F1])
{
keys[VK_F1]=FALSE;
KillGLWindow();
fullscreen=!fullscreen;
if (!CreateGLWindow("NeHe's Textures, Lighting & Keyboard Tutorial",640,480,16,fullscreen))
{
return 0;
}
}
}
}
}

KillGLWindow();
return (msg.wParam);
}


Teraz už viete tvoriť fakt pekné a najmä realistické scény. A pri hraní nejakej 3D hry si už určite aj sem-tam všimnete, že tá textúra vzadu je nejaká nižšej kvality. A dokonca aj nájdete prechody medzi jednotlivými mipmappovými úrovňami. Napríklad v Maxovi Paynovi stačí znížiť detaily a je to ľahko badateľné.

http://www.softsklad.host.sk/opengl/lesson07.zip


Najnovsie clanky od tohto redaktora
Podobne clanky