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
BIN
18-depth-testing/assets/marble.jpg
Normal file
BIN
18-depth-testing/assets/marble.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 508 KiB |
1
18-depth-testing/assets/marble_cube.bbmodel
Normal file
1
18-depth-testing/assets/marble_cube.bbmodel
Normal file
File diff suppressed because one or more lines are too long
BIN
18-depth-testing/assets/marble_cube.glb
Normal file
BIN
18-depth-testing/assets/marble_cube.glb
Normal file
Binary file not shown.
BIN
18-depth-testing/assets/metal.png
Normal file
BIN
18-depth-testing/assets/metal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
1
18-depth-testing/assets/metal_floor.bbmodel
Normal file
1
18-depth-testing/assets/metal_floor.bbmodel
Normal file
File diff suppressed because one or more lines are too long
BIN
18-depth-testing/assets/metal_floor.glb
Normal file
BIN
18-depth-testing/assets/metal_floor.glb
Normal file
Binary file not shown.
|
|
@ -1,21 +1,25 @@
|
||||||
{
|
{
|
||||||
"scene": {
|
"scene": {
|
||||||
"shader": {
|
"shader": {
|
||||||
"vertex_path": "shaders/17-vert.glsl",
|
"vertex_path": "shaders/18-vert.glsl",
|
||||||
"frag_path": "shaders/17-frag.glsl"
|
"frag_path": "shaders/18-frag.glsl"
|
||||||
},
|
},
|
||||||
"light_shader": {
|
"light_shader": {
|
||||||
"vertex_path": "shaders/17-vert.glsl",
|
"vertex_path": "shaders/18-vert.glsl",
|
||||||
"frag_path": "shaders/17-lightsource.frag.glsl"
|
"frag_path": "shaders/18-lightsource.frag.glsl"
|
||||||
|
},
|
||||||
|
"outline_shader": {
|
||||||
|
"vertex_path": "shaders/18-vert.glsl",
|
||||||
|
"frag_path": "shaders/18-outline.glsl"
|
||||||
},
|
},
|
||||||
"materials": {
|
"materials": {
|
||||||
"crate": {
|
"default": {
|
||||||
"ambient": [0.5, 0.5, 0.5],
|
"ambient": [0.5, 0.5, 0.5],
|
||||||
"shininess": 32.0,
|
"shininess": 32.0,
|
||||||
"diffuseMap": 0,
|
"diffuseMap": 0,
|
||||||
"specularMap": 0
|
"specularMap": 0
|
||||||
},
|
},
|
||||||
"popcorn": {
|
"shiny": {
|
||||||
"ambient": [0.5, 0.25, 0.31],
|
"ambient": [0.5, 0.25, 0.31],
|
||||||
"shininess": 10000.0,
|
"shininess": 10000.0,
|
||||||
"diffuseMap": 0,
|
"diffuseMap": 0,
|
||||||
|
|
@ -23,29 +27,22 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
"crate": {
|
"marble_cube": {
|
||||||
"directory": "assets",
|
"directory": "assets",
|
||||||
"model_path": "crate.obj"
|
"model_path": "marble_cube.glb"
|
||||||
},
|
},
|
||||||
"popcorn": {
|
"metal_floor": {
|
||||||
"directory": "assets",
|
"directory": "assets",
|
||||||
"model_path": "popcorn_model_a.glb"
|
"model_path": "metal_floor.glb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"things": [
|
"things": [
|
||||||
{"model": "crate", "position": [0.0, 0.0, 0.0], "material": "crate"},
|
{"model": "marble_cube", "position": [-1.0, 0.0, -1.0], "material": "default"},
|
||||||
{"model": "crate", "position": [2.0, 5.0, -15.0], "material": "crate"},
|
{"model": "marble_cube", "position": [2.0, 0.0, 0.0], "material": "default"},
|
||||||
{"model": "crate", "position": [-1.5, -2.2, -2.5], "material": "crate"},
|
{"model": "metal_floor", "position": [0.0, 0.0, 0.0], "material": "shiny"}
|
||||||
{"model": "popcorn", "position": [-3.8, -2.0, -12.3], "material": "popcorn"},
|
|
||||||
{"model": "crate", "position": [ 2.4, -0.4, -3.5], "material": "crate"},
|
|
||||||
{"model": "crate", "position": [-1.7, 3.0, -7.5], "material": "crate"},
|
|
||||||
{"model": "popcorn", "position": [ 1.3, -2.0, -2.5], "material": "popcorn"},
|
|
||||||
{"model": "crate", "position": [ 1.5, 2.0, -2.5], "material": "crate"},
|
|
||||||
{"model": "popcorn", "position": [ 1.5, 0.2, -1.5], "material": "popcorn"},
|
|
||||||
{"model": "crate", "position": [-1.3, 1.0, -1.5], "material": "crate"}
|
|
||||||
],
|
],
|
||||||
"camera": {
|
"camera": {
|
||||||
"position": [0.0, 0.0, 3.0],
|
"position": [0.0, 0.1, 3.0],
|
||||||
"front": [0.0, 0.0, -1.0],
|
"front": [0.0, 0.0, -1.0],
|
||||||
"up": [0.0, 1.0, 0.0],
|
"up": [0.0, 1.0, 0.0],
|
||||||
"direction": [0.0, 0.0, 0.0],
|
"direction": [0.0, 0.0, 0.0],
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,10 @@ uniform DirLight dirLights[MAX_LIGHTS];
|
||||||
uniform int spotLightCount = 0;
|
uniform int spotLightCount = 0;
|
||||||
uniform SpotLight spotLights[MAX_LIGHTS];
|
uniform SpotLight spotLights[MAX_LIGHTS];
|
||||||
|
|
||||||
|
|
||||||
|
float near = 0.1;
|
||||||
|
float far = 100.0;
|
||||||
|
|
||||||
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
|
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
|
||||||
{
|
{
|
||||||
vec3 mat_tex = vec3(texture(material.diffuse, TexCoords));
|
vec3 mat_tex = vec3(texture(material.diffuse, TexCoords));
|
||||||
|
|
@ -137,6 +141,13 @@ vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
|
||||||
return ambient + diffuse + specular;
|
return ambient + diffuse + specular;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float LinearizeDepth(float depth)
|
||||||
|
{
|
||||||
|
float ndc = depth * 2.0 - 1.0;
|
||||||
|
return (2.0 * near * far) / (far + near - ndc * (far - near));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 norm = normalize(Normal);
|
vec3 norm = normalize(Normal);
|
||||||
|
|
@ -159,4 +170,7 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
FragColor = vec4(result, 1.0);
|
FragColor = vec4(result, 1.0);
|
||||||
|
|
||||||
|
// float depth = LinearizeDepth(gl_FragCoord.z) / far;
|
||||||
|
// FragColor = vec4(vec3(depth), 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
18-depth-testing/shaders/18-outline.glsl
Normal file
6
18-depth-testing/shaders/18-outline.glsl
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -94,6 +94,7 @@ namespace components {
|
||||||
struct Scene {
|
struct Scene {
|
||||||
components::Shader shader;
|
components::Shader shader;
|
||||||
components::Shader light_shader;
|
components::Shader light_shader;
|
||||||
|
components::Shader outline_shader;
|
||||||
std::map<std::string, Material> materials;
|
std::map<std::string, Material> materials;
|
||||||
std::map<std::string, Model> models;
|
std::map<std::string, Model> models;
|
||||||
std::vector<Thing> things;
|
std::vector<Thing> things;
|
||||||
|
|
@ -101,5 +102,5 @@ namespace components {
|
||||||
Lighting light;
|
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) {
|
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) {
|
if(glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {
|
||||||
|
|
@ -84,6 +84,10 @@ void process_input(GLFWwindow *window, Scene& scene) {
|
||||||
|
|
||||||
Scene setup() {
|
Scene setup() {
|
||||||
glEnable(GL_DEPTH_TEST);
|
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");
|
components::Scene config = utils::load_scene_config("config.json");
|
||||||
Scene scene(config);
|
Scene scene(config);
|
||||||
|
|
|
||||||
|
|
@ -10,28 +10,22 @@ void Scene::update() {
|
||||||
camera.update(deltaTime);
|
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);
|
glm::mat4 model = glm::mat4(1.0f);
|
||||||
model = glm::translate(model, position);
|
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) {
|
void Scene::render(GLFWwindow* window) {
|
||||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
shader.use();
|
|
||||||
|
|
||||||
// time is used for fake 3d rotation
|
|
||||||
float time = glfwGetTime();
|
|
||||||
|
|
||||||
glm::mat4 view = camera.look_at();
|
glm::mat4 view = camera.look_at();
|
||||||
glm::mat4 projection = glm::mat4(1.0f);
|
glm::mat4 projection = glm::mat4(1.0f);
|
||||||
|
|
@ -42,7 +36,6 @@ void Scene::render(GLFWwindow* window) {
|
||||||
shader.use();
|
shader.use();
|
||||||
shader.setMat4("view", view);
|
shader.setMat4("view", view);
|
||||||
shader.setMat4("projection", projection);
|
shader.setMat4("projection", projection);
|
||||||
shader.setVec3("viewPos", camera.position);
|
|
||||||
|
|
||||||
// for now just detect the camera moved and do spotlight update
|
// for now just detect the camera moved and do spotlight update
|
||||||
if(camera.dirty) {
|
if(camera.dirty) {
|
||||||
|
|
@ -53,10 +46,41 @@ void Scene::render(GLFWwindow* window) {
|
||||||
camera.dirty = false;
|
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) {
|
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() {
|
void Scene::cleanup() {
|
||||||
|
|
@ -64,8 +88,13 @@ void Scene::cleanup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::spawn(const std::string& name, components::Position& position) {
|
void Scene::spawn(const std::string& name, components::Position& position) {
|
||||||
things.emplace_back(
|
if(models.contains(name)) {
|
||||||
models.at(name),
|
things.emplace_back(
|
||||||
position,
|
name,
|
||||||
materials.at(name));
|
models.at(name),
|
||||||
|
position,
|
||||||
|
materials.at("default"));
|
||||||
|
} else {
|
||||||
|
dbc::log($F("No model named: {}", name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct Thing {
|
struct Thing {
|
||||||
|
std::string name;
|
||||||
Model& model;
|
Model& model;
|
||||||
components::Position position;
|
components::Position position;
|
||||||
Material& material;
|
Material& material;
|
||||||
|
|
@ -22,6 +23,8 @@ struct Thing {
|
||||||
struct Scene {
|
struct Scene {
|
||||||
Shader shader;
|
Shader shader;
|
||||||
Shader light_shader;
|
Shader light_shader;
|
||||||
|
Shader outline_shader;
|
||||||
|
|
||||||
std::map<std::string, components::Material> materials;
|
std::map<std::string, components::Material> materials;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
components::Lighting light;
|
components::Lighting light;
|
||||||
|
|
@ -34,6 +37,7 @@ struct Scene {
|
||||||
Scene(components::Scene& config):
|
Scene(components::Scene& config):
|
||||||
shader{config.shader.vertex_path, config.shader.frag_path},
|
shader{config.shader.vertex_path, config.shader.frag_path},
|
||||||
light_shader{config.light_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},
|
materials{config.materials},
|
||||||
camera{
|
camera{
|
||||||
.position=config.camera.position,
|
.position=config.camera.position,
|
||||||
|
|
@ -50,6 +54,7 @@ struct Scene {
|
||||||
|
|
||||||
for(auto& thing : config.things) {
|
for(auto& thing : config.things) {
|
||||||
things.emplace_back(
|
things.emplace_back(
|
||||||
|
thing.model,
|
||||||
models.at(thing.model),
|
models.at(thing.model),
|
||||||
thing.position,
|
thing.position,
|
||||||
materials.at(thing.material));
|
materials.at(thing.material));
|
||||||
|
|
@ -60,7 +65,7 @@ struct Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
void update();
|
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 render(GLFWwindow* window);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void spawn(const std::string& name, components::Position& position);
|
void spawn(const std::string& name, components::Position& position);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue