În acest laborator vom recapitula cunoștințe de anul trecut de la EGC, aceste informații sunt esențiale pentru laboratoarele de SPG.
Tot conținutul laboratoarelor EGC se poate găsi în Laboratorul 00.
Acest laborator va utiliza framework-ul de la EGC cu mici imbunatatiri si noi functionalitati pentru usurarea implementarii noilor tehnici avansate ce vor fi invatate.
Acesta se găsește pe Github
Puteți să descărcați direct arhiva accesând acest link
Pentru implementarea de programe SHADER in OpenGL se foloseste limbajul dedicat GLSL (GL Shading Language).
Legarea unui shader la programul care foloseste OpenGL este o operatie complicata, de aceea va este oferit codul prin care se incarca un shader.
Un GEOMETRY SHADER e un program care se executa pentru FIECARE primitiva trimisa catre banda grafica. Pe scurt, acest shader primeste ca intrare primitive grafice (puncte, linii si triunghiuri) si ofera ca iesire tot primitive grafice. In banda grafica, asa cum se poate vedea in imaginea de mai sus, se afla intre Vertex Shader si Fragment Shader. Mai exact, iesirea de la vertex shader devine intrare pentru geometry shader si iesirea de la acesta devine intrare pentru fragment shader (dupa alti cativa pasi ficsi).
In continuare vom analiza un geometry shader simplu pentru a vedea sintaxa:
#version 330 layout(location = 0) in vec3 v_position; layout(location = 1) in vec3 v_texcoord; uniform mat4 Model; uniform mat4 View; uniform mat4 Projection; out vert_texcoord; void main() { gl_Position = Projection * View * Model * vec4(v_position, 1.0); vert_texcoord = v_texcoord; }
#version 330 layout(triangles) in; layout(triangle_strip, max_vertices = 3) out; layout(location = 0) in vec2 vert_texcoord[]; layout(location = 0) out vec2 geom_texcoord; void main() { gl_Position = gl_in[0].gl_Position; geom_texcoord = vert_texcoord[0]; EmitVertex(); gl_Position = gl_in[1].gl_Position; geom_texcoord = vert_texcoord[1]; EmitVertex(); gl_Position = gl_in[2].gl_Position; geom_texcoord = vert_texcoord[2]; EmitVertex(); EndPrimitive(); }
layout(triangles) in;
Trebuie sa fie unul din: points
, lines
, lines_adjacency
, triangles
, triangles_adjacency
layout(triangle_strip, max_vertices = 3) out;
Trebuie sa fie unul din: points
, line_strip
, triangle_strip
layout(location = 0) in vec2 vert_texcoord[];
De asemenea exista si intrare implicita, dar cea care ne intereseaza este:
in gl_PerVertex { vec4 gl_Position; ... } gl_in[];
layout(location = 0) out vec2 geom_texcoord;
Pentru fiecare vertex care compune primitiva noastra, trebuie sa setam valorile de output pentru vertexul modificat si apoi sa utilizam directiva EmitVertex()
.
gl_Position = gl_in[0].gl_Position; geom_texcoord = vert_texcoord[0]; EmitVertex();
Tasta F5 - reincarca shaderele in timpul rularii aplicatiei. Nu este nevoie sa opriti aplicatia intrucat shaderele sunt compilate si rulate de catre procesorul grafic si nu au legatura cu codul sursa C++ propriu zis.