Uživatelské nástroje

Nástroje pro tento web


pitel:pgr:cviceni:2

Cvičení 2

lab02_task

  • Načíst lightmapu ze souboru lightmap.bmp
  • Natáhnout ji na domek a ve FS zkombinovat s kachličkovou texturou
  • Upravujte pouze věci týkající se domečku. Do vykreslování koulí a příslušných shaderů nemusíte nijak zasahovat.
lab02_task.cpp
#include "pgr.h"
 
#include "sphere.h"
 
#include <glm/glm.hpp>
#include <glm/gtc/matrix_projection.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
 
using namespace std;
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Data
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
struct Point {
    float texcoord[2];
	float lightcoord[2];
    float position[3];
} const houseVertices[] = {
    // Walls
    { { 0.0, 0.0 }, {.25, 1}, { -5.0, -5.0, -5.0 } },	//Podlaha
    { { 0.0, 4.0 }, {.25, 0}, { -5.0, -5.0,  5.0 } },
    { { 4.0, 4.0 }, {.5, 0}, {  5.0, -5.0,  5.0 } },
    { { 4.0, 0.0 }, {.5, 1}, {  5.0, -5.0, -5.0 } },
 
    { { 0.0, 0.0 }, {.75, 1}, { -5.0,  5.0, -5.0 } },	//Strop
    { { 0.0, 2.0 }, {.75, 0}, { -5.0,  5.0,  5.0 } },
    { { 2.0, 2.0 }, {1, 0}, {  5.0,  5.0,  5.0 } },
    { { 2.0, 0.0 }, {1, 1}, {  5.0,  5.0, -5.0 } },
 
    { { 0.0, 0.0 }, {0, 1}, { -5.0, -5.0, -5.0 } },	//Leva zed
    { { 0.0, 1.0 }, {0, 0}, { -5.0, -5.0,  5.0 } },
    { { 1.0, 1.0 }, {.25, 0}, { -5.0,  5.0,  5.0 } },
    { { 1.0, 0.0 }, {.25, 1}, { -5.0,  5.0, -5.0 } },
 
    { { 0.0, 0.0 }, {.5, 1}, {  5.0, -5.0, -5.0 } },	//Prava zed
    { { 0.0, 1.0 }, {.5, 0}, {  5.0, -5.0,  5.0 } },
    { { 1.0, 1.0 }, {.75, 0}, {  5.0,  5.0,  5.0 } },
    { { 1.0, 0.0 }, {.75, 1}, {  5.0,  5.0, -5.0 } },
    // Roof
    { { 0.0, 0.0 }, {}, { -5.0,  5.0, -5.0 } },
    { { 1.0, 0.0 }, {}, {  5.0,  5.0, -5.0 } },
    { { 0.0, 1.0 }, {}, {  0.0, 11.0,  0.0 } }, 
 
    { { 0.0, 0.0 }, {}, {  5.0,  5.0, -5.0 } },
    { { 1.0, 0.0 }, {}, {  5.0,  5.0,  5.0 } },
    { { 0.0, 1.0 }, {}, {  0.0, 11.0,  0.0 } },
 
    { { 0.0, 0.0 }, {}, {  5.0,  5.0,  5.0 } },
    { { 0.0, 1.0 }, {}, { -5.0,  5.0,  5.0 } },
    { { 1.0, 1.0 }, {}, {  0.0, 11.0,  0.0 } },
 
    { { 0.0, 1.0 }, {}, { -5.0,  5.0,  5.0 } },
    { { 0.0, 0.0 }, {}, { -5.0,  5.0, -5.0 } },
    { { 1.0, 1.0 }, {}, {  0.0, 11.0,  0.0 } }
};
 
// House indices
const unsigned char house[] = {
//Walls
     0,  1,  2,
     0,  2,  3,
     4,  5,  6,
     4,  6,  7,
     8,  9, 10,
     8, 10, 11,
    12, 13, 14,
    12, 14, 15,
//Roof
    16, 17, 18,
    19, 20, 21,
    22, 23, 24,
    25, 26, 27
};
 
const float lightquad[][3] = {
    { -2.2, 4.97, -0.6},
    {-2.2, 4.97,  0.6},
    { 2.2, 4.97,  0.6},
    { 2.2, 4.97, -0.6}
};
 
GLuint HouseVBO, HouseEBO;
 
GLuint SphereVBO, SphereEBO;
 
GLuint lightquadVBO;
 
GLuint textures[2];
 
int width, height;
float rx = 0.0f, ry = 0.0f, pz = -70.0f;
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Shaders
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
const char * HVSSource
    = "#version 130\n in vec3 position; in vec2 tc; in vec2 ltc; uniform mat4 mvp; out vec2 coord; out vec2 lightcoord; void main() { gl_Position = mvp*vec4(position,1); coord = tc; lightcoord = ltc; }";
const char * HFSSource
    = "#version 130\n in vec2 coord; in vec2 lightcoord; uniform sampler2D tex; uniform sampler2D lmap; out vec4 gl_FragColor; void main() { vec4 tiles = texture2D(tex, coord); vec4 light = texture2D(lmap, lightcoord); gl_FragColor = tiles * light; }";
 
GLuint HVS, HFS, HProg;
 
GLuint HpositionAttrib, HtcAttrib, HLtcAttrib, HmvpUniform;
GLuint HtextureUniform, LtextureUniform;
 
const char * SVSSource
    = "#version 130\n in vec3 position; in vec3 normal; uniform mat4 mvp; uniform vec3 lightvec; out float color; void main() { gl_Position = mvp*vec4(position,1); color = 0.3 + 0.7*max(0, dot(normal, lightvec)); }";
const char * SFSSource
    = "#version 130\n in float color; out vec4 gl_FragColor; void main() { gl_FragColor = vec4(color); }";
 
GLuint SVS, SFS, SProg;
 
GLuint SpositionAttrib, SnormalAttrib, SmvpUniform, SlightvecUniform;
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Event handlers
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
void onInit()
{
    // Shaders
    HVS = CompileShader(GL_VERTEX_SHADER, HVSSource);
    HFS = CompileShader(GL_FRAGMENT_SHADER, HFSSource);
    HProg = LinkShader(2, HVS, HFS);
 
    HpositionAttrib = glGetAttribLocation(HProg, "position");
    HtcAttrib = glGetAttribLocation(HProg, "tc");
    HLtcAttrib = glGetAttribLocation(HProg, "ltc");
    HmvpUniform = glGetUniformLocation(HProg, "mvp");
 
    HtextureUniform = glGetUniformLocation(HProg, "tex");
	LtextureUniform = glGetUniformLocation(HProg, "lmap");
 
    SVS = CompileShader(GL_VERTEX_SHADER, SVSSource);
    SFS = CompileShader(GL_FRAGMENT_SHADER, SFSSource);
    SProg = LinkShader(2, SVS, SFS);
 
    SpositionAttrib = glGetAttribLocation(SProg, "position");
    SnormalAttrib = glGetAttribLocation(SProg, "normal");
    SmvpUniform = glGetUniformLocation(SProg, "mvp");
    SlightvecUniform = glGetUniformLocation(SProg, "lightvec");
 
    // Copy house to graphics card
    glGenBuffers(1, &HouseVBO);
    glBindBuffer(GL_ARRAY_BUFFER, HouseVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(houseVertices), houseVertices, GL_STATIC_DRAW);
 
    glGenBuffers(1, &HouseEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HouseEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(house), house, GL_STATIC_DRAW);
 
    // Copy sphere to graphics card
    glGenBuffers(1, &SphereVBO);
    glBindBuffer(GL_ARRAY_BUFFER, SphereVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(sphereVertices), sphereVertices, GL_STATIC_DRAW);
 
    glGenBuffers(1, &SphereEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SphereEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sphere), sphere, GL_STATIC_DRAW);
 
    // Light quad
    glGenBuffers(1, &lightquadVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lightquadVBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(lightquad), lightquad, GL_STATIC_DRAW);
 
    //Load texture from file
    SDL_Surface * surface = SDL_LoadBMP("tiles.bmp");
    SDL_Surface * lightmap = SDL_LoadBMP("lightmap.bmp");
    if(surface == NULL || lightmap == NULL) throw SDL_Exception();
 
    glGenTextures(2, &textures[0]);
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    SurfaceImage2D(GL_TEXTURE_2D, 0, GL_RGB, surface);
    glGenerateMipmap(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, textures[1]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	SurfaceImage2D(GL_TEXTURE_2D, 0, GL_RGB, lightmap);
	glGenerateMipmap(GL_TEXTURE_2D);
}
 
void onWindowRedraw()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
 
    //ModelViewProjection
    glm::mat4 mvp = glm::rotate(
            glm::rotate(
                glm::translate(
                    glm::perspective(45.0f, (float)width/(float)height, 1.0f, 1000.0f),
                    glm::vec3(0, 0, pz)
                    ),
                ry, glm::vec3(1, 0, 0)
                ),
            rx, glm::vec3(0, 1, 0)
            );
 
    //Draw house
 
    glUseProgram(HProg);
 
    glUniformMatrix4fv(HmvpUniform, 1, GL_FALSE, glm::value_ptr(mvp));
 
    // Texture 0
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glUniform1i(HtextureUniform, 0);
 
	// Lightmap
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, textures[1]);
	glUniform1i(LtextureUniform, 1);
 
    glEnableVertexAttribArray(HpositionAttrib);
    glEnableVertexAttribArray(HtcAttrib);
	glEnableVertexAttribArray(HLtcAttrib);
 
    glBindBuffer(GL_ARRAY_BUFFER, HouseVBO);
    glVertexAttribPointer(HpositionAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)offsetof(Point, position));
    glVertexAttribPointer(HtcAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)offsetof(Point, texcoord));
	glVertexAttribPointer(HLtcAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)offsetof(Point, lightcoord));
 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HouseEBO);
    glDrawElements(GL_TRIANGLES, sizeof(house)/sizeof(*house), GL_UNSIGNED_BYTE, NULL);
 
    glDisableVertexAttribArray(HpositionAttrib);
    glDisableVertexAttribArray(HtcAttrib);
	glDisableVertexAttribArray(HLtcAttrib);
 
    //Draw "light"
 
    glUseProgram(SProg);
    glEnableVertexAttribArray(SpositionAttrib);
 
    glVertexAttrib3f(SnormalAttrib, 1, 0, 0);
    glUniform3f(SlightvecUniform, 1, 0, 0);
    glUniformMatrix4fv(SmvpUniform, 1, GL_FALSE, glm::value_ptr(mvp));
 
    glBindBuffer(GL_ARRAY_BUFFER, lightquadVBO);
    glVertexAttribPointer(SpositionAttrib, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
    // Draw spheres
 
    glEnableVertexAttribArray(SnormalAttrib);
 
    glBindBuffer(GL_ARRAY_BUFFER, SphereVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SphereEBO);
    glVertexAttribPointer(SpositionAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(SphereVertex), (void*)offsetof(SphereVertex, position));
    glVertexAttribPointer(SnormalAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(SphereVertex), (void*)offsetof(SphereVertex, normal));
 
    // Sphere 1
    glUniformMatrix4fv(SmvpUniform, 1, GL_FALSE, glm::value_ptr(glm::scale(glm::translate(mvp, glm::vec3(-2.1, -0.9, 0.9)), glm::vec3(1.8))));
    glUniform3fv(SlightvecUniform, 1, glm::value_ptr(glm::normalize(glm::vec3(0.0f, 5.0f, 0.0f) - glm::vec3(-2.1, -0.9, 0.9))));
    glDrawElements(GL_TRIANGLES, sizeof(sphere)/sizeof(**sphere), sphereIndexType, NULL);
 
    // Sphere 2
    glUniformMatrix4fv(SmvpUniform, 1, GL_FALSE, glm::value_ptr(glm::translate(mvp, glm::vec3(1.8, 2.3, -0.5))));
    glUniform3fv(SlightvecUniform, 1, glm::value_ptr(glm::normalize(glm::vec3(0.0f, 5.0f, 0.0f) - glm::vec3(1.8, 2.3, -0.5))));
    glDrawElements(GL_TRIANGLES, sizeof(sphere)/sizeof(**sphere), sphereIndexType, NULL);
 
    glDisableVertexAttribArray(SnormalAttrib);
    glDisableVertexAttribArray(SpositionAttrib);
 
    SDL_GL_SwapBuffers();
}
 
void onWindowResized(int w, int h)
{
    glViewport(0, 0, w, h);
    width = w; height = h;
}
 
void onKeyDown(SDLKey key, Uint16 /*mod*/)
{
    switch(key) {
        case SDLK_ESCAPE : quit(); return;
        default : return;
    }
}
 
void onKeyUp(SDLKey /*key*/, Uint16 /*mod*/)
{
}
 
void onMouseMove(unsigned /*x*/, unsigned /*y*/, int xrel, int yrel, Uint8 buttons)
{
    if(buttons & SDL_BUTTON_LMASK)
    {
        rx += xrel;
        ry += yrel;
        redraw();
    }
    if(buttons & SDL_BUTTON_RMASK)
    {
        pz += yrel;
        redraw();
    }
}
 
void onMouseDown(Uint8 /*button*/, unsigned /*x*/, unsigned /*y*/)
{
}
 
void onMouseUp(Uint8 /*button*/, unsigned /*x*/, unsigned /*y*/)
{
}
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Main
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
int main(int /*argc*/, char ** /*argv*/)
{
    try {
        // Init SDL - only video subsystem will be used
        if(SDL_Init(SDL_INIT_VIDEO) < 0) throw SDL_Exception();
 
        // Shutdown SDL when program ends
        atexit(SDL_Quit);
 
        init(800, 600, 24, 16, 0);
 
        mainLoop();
 
    } catch(exception & ex) {
        cout << "ERROR : " << ex.what() << endl;
        return EXIT_FAILURE;
    }
 
    return EXIT_SUCCESS;
}
/var/www/wiki/data/pages/pitel/pgr/cviceni/2.txt · Poslední úprava: 30. 12. 2022, 13.43:01 autor: 127.0.0.1