Skip to content

Instantly share code, notes, and snippets.

@saucecode
Created June 26, 2018 10:44
Show Gist options
  • Save saucecode/45d660a6a5d53216578ab0d1fe4e34ea to your computer and use it in GitHub Desktop.
Save saucecode/45d660a6a5d53216578ab0d1fe4e34ea to your computer and use it in GitHub Desktop.
attempt at porting mattdesl's 2d pixel perfect shadows
#include "Game.hpp"
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Shader.hpp"
#include "Geometry.hpp"
Game::Game(GLFWwindow *window) : window{window} {
glfwGetWindowSize(window, &windowWidth, &windowHeight);
light.x = 0.0f;
light.y = 100.0f;
light.size = 256;
prepareResources();
}
Game::~Game(){
}
void Game::prepareResources() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
shader = new Shader("shaders/simple.vert", "shaders/simple.frag");
shadowShader = new Shader("shaders/simple.vert", "shaders/shadow.frag");
shadowRenderShader = new Shader("shaders/simple.vert", "shaders/shadowRender.frag");
shader->prepareShader();
shadowRenderShader->prepareShader();
shadowShader->prepareShader();
float vertices[] = {
0,0,0, 0,0,
80,0,0, 0,1,
80,80,0, 1,1
};
float square[] = {
0,0,0, 0,0,
1,0,0, 1,0,
1,1,0, 1,1,
0,0,0, 0,0,
1,1,0, 1,1,
0,1,0, 0,1
};
geometry = new Geometry(&vertices[0], sizeof(vertices), 3, GL_TRIANGLES);
unitSquare = new Geometry(&square[0], sizeof(square), 6, GL_TRIANGLES);
view = glm::lookAt(glm::vec3(0,0,5), glm::vec3(0,0,0), glm::vec3(0,1,0));
projection = glm::ortho(-windowWidth/2.0f, windowWidth/2.0f, -windowHeight/2.0f, windowHeight/2.0f, 0.1f, 100.0f);
// OCCLUDERS
// create & bind fbo
glGenFramebuffers(1, &occlusionFbo);
glBindFramebuffer(GL_FRAMEBUFFER, occlusionFbo);
// attach a texture
glGenTextures(1, &occlusionTexture);
glBindTexture(GL_TEXTURE_2D, occlusionTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, light.size, light.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, occlusionTexture, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
std::cout << "Fraembuffer is complete\n";
else
std::cout << "Fraembuffer is NOT complete\n";
// SHADOWMAP
// create & bind fbo
glGenFramebuffers(1, &shadowFbo);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFbo);
// attach a texture
glGenTextures(1, &shadowTexture);
glBindTexture(GL_TEXTURE_1D, shadowTexture);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, light.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glFramebufferTexture1D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_1D, shadowTexture, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
std::cout << "Fraembuffer is complete\n";
else
std::cout << "Fraembuffer is NOT complete\n";
glBindFramebuffer(GL_FRAMEBUFFER, 0);
shader->useProgram();
}
void Game::tick(float dt) {
// generate occlusion map
glBindFramebuffer(GL_FRAMEBUFFER, occlusionFbo);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader->useProgram();
shader->setVec3("color", glm::vec3(0,0,0));
shader->setMat4("model", glm::mat4(1));
shader->setMat4("view", view);
shader->setMat4("projection", glm::ortho(light.x - light.size/2, light.x + light.size/2, light.y - light.size/2, light.y + light.size/2));
glBindVertexArray(geometry->VAO);
glDrawArrays(geometry->type, 0, geometry->vertexCount);
// generate shadow map
glBindFramebuffer(GL_FRAMEBUFFER, shadowFbo);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shadowShader->useProgram();
shadowShader->setVec2("resolution", light.size, light.size);
shadowShader->setInt("u_texture", 0);
shadowShader->setVec3("color", glm::vec3(0,0,0));
shadowShader->setMat4("model", glm::scale(glm::mat4(1), glm::vec3(light.size, 1, 0)));
shadowShader->setMat4("view", view);
shadowShader->setMat4("projection", glm::ortho(light.x - light.size/2, light.x + light.size/2, light.y - light.size/2, light.y + light.size/2));
glBindTexture(GL_TEXTURE_2D, occlusionTexture);
glBindVertexArray(unitSquare->VAO);
glDrawArrays(unitSquare->type, 0, unitSquare->vertexCount);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// draw shadows
shadowRenderShader->useProgram();
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shadowRenderShader->setVec2("resolution", light.size, light.size);
shadowRenderShader->setInt("u_texture", 0);
shadowRenderShader->setVec3("color", glm::vec3(1,1,1));
shadowRenderShader->setMat4("model",
glm::translate(
glm::scale(glm::mat4(1), glm::vec3(light.size, light.size, 0)),
glm::vec3(light.x - light.size/2, light.y - light.size/2, 0))
);
shadowRenderShader->setMat4("view", view);
shadowRenderShader->setMat4("projection", projection);
glBindTexture(GL_TEXTURE_2D, shadowTexture);
glBindVertexArray(unitSquare->VAO);
glDrawArrays(unitSquare->type, 0, unitSquare->vertexCount);
// draw scene
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
shader->useProgram();
shader->setVec3("color", glm::vec3(1,0,0));
shader->setMat4("model", glm::mat4(1));
shader->setMat4("view", view);
shader->setMat4("projection", projection);
shader->setInt("tex", 0);
glBindVertexArray(geometry->VAO);
glDrawArrays(geometry->type, 0, geometry->vertexCount);
}
@tarik02
Copy link

tarik02 commented Jan 19, 2019

Where can I get full source?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment