Have a basic outlining thing with stencils but required a bit of hacking to make it work in Scene::render.
This commit is contained in:
parent
993f148710
commit
dc973009fd
13 changed files with 101 additions and 43 deletions
|
|
@ -94,6 +94,7 @@ namespace components {
|
|||
struct Scene {
|
||||
components::Shader shader;
|
||||
components::Shader light_shader;
|
||||
components::Shader outline_shader;
|
||||
std::map<std::string, Material> materials;
|
||||
std::map<std::string, Model> models;
|
||||
std::vector<Thing> things;
|
||||
|
|
@ -101,5 +102,5 @@ namespace components {
|
|||
Lighting light;
|
||||
};
|
||||
|
||||
ENROLL_COMPONENT(Scene, shader, light_shader, materials, models, things, camera, light);
|
||||
ENROLL_COMPONENT(Scene, shader, light_shader, outline_shader, materials, models, things, camera, light);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void process_input(GLFWwindow *window, Scene& scene) {
|
|||
}
|
||||
|
||||
if(glfwGetKey(window, GLFW_KEY_M) == GLFW_PRESS) {
|
||||
scene.spawn("popcorn", scene.camera.position);
|
||||
scene.spawn("marble_cube", scene.camera.position);
|
||||
}
|
||||
|
||||
if(glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {
|
||||
|
|
@ -84,6 +84,10 @@ void process_input(GLFWwindow *window, Scene& scene) {
|
|||
|
||||
Scene setup() {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
components::Scene config = utils::load_scene_config("config.json");
|
||||
Scene scene(config);
|
||||
|
|
|
|||
|
|
@ -10,28 +10,22 @@ void Scene::update() {
|
|||
camera.update(deltaTime);
|
||||
}
|
||||
|
||||
void Scene::draw_model(Model& scene_model, Material& material, glm::mat4& projection, glm::mat4& view, glm::vec3& position)
|
||||
void Scene::draw_model(Shader& with_shader, Model& scene_model, Material& material, glm::mat4& projection, glm::mat4& view, glm::vec3& position, float scale)
|
||||
{
|
||||
shader.apply_material(material);
|
||||
with_shader.apply_material(material);
|
||||
|
||||
float time = glfwGetTime();
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, position);
|
||||
model = glm::rotate(model, glm::radians(time * 10.0f), glm::vec3(1.0f, 0.3f, 0.5f));
|
||||
model = glm::scale(model, glm::vec3(scale, scale, scale));
|
||||
|
||||
shader.setMat4("model", model);
|
||||
with_shader.setMat4("model", model);
|
||||
|
||||
scene_model.draw(shader);
|
||||
scene_model.draw(with_shader);
|
||||
}
|
||||
|
||||
void Scene::render(GLFWwindow* window) {
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
shader.use();
|
||||
|
||||
// time is used for fake 3d rotation
|
||||
float time = glfwGetTime();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glm::mat4 view = camera.look_at();
|
||||
glm::mat4 projection = glm::mat4(1.0f);
|
||||
|
|
@ -42,7 +36,6 @@ void Scene::render(GLFWwindow* window) {
|
|||
shader.use();
|
||||
shader.setMat4("view", view);
|
||||
shader.setMat4("projection", projection);
|
||||
shader.setVec3("viewPos", camera.position);
|
||||
|
||||
// for now just detect the camera moved and do spotlight update
|
||||
if(camera.dirty) {
|
||||
|
|
@ -53,10 +46,41 @@ void Scene::render(GLFWwindow* window) {
|
|||
camera.dirty = false;
|
||||
}
|
||||
|
||||
// BUG: no connection between models and positions
|
||||
|
||||
// ultra dumb way to draw the floor without stencil, so next move is to
|
||||
// be able to tag models with specific functionality during render.
|
||||
for(auto& thing : things) {
|
||||
draw_model(thing.model, thing.material, projection, view, thing.position);
|
||||
if(thing.name == "metal_floor") {
|
||||
draw_model(shader, thing.model, thing.material, projection, view, thing.position);
|
||||
}
|
||||
}
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glStencilMask(0xFF);
|
||||
|
||||
for(auto& thing : things) {
|
||||
if(thing.name != "metal_floor") {
|
||||
draw_model(shader, thing.model, thing.material, projection, view, thing.position);
|
||||
}
|
||||
}
|
||||
|
||||
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
||||
glStencilMask(0x00);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
outline_shader.use();
|
||||
outline_shader.setMat4("view", view);
|
||||
outline_shader.setMat4("projection", projection);
|
||||
|
||||
for(auto& thing : things) {
|
||||
if(thing.name != "metal_floor") {
|
||||
draw_model(outline_shader, thing.model, thing.material, projection, view, thing.position, 1.01f);
|
||||
}
|
||||
}
|
||||
|
||||
glStencilMask(0xFF);
|
||||
glStencilFunc(GL_ALWAYS, 0, 0xFF);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void Scene::cleanup() {
|
||||
|
|
@ -64,8 +88,13 @@ void Scene::cleanup() {
|
|||
}
|
||||
|
||||
void Scene::spawn(const std::string& name, components::Position& position) {
|
||||
things.emplace_back(
|
||||
models.at(name),
|
||||
position,
|
||||
materials.at(name));
|
||||
if(models.contains(name)) {
|
||||
things.emplace_back(
|
||||
name,
|
||||
models.at(name),
|
||||
position,
|
||||
materials.at("default"));
|
||||
} else {
|
||||
dbc::log($F("No model named: {}", name));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <vector>
|
||||
|
||||
struct Thing {
|
||||
std::string name;
|
||||
Model& model;
|
||||
components::Position position;
|
||||
Material& material;
|
||||
|
|
@ -22,6 +23,8 @@ struct Thing {
|
|||
struct Scene {
|
||||
Shader shader;
|
||||
Shader light_shader;
|
||||
Shader outline_shader;
|
||||
|
||||
std::map<std::string, components::Material> materials;
|
||||
Camera camera;
|
||||
components::Lighting light;
|
||||
|
|
@ -34,6 +37,7 @@ struct Scene {
|
|||
Scene(components::Scene& config):
|
||||
shader{config.shader.vertex_path, config.shader.frag_path},
|
||||
light_shader{config.light_shader.vertex_path, config.shader.frag_path},
|
||||
outline_shader{config.outline_shader.vertex_path, config.outline_shader.frag_path},
|
||||
materials{config.materials},
|
||||
camera{
|
||||
.position=config.camera.position,
|
||||
|
|
@ -50,6 +54,7 @@ struct Scene {
|
|||
|
||||
for(auto& thing : config.things) {
|
||||
things.emplace_back(
|
||||
thing.model,
|
||||
models.at(thing.model),
|
||||
thing.position,
|
||||
materials.at(thing.material));
|
||||
|
|
@ -60,7 +65,7 @@ struct Scene {
|
|||
}
|
||||
|
||||
void update();
|
||||
void draw_model(Model& scene_model, Material& material, glm::mat4& projection, glm::mat4& view, glm::vec3& position);
|
||||
void draw_model(Shader& with_shader, Model& scene_model, Material& material, glm::mat4& projection, glm::mat4& view, glm::vec3& position, float scale=1.0f);
|
||||
void render(GLFWwindow* window);
|
||||
void cleanup();
|
||||
void spawn(const std::string& name, components::Position& position);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue