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": {
|
||||
"shader": {
|
||||
"vertex_path": "shaders/17-vert.glsl",
|
||||
"frag_path": "shaders/17-frag.glsl"
|
||||
"vertex_path": "shaders/18-vert.glsl",
|
||||
"frag_path": "shaders/18-frag.glsl"
|
||||
},
|
||||
"light_shader": {
|
||||
"vertex_path": "shaders/17-vert.glsl",
|
||||
"frag_path": "shaders/17-lightsource.frag.glsl"
|
||||
"vertex_path": "shaders/18-vert.glsl",
|
||||
"frag_path": "shaders/18-lightsource.frag.glsl"
|
||||
},
|
||||
"outline_shader": {
|
||||
"vertex_path": "shaders/18-vert.glsl",
|
||||
"frag_path": "shaders/18-outline.glsl"
|
||||
},
|
||||
"materials": {
|
||||
"crate": {
|
||||
"default": {
|
||||
"ambient": [0.5, 0.5, 0.5],
|
||||
"shininess": 32.0,
|
||||
"diffuseMap": 0,
|
||||
"specularMap": 0
|
||||
},
|
||||
"popcorn": {
|
||||
"shiny": {
|
||||
"ambient": [0.5, 0.25, 0.31],
|
||||
"shininess": 10000.0,
|
||||
"diffuseMap": 0,
|
||||
|
|
@ -23,29 +27,22 @@
|
|||
}
|
||||
},
|
||||
"models": {
|
||||
"crate": {
|
||||
"marble_cube": {
|
||||
"directory": "assets",
|
||||
"model_path": "crate.obj"
|
||||
"model_path": "marble_cube.glb"
|
||||
},
|
||||
"popcorn": {
|
||||
"metal_floor": {
|
||||
"directory": "assets",
|
||||
"model_path": "popcorn_model_a.glb"
|
||||
"model_path": "metal_floor.glb"
|
||||
}
|
||||
},
|
||||
"things": [
|
||||
{"model": "crate", "position": [0.0, 0.0, 0.0], "material": "crate"},
|
||||
{"model": "crate", "position": [2.0, 5.0, -15.0], "material": "crate"},
|
||||
{"model": "crate", "position": [-1.5, -2.2, -2.5], "material": "crate"},
|
||||
{"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"}
|
||||
{"model": "marble_cube", "position": [-1.0, 0.0, -1.0], "material": "default"},
|
||||
{"model": "marble_cube", "position": [2.0, 0.0, 0.0], "material": "default"},
|
||||
{"model": "metal_floor", "position": [0.0, 0.0, 0.0], "material": "shiny"}
|
||||
],
|
||||
"camera": {
|
||||
"position": [0.0, 0.0, 3.0],
|
||||
"position": [0.0, 0.1, 3.0],
|
||||
"front": [0.0, 0.0, -1.0],
|
||||
"up": [0.0, 1.0, 0.0],
|
||||
"direction": [0.0, 0.0, 0.0],
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ uniform DirLight dirLights[MAX_LIGHTS];
|
|||
uniform int spotLightCount = 0;
|
||||
uniform SpotLight spotLights[MAX_LIGHTS];
|
||||
|
||||
|
||||
float near = 0.1;
|
||||
float far = 100.0;
|
||||
|
||||
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
float LinearizeDepth(float depth)
|
||||
{
|
||||
float ndc = depth * 2.0 - 1.0;
|
||||
return (2.0 * near * far) / (far + near - ndc * (far - near));
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 norm = normalize(Normal);
|
||||
|
|
@ -159,4 +170,7 @@ void main()
|
|||
}
|
||||
|
||||
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 {
|
||||
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