Uživatelské nástroje

Nástroje pro tento web


pitel:pgr:cviceni:1

Cvičení 1

farm2.static.flickr.com_1230_5107287064_a08997d078_m.jpg

  • Pod domkem vykreslit trávník
  • V otevřených stěnách domku vykreslit okna – poloprůhledná, přes půl stěny
  • Kód vertex shaderu upravit tak, aby transformoval vrcholy jedním násobením maticí
  • Pozor na pořadí vykreslování průhledných objektů (správné pořadí, nebo bez zápisu do z-bufferu)
lab_01_task.cpp
#include "pgr.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 color[4];
    float position[3];	//LR TD FB
} const houseVertices[] = {
    // Walls
    { { 0.0, 0.0, 1.0 }, { -5.0, -5.0, -5.0 } },
    { { 0.0, 1.0, 0.0 }, { -5.0, -5.0,  5.0 } },
    { { 0.0, 1.0, 1.0 }, {  5.0, -5.0,  5.0 } },
    { { 1.0, 0.0, 0.0 }, {  5.0, -5.0, -5.0 } },
 
    { { 1.0, 0.0, 1.0 }, { -5.0,  5.0, -5.0 } },
    { { 1.0, 1.0, 0.0 }, { -5.0,  5.0,  5.0 } },
    { { 1.0, 1.0, 1.0 }, {  5.0,  5.0,  5.0 } },
    { { 0.0, 0.0, 1.0 }, {  5.0,  5.0, -5.0 } },
 
    { { 0.0, 1.0, 0.0 }, { -5.0, -5.0, -5.0 } },
    { { 0.0, 1.0, 1.0 }, { -5.0, -5.0,  5.0 } },
    { { 1.0, 0.0, 0.0 }, { -5.0,  5.0,  5.0 } },
    { { 1.0, 0.0, 1.0 }, { -5.0,  5.0, -5.0 } },
 
    { { 0.0, 1.0, 0.0 }, {  5.0, -5.0, -5.0 } },
    { { 0.0, 1.0, 1.0 }, {  5.0, -5.0,  5.0 } },
    { { 1.0, 0.0, 0.0 }, {  5.0,  5.0,  5.0 } },
    { { 1.0, 0.0, 1.0 }, {  5.0,  5.0, -5.0 } },
    // Roof
    { { 0.0, 0.0, 1.0 }, { -5.0,  5.0, -5.0 } },
    { { 0.0, 1.0, 1.0 }, {  5.0,  5.0, -5.0 } },
    { { 1.0, 1.0, 1.0 }, {  0.0, 11.0,  0.0 } }, 
 
    { { 1.0, 0.0, 0.0 }, {  5.0,  5.0, -5.0 } },
    { { 1.0, 1.0, 0.0 }, {  5.0,  5.0,  5.0 } },
    { { 1.0, 1.0, 1.0 }, {  0.0, 11.0,  0.0 } },
 
    { { 0.0, 1.0, 0.0 }, {  5.0,  5.0,  5.0 } },
    { { 0.0, 1.0, 1.0 }, { -5.0,  5.0,  5.0 } },
    { { 1.0, 1.0, 1.0 }, {  0.0, 11.0,  0.0 } },
 
    { { 0.0, 1.0, 0.0 }, { -5.0,  5.0,  5.0 } },
    { { 1.0, 1.0, 0.0 }, { -5.0,  5.0, -5.0 } },
    { { 1.0, 1.0, 1.0 }, {  0.0, 11.0,  0.0 } },
 
	// Grass
	{{0, 0.8, 0}, {-50, -5.01, -50}},
	{{0, 0.8, 0}, {-50, -5.01,  50}},
	{{0, 0.8, 0}, { 50, -5.01,  50}},
	{{0, 0.8, 0}, { 50, -5.01, -50}}
};
 
// 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,
//Grass
    28, 29, 30,
    28, 30, 31
};
 
const Point windowsVertices[] = {
	{{0, 0, 1, 0.5}, {-5,  5,  5}},
	{{0, 0, 1, 0.5}, { 0,  5,  5}},
	{{0, 0, 1, 0.5}, { 0, -5,  5}},
	{{0, 0, 1, 0.5}, {-5, -5,  5}},
	{{1, 0, 0, 0.5}, {-5,  5, -5}},
	{{1, 0, 0, 0.5}, { 0,  5, -5}},
	{{1, 0, 0, 0.5}, { 0, -5, -5}},
	{{1, 0, 0, 0.5}, {-5, -5, -5}}
};
 
const unsigned char quad[] = {0, 1, 2, 3, 4, 5, 6, 7};
 
GLuint VBO, EBO, winVBO, quadEBO;
 
int width, height;
float rx = 0.0f, ry = 0.0f, pz = -70.0f, wheel = 1.0f;
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Shaders
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
GLuint VS, FS, Prog;
 
GLuint positionAttrib, colorAttrib, mvpUniform;
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Event handlers
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
void onInit()
{
    // Shader
    VS = CompileShader(GL_VERTEX_SHADER, loadFile("lab01_task.vs").c_str());
    FS = CompileShader(GL_FRAGMENT_SHADER, loadFile("lab01_task.fs").c_str());
    Prog = LinkShader(2, VS, FS);
 
    positionAttrib = glGetAttribLocation(Prog, "position");
    colorAttrib = glGetAttribLocation(Prog, "color");
    mvpUniform = glGetUniformLocation(Prog, "mvp");
 
    // Copy house to graphics card
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(houseVertices), houseVertices, GL_STATIC_DRAW);
 
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(house), house, GL_STATIC_DRAW);
 
    // Copy windows to graphic card
    glGenBuffers(1, &winVBO);
    glBindBuffer(GL_ARRAY_BUFFER, winVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(windowsVertices), windowsVertices, GL_STATIC_DRAW);
 
    glGenBuffers(1, &quadEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
}
 
void onWindowRedraw()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    glEnable(GL_DEPTH_TEST);
 
    glUseProgram(Prog);
 
	//MVP
	float aspect = (float)width / (float)height;
	glm::mat4 mvp = glm::rotate(
		glm::rotate(
			glm::translate(
				glm::perspective(10.0f * wheel, aspect, 1.0f, 1000.0f),
				glm::vec3(0, 0, pz)
			),
			ry,
			glm::vec3(1, 0, 0)
		),
		rx,
		glm::vec3(0, 1, 0)
	);
	glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, glm::value_ptr(mvp));
 
    glEnableVertexAttribArray(positionAttrib);
    glEnableVertexAttribArray(colorAttrib);
 
 
 
    //Vykresleni domu
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)offsetof(Point, position));
    glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)offsetof(Point, color));
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glDrawElements(GL_TRIANGLES, sizeof(house)/sizeof(*house), GL_UNSIGNED_BYTE, NULL);
 
	//Vykresleni oken
	glDepthMask(GL_FALSE);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadEBO);
	glBindBuffer(GL_ARRAY_BUFFER, winVBO);
	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)offsetof(Point, position));
	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)offsetof(Point, color));
	glDrawElements(GL_QUADS, sizeof(quad)/sizeof(*quad), GL_UNSIGNED_BYTE, NULL);
	glDisable(GL_BLEND);
	glDepthMask(GL_TRUE);
 
    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*/)
{
    switch(button) {
        case SDL_BUTTON_WHEELUP : wheel += 1; break;
        case SDL_BUTTON_WHEELDOWN : wheel -= 1; break;
        default : return;
    };
    redraw();
}
 
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;
}
lab_01_task.vs
#version 130
 
in vec3 position;
in vec4 color;
 
uniform mat4 mvp;
 
out vec4 c;
 
void main() {
	gl_Position = mvp * vec4(position, 1);
	c = color;
}
/var/www/wiki/data/pages/pitel/pgr/cviceni/1.txt · Poslední úprava: 30. 12. 2022, 13.43:01 autor: 127.0.0.1