Laboration 0

Introduktion/repetition till OpenGL 3.2 och högre med shaders + introduktion för Simpler Vulkan v2

Denna laboration är ett koncentrat av en del av våra grundkurslabbar. Vi startar lite längre in, ni får en del givet att starta med så vi kommer till saken.

Om du inte har gått TSBK07 i våras är Labb 0 obligatorisk! Låt oss hjälpa dig igång!

Om du gick TSBK07 och använder Vulkan så vill du testa version 2.

Uppgifterna är flexibla; Om du känner att du behöver öva på något annat så kan vi diskutera saken.

Har du inte använt OpenGL 3.2+ förr så är det viktigt att du övar på att styra transformering och shading med input från huvudprogrammet.

Är du ovan vid shaders så bör du öva speciellt på dessa.

0. Kom igång

Ladda ner labbskalet här (testat på Linux och Mac):

lab0.zip (C++-version. Det fanns en C-version men numera uppdateras enbart denna.)

common.zip (Alla hjälpfiler.)

Vulkan-version (ny 2026!)

lab0.zip

common.zip (Alla hjälpfiler - Vulkan-version. Nuvarande version - mer ändringar kommer.)


Kompilera med make (makefil enbart för Linux). Kör med ./lab0.

Hur gör man för att placera ett objekt där man vill i en scen? Hur flyttar du kaninen 0.1 åt höger?

Ljussättningen är "fusk", tar bara normalvektorns z-komponent, vilket kopieras till "shade" i vertex-shaders). Vad händer om du inte tar normalens z till alla komponenter? Testa med x och y!

Är detta en Phong-shader eller Gouraud-shader?

Notera att ett antal externa hjälpmoduler ingår:

För OpenGL:

GL_utilities: Shaderladdare och FBO-byggare.

LittleOBJLoader: Laddare av OBJ-filer. Klarar de flesta enligt mina tester.

VectorUtils4: Vektor- och matrisoperationer.

LoadTGA: Texturladdare för TGA-filer.

MicroGlut: Enfils fönster- och eventhanterare, baserad på delar av GLUT-APIet, för Linux, Mac samt Windows.

För Vulkan: Simpler Vulkan v2.

Det finns många större bibliotek för dessa problem. Dessa är dock just stora och svåröverskådliga. Målet med detta labbmaterial är att hålla det överskådligt, transparent, och lättmodifierat. För Vulkan är det betydligt mer kod så där är snarast målet att ge er ett förenklat gränssnitt, men även här så öppet som möjligt.

Nytt för 2024: C-versionerna fasas ut. Enbart C++-versionerna uppdateras.

Nytt för 2026: Vulkan tillkommer som alternativ. Dokumentation:

https://www.computer-graphics.se/TSBK03/files/labb26vulkan/SimplerVulkan%20v2%20documentation.pdf

För Mac- och Windows-användare: Se här.

1. Modifiera position, rotation, kamera

Labbfilen definierar tre matriser (projectionMatrix, viewMatrix, objectExampleMatrix), multiplicerar ihop två av dem och laddar upp till två matriser i shadern, kallas där projectionMatrix och viewMatrix (men namnen måste inte matcha mellan shader och huvudprogram).

Ändra lämplig matris för att få kaninen att snurra. Om du gör detta tidsberoende får du en enkel animation.

Trevlig övning om du är ovan vid shaders: Gör en shader som deformerar objektet, t.ex. får den att slingra som en orm. Gör en procedurell textur i fragment shadern, t.ex. i stil med Ingemar's Psychedelic Teapot. (OBS att du behöver tiden som "uniform" för att slingra som animation, se nedan.)

Vulkan: Varning för tiden: Om du levererar tiden som uniform kan du få alignmentproblem. Lägg den sist i uniforms eller använd push constants.

2. Varde ljus

Från början har vi fuskljus. Lägg till ljuskällor. En eller flera, diffusa eller spekulära.

Enkelt: Diffus belysning. Helst Phong.

Svårare: Tag med spekulärkomponenten, dvs hela tre-komponents Phongmodellen.

Svårast: Gör flera ljuskällor, med olika egenskaper, färger, positioner, vissa positionsljus och vissa riktningsljus (oändligt avstånd).

Vulkan: Risk för alignmentproblem igen. Om du lägger ljuskällor i uniforms, använd vec4.

3. Bygg en scen

Gör flera objekt i scenen. Bara att ha två objekt är intressant nog. Placera objekten på ett markplan för att ge en referensram.

Svårare: Ha flera olika shaders för olika delar av scenen.

Animera ett objekt. För att göra detta behöver du tiden, som du får med

GLfloat t = (GLfloat)glutGet(GLUT_ELAPSED_TIME);

4. Texturer

Lägg till en textur till modellen! (Detta är tämligen oförändrat mot hur det fungerar i OpenGL 2.)

I huvudprogrammet måste då texturens bindas till en texturenhet, och texturenhetens nummer meddelas till shadern. Dessutom måste texturkoordinater finnas tillgängliga, och interpoleras från vertex till fragment shader (eller genereras från geometrin).

I huvudprogrammet:

glUniform1i(glGetUniformLocation(program,"exampletexture"),0);//the last argument has to be the same as the texture-unit that is to be used

glActiveTexture(GL_TEXTURE0);//which texture-unit is active

glBindTexture(GL_TEXTURE_2D, texture);//load the texture to active texture-unit

vertex shader:

out vec2 frag_texcoord;

frag_texcoord=in_TexCoord;

fragment shader:

in vec2 frag_texcoord;

uniform sampler2D exampletexture;

out_Color=texture(exampletexture,frag_texcoord);

Blev modellen texturerad? Om inte, varför? Blev den svart eller enfärgad?

Vulkan: Här fungerar texturer lite annorlunda. Texturenheter är numera dolda. (Jag tänker skriva lite mer här. Dokumentation är på gång.)

Vid oklarheter, fråga oss!

Efter dessa övningar hoppas vi att ni känner er bekväma nog med OpenGL 3.2+ och GLSL så de inte är något problem i följande laborationer!

Denna sida underhålls av Ingemar Ragnemalm.