Hlavní navigace

Knihovna PyOpenGL (6)

19. 5. 2005
Doba čtení: 5 minut

Sdílet

V dnešním dílu si budeme povídat o display-listech, materiálech a nastavení světla. Samozřejmě nebude chybět příklad.

Nejprve kus kódu jako příklad:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from sys import argv

SPHERE = 1
CUBE = 2

def reshape(width, height):
    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0)
    glMatrixMode(GL_MODELVIEW)

def draw():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()
    glTranslatef(-2.5, 0.0, 0.0)
    glCallList(SPHERE)
    glLoadIdentity()
    glTranslatef(2.5, 0.0, 0.0)
    glRotatef(45, 1.0, 0.0, 0.0)
    glRotatef(45, 0.0, 1.0, 0.0)
    glRotatef(45, 0.0, 0.0, 1.0)
    glCallList(CUBE)
    glFlush()

def make_sphere():
    quadObj = gluNewQuadric()
    slices = 16
    stacks = 10
    glNewList(SPHERE, GL_COMPILE)
    glColor3f(1.0, 0.0, 1.0)
    gluSphere(quadObj, 4.0, slices, stacks)
    glEndList()

def make_cube():
    glNewList(CUBE, GL_COMPILE)
    glColor3f(0.0, 1.0, 0.0)

    glBegin(GL_QUAD_STRIP)
    glNormal3d(0.0, 0.0, -1.0);
    glVertex3d(3, 3, -3)
   glVertex3d(3, -3, -3)
    glVertex3d(-3, 3, -3)
   glVertex3d(-3, -3, -3)
    glNormal3d(-1.0, 0.0, 0.0)
    glVertex3d(-3, 3, 3)
   glVertex3d(-3, -3, 3)
    glNormal3d(0.0, 0.0, 1.0)
    glVertex3d(3, 3, 3)
   glVertex3d(3, -3, 3)
    glNormal3d(1.0, 0.0, 0.0)
    glVertex3d(3, 3, -3)
    glVertex3d(3, -3, -3)
    glEnd()

    glColor3f(0.0, 0.0, 1.0)

    glBegin(GL_QUADS)
    glNormal3d(0.0, 1.0, 0.0)
    glVertex3d(-3, -3, -3)
    glVertex3d(3, -3, -3)
    glVertex3d(3, -3, 3)
    glVertex3d(-3, -3, 3)
    glNormal3d(0.0, 1.0, 0.0)
    glVertex3d(-3, 3, -3)
    glVertex3d(3, 3, -3)
    glVertex3d(3, 3, 3)
    glVertex3d(-3, 3, 3)
    glEnd()
    glEndList()

if __name__ == '__main__':
    specular = [1.0, 1.0, 1.0, 1.0]
    shininess = [100.0]
    position = [1.0, 1.0, 1.0, 0.0]
    glutInit(argv)
    glutCreateWindow('Knihovna PyOpengl(6)')
    glutReshapeWindow(500, 500)
    glutPositionWindow(0, 0)
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH)

    glClearColor(0.0, 0.0, 0.0, 0.0)
    glShadeModel(GL_SMOOTH)
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
    glEnable(GL_DEPTH_TEST)
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular)
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess)
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
    glEnable(GL_COLOR_MATERIAL)
    glLightfv(GL_LIGHT0, GL_POSITION, position)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)

    make_sphere()
    make_cube()

    glutReshapeFunc(reshape)
    glutDisplayFunc(draw)
    glutMainLoop() 

glNewList
glEndList
glCallList

void glNewList(GLuint list, GLenum mode);
glNewList(list, mode) -> None
void glEndList();
glEndList() -> None

void glCallList(GLuint list);
glCallList(list) -> None 

Funkce glNewList ukládá příkazy následující po volání do display-listu. Display-listy si můžeme představit jako makra, do kterých můžeme uložit několik příkazů knihovny a poté je i najednou spustit. Display-listy jsou většinou uloženy přímo v paměti akcelerátoru, takže rychlost jejich vykreslování bude pravděpodobně větší než v případě jednotlivých funkcí. Další výhodou může být členění kódu; podobně jako u klasických funkcí.

glNormal

void glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz);
void glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz);

void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
void glNormal3i(GLint nx, GLint ny, GLint nz);
void glNormal3s(GLshort nx, GLshort ny, GLshort nz);

glNormal3b(nx, ny, nz) -> None
glNormal3d(nx, ny, nz) -> None
glNormal3f(nx, ny, nz) -> None

glNormal3i(nx, ny, nz) -> None
glNormal3s(nx,ny, nz) -> None 

Funkce slouží k zadání normály o složkách (nx, ny, nz). Normála slouží k výpočtu osvětlení; jedná se o vektor, který je kolmý k povrchu v daném místě. Její výpočet je velmi jednoduchý, jedná se o vektorový součin dvou krajních hran. Předávaná normála by měla být jednotkový vektor. OpenGL umožňuje automatickou normalizaci normál, zapnete ji příkazem glEnable(GL_NORMALIZE), zatěžuje to však systém. Je možné, že se při modelovacích transformacích změní velikosti normál, je tedy nutné je znovu znormalizovat. Renormalizace se zapne pomocí  glEnable(GL_RESCALE_NORMAL).

glMaterial

void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
void glMaterialiv(GLenum face, GLenum pname, const GLint *params);
glMaterialfv(face, pname, params) -> None
glMaterialiv(face, pname, params) -> None 

Nastavuje způsob odrážení světla od materiálu (jednotlivých plošek). U materiálů existují tři složky:

  1. ambientní – GL_AMBIENT
  2. difůzní – GL_DIFFUSE
  3. zrcadlová – GL_SPECULAR

Definujeme jimi, jak se odráží odpovídající složky jednotlivých světelných zdrojů. Dále funkce umožňuje nastavit emisní složku ( GL_EMISSION), ta vyjadřuje vlastní vyzařování plošky, a určit ostrost odrazu zrcadlové plošky ( GL_SHININESS). Parametru face můžeme předat stranu plošek, kterou budeme nastavovat:

  • GL_FRONT  – přední strana
  • GL_BACK  – zadní strana
  • GL_FRONT_AND_BACK  – přední i zadní strana

value je číslo nebo seznam určující hodnotu parametru. Implicitní hodnoty jsou:

GL_AMBIENT = [0.2, 0.2, 0.2, 1.0]
GL_DIFFUSE = [0.8, 0.8, 0.8, 1.0]
GL_SPECULAR = [0.0, 0.0, 0.0, 1.0]
GL_SHININESS = 0.0
GL_EMISSION = [0.0, 0.0, 0.0, 1.0] 

glLight

void glLightfv(GLenum light, GLenum pname, const GLfloat *params);
void glLightiv(GLenum light, GLenum pname, const GLint *params);
glLightfv(light, pname, params) -> None
glLightiv(light, pname, params) -> None 

OpenGL umožňuje používat až osm nezávislých světelných zdrojů. Přičemž každý z těchto zdrojů se může chovat jako lokální (reflektor) nebo jako směrový (zdroj v nekonečnu s rovnoběžnými paprsky). Světlo zdroji produkované je složeno ze tří složek:

CS24_early

  1. ambientní ( GL_AMBIENT) – Nesměrové světlo, které je stejné ve všech místech scény (přichází ze všech směrů).
  2. difúzní ( GL_DIFFUSE) – Toto světlo se po dopadu rozptýlí do všech směrů.
  3. zrcadlová ( GL_SPECULAR) – Světlo se po dopadu odráží převážně do jednoho směru – zrcadlový obraz.

Povolení světel se provádí příkazem glEnable(GL_LIGHTING). Všechna světla jsou však implicitně vypnuta; jejich zapnutí provedete příkazem glEnable(light), kde light představuje GL_LIGHT0GL_LIGHT7. Směrový světelný zdroj je umístěn v nekonečnu a směr jeho paprsků určuje parametr GL_POSITION funkce glLight. Lokální zdroj je umístěn na pozici GL_POSITION, směr vyzařování je GL_SPOT_DIRECTION a úhel, pod kterým reflektor svítí, představuje GL_SPOT_CUTOFF. Funkcí glLight je možné dále nastavit koeficienty útlumu ( GL_*_ATTENUATION) a ambientní, difúzní a zrcadlové hodnoty.

Parametr light obsahuje jméno světelného zdroje(GL_LIG­HT0…), pname parametr světla a params jeho hodnoty.

GL_AMBIENT
Nastavení RGBA intenzity pro ambientní složku. (defaultně [0.0, 0.0, 0.0, 1.0])
GL_DIFFUSE
Nastavení intenzity difúzní složky. ([1.0, 1.0, 1.0, 1.0])
GL_SPECULAR
Nastavení intenzity zrcadlové složky. ([1.0, 1.0, 1.0, 1.0])
GL_POSITION
Nastavuje polohu světla (x, y, z, w). Pokud je w = 0.0, je světlo bráno jako směrové a ostatní hodnoty udávají směr ke zdroji. Jestliže je w = 1.0, jedná se o světlo lokální. ([0.0, 0.0, 1.0, 0.0])
GL_SPOT_DIRECTION
Směr, kterým svítí lokální světlo. ([0.0, 0.0, –1.0])
GL_SPOT_CUTTOFF
Úhel, pod kterým svítí reflektor. Přípustné hodnoty jsou 0 – 90 a 180 (jedná se o bodové světlo). (180)
GL_SPOT_EXPONENT
Udává změnu rozložení intenzity světelného kuželu – mocnina cosinu. (0)
GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION
Koeficienty útlumu světla v závislosti na vzdálenosti.

Byl pro vás článek přínosný?

Autor článku