számítógépes grafika gyakorlatok programtervező informatikus (nappali) a, c, t szakirányok
DESCRIPTION
Számítógépes Grafika gyakorlatok Programtervező Informatikus (Nappali) A, C, T szakirányok. OpenGL 2. gyakorlat Hapák József. Emlékeztető. Múlt órán a Windows-os alkalmazásokat tekintettük át Továbbá láttuk, hogy programjainak szüksége van Egy ablakra, amibe rajzolhatunk - PowerPoint PPT PresentationTRANSCRIPT
Számítógépes Grafika gyakorlatokProgramtervező Informatikus (Nappali)
A, C, T szakirányok
OpenGL2. gyakorlat
Hapák József
Emlékeztető
● Múlt órán a Windows-os alkalmazásokat tekintettük át
● Továbbá láttuk, hogy programjainak szüksége van● Egy ablakra, amibe rajzolhatunk● Egy ún. OpenGL context-re, amin keresztül
rajzolunk az ablakra● Illetve a kettő összekapcsolására, amit a WinAPI
segítségével végeztünk (más-más ablakozórendszereknél más-más API/függvényeken-n keresztül történik ez)
Most következik
● Mi a grafikus szerelőszalag/grafikus csővezeték/pipeline
● Geometria tárolása és kirajzolása● Shaderek használata
Grafikus szerelőszalag
Grafikus szerelőszalag
● Az alkalmazásaink célja a színterünk kirajzolása
● A kép előállítása során használt műveletek sorozatát hívjuk grafikus szerelőszalagnak (grafikus csővezeték, graphics pipeline)
● A színterünket benépesítő geometriai elemeket (ember, hajó stb.) egyszerű, elemi geometriai primitívekből építjük fel
● Részletesebben l. előadás
Grafikus szerelőszalag (OGL 2.x)
Vertex shader
Fragmentshader
Ope
nGL
4.x
pipe
line
(x<3
)
Grafikus primitívek
Grafikus primitívek - DEPRECATED
Vertex és pixel shader
Vertex shaderA vertex shader programunkban végezzük el a bejövő geometria csúcspontjainak transzformációjátglDrawArrays/glDrawElements hívásban hivatkozott csúcspontok lesznek a bemeneteiA vertex shader bemeneti változóihoz (in módosító) a hozzárendelést a programból csináljukA csúcspontbeli attribútumoknál ritkábban változó bemenetet uniform változókon keresztül adhatjuk át (uniform = a kirajzolás hívás idejére konstans)
Vertex shader
A bejövő csúcspont koordinátáit clip space-be ( -1 <= x,y,z <= 1) kell transzformálni és a beépített gl_Position változónak átadni – ezt a pipeline nem programozható részeinek is kellgl_Position = gl_MVPMatrix * bejövő_vertex_pos4
Ezen kívül azt csinálunk „amit akarunk” (minden out-tal megjelölt változónak adhatunk értéket és továbbküldhetjük a következő programozható fázisnak)
Vertex shader
A következő beépített kimeneti változók írhatóak a vertex shaderből:vec4 gl_Position: a transzformált homogén koordinátái a bejövő vertex-nek. Ebbe írnia kell a VS-nek.float gl_PointSize: a kirajzolandó pont mérete pixelben (point sprite-okhoz). Opcionális.vec4 gl_ClipVertex: felhasználói vágósíkokhoz. Opcionális.És ezeken kívül minden, amit mi is felveszünk...
Fragment shader vec4 gl_FragColor: a fragment színe, de ha nem írun bele viszont van kimeneti vec4, az lesz ez vec4 glFragData[gl_MaxDrawBuffers]: ha több color attachment-je van az aktív FBO-nak, akkor ezen keresztül írhatunk rájuk float gl_FragDepth: fragment mélységi értéke (ha módosítanánk, mint a raycasterben) vec4 gl_FragCoord: csak olvasható, a fragment homogén koordinátái (4. koord 1/w) bool gl_FrontFacing: előrefelé néz-e a fragment lapja
Vertex shader
#version 400in vec3 VertexPosition;in vec3 VertexColor;out vec3 Color;void main(){ Color = VertexColor; gl_Position = vec4(VertexPosition,1.0);
}
Fragment shader
#version 400
in vec3 Color;
out vec4 FragColor;
void main(){
FragColor = vec4(Color, 1.0);}
Program-shader megfeleltetések
Vertex attribútumok és a shader bemeneti változóinak összerendelés:glBindAttribLocation(
programHandle, // shader prog0, // index"VertexPosition"); // sh-s nev
glBindAttribLocation(programHandle, 1, "VertexColor");
Program-shader megfeleltetésekglGenVertexArrays( 1, &vaoHandle );
glBindVertexArray(vaoHandle);
glEnableVertexAttribArray(0); // Vertex position
glEnableVertexAttribArray(1); // Vertex color
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
Program-shader megfeleltetések
Lényegében tehát általános, indexekkel azonosított csatornákon keresztül megy az információátadásA csatornák száma a GL_MAX_VERTEX_ATTRIBS segítségével kérhetőek le
Layout
A shader oldalon is megcsinálhatjuk a bejövő csatornák „index-esítését”, és nem kell bind-olni az attrib location-öket:layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexColor;
Ezt a kimeneti változóknál is lehet használni:layout (location = 0) out vec4 FragColor;
Uniform változók
A shaderen belül read-only-k (konstansok), de kezdeti értéket kaphatnakuniform mat4 MVPTípusok:, n = 2,3,4mat<n>: n x n-es mátrixvec<n>: n dim vektor
Uniform változók
Először meg kell tudnunk az OpenGL-es azonosítóját a uniform változónak:GLuint mvpInShader = glGetUniformLocation(programHandle, "MVP");
Ezután már típusának megfelelő fv-vel értéket adhatunk neki:GlUniformMatrix4fv(mvpInShader, 1, GL_FALSE, &app_mvp[0][0]);Többiek: http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml
Uniform változók
Alaptípusok tömbjét is megjelölhetünk uniform-kéntEkkor pl. egy mátrixtömb konkrét indexen lévő mátrixának azonosítóját megkapjuk így:GLuint location = glGetUniformLocation( programHandle, "MyArray[1]" );
Uniform block
Több shader változó használhatja a program szempontjából ugyanazon uniform változókatEzeket mégis külön-külön kellene feltöltenünk stb., mert ugyanannak a uniform változónak más lesz a címe a különböző shader programokbanA uniform block segítségével ezen segíthetünk (csak használjunk shared layout-ot)
Uniform block – a shaderben
uniform BlobSettings{
vec4 InnerColor;vec4 OuterColor;float RadiusInner;float RadiusOuter;
};
Uniform block
A uniform változók adatait tartalmazó puffer objektum a uniform buffer objectA változókra hivatkozásnál elég az adattag nevét írni, nem kell prefixelni az UBO nevével (tehát pl. elég az InnerColor, nem kell BlobSettings.InnerColor)
Uniform block
GLuint blockIndex = glGetUniformBlockIndex(
programHandle, "BlobSettings");
GLint blockSize;
glGetActiveUniformBlockiv( programHandle, blockIndex,GL_UNIFORM_BLOCK_DATA_SIZE,
&blockSize);GLubyte * blockBuffer=
(GLubyte *)malloc(blockSize);
Uniform block
const GLchar *names[] = { "InnerColor", "OuterColor",
"RadiusInner", "RadiusOuter" };GLuint indices[4];glGetUniformIndices(
programHandle, 4, names, indices);
GLint offset[4];glGetActiveUniformsiv(
programHandle, 4, indices,GL_UNIFORM_OFFSET, offset);
Uniform block
GLfloat outerColor[] = {0.0f, 0.0f, 0.0f, 0.0f};GLfloat innerColor[] = {1.0f, 1.0f, 0.75f, 1.0f};
GLfloat innerRadius = 0.25f, outerRadius = 0.45f;
memcpy(blockBuffer + offset[0], innerColor, 4 *
sizeof(GLfloat));memcpy(blockBuffer + offset[1],
outerColor, 4 * sizeof(GLfloat));memcpy(blockBuffer + offset[2],
&innerRadius, sizeof(GLfloat));memcpy(blockBuffer + offset[3],
&outerRadius, sizeof(GLfloat));
Uniform block
GLuint uboHandle;glGenBuffers( 1, &uboHandle );glBindBuffer( GL_UNIFORM_BUFFER,
uboHandle );
glBufferData( GL_UNIFORM_BUFFER, blockSize,blockBuffer, GL_DYNAMIC_DRAW );
glBindBufferBase( GL_UNIFORM_BUFFER, blockIndex, uboHandle );
Fragment shader
#version 400in vec3 Color;out vec4 FragColor;void main(){
FragColor = vec4(Color, 1.0);}