Skip to content

Commit

Permalink
feat: add preset::shader
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAMS committed Apr 2, 2024
1 parent 4a82de7 commit 22e91f1
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 17 deletions.
15 changes: 0 additions & 15 deletions core/entity_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,4 @@ class DynamicObj{
glm::vec3 acceleration;
};

// class RenderObj{
// public:
// RenderObj(Shader* shader, Model* model, model_t* mat_model):
// shader(shader), model(model), mat_model(mat_model){}
// void render(const Lights* lights, const camera_t* camera){
// lights->apply_shader(shader);
// model->draw(shader, camera, mat_model);
// }
// private:
// model_t* mat_model;
// Model* model;
// Shader* shader;

// };

}
6 changes: 4 additions & 2 deletions core/mesh_layer.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <string>
#include <sys/socket.h>
#include <vector>
#include "utils/preset.hpp"
#include "vertices_layer.hpp"


Expand Down Expand Up @@ -107,9 +109,9 @@ class Shader{
public:
float tmp_material_shininess=32;

void setup_shader(){
void setup_shader(uint32_t max_light_num=128){
assert_with_info(shader==nullptr, "shader is already setup");
shader = new shader_t("../shader/fragpos_normal_texcoord.vs", "../shader/multiple_lights.fs", "view", "projection", "model");
shader = new shader_t(preset::shader::vs_fragpos_normal_texcoord(), preset::shader::fs_multiple_lights_shader(max_light_num), "view", "projection", "model");
}
void set_lights(const std::vector<LightDir>& dir_lights, const std::vector<LightPoint>& point_lights, const std::vector<LightSpot>& spot_lights){
shader->use();
Expand Down
29 changes: 29 additions & 0 deletions core/vertices_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,35 @@ shader_t::shader_t(const char* vertex_shader_path, const char* fragment_shader_p
glDeleteShader(fragment_id);
}

shader_t::shader_t(const std::string vertex_shader, const std::string fragment_shader,
const char* view_key, const char* proj_key, const char* model_key):
vertex_shader_path("FROM STRING"), fragment_shader_path("FROM STRING"),
view_key(view_key), proj_key(proj_key), model_key(model_key)
{
const char* vShaderCode = vertex_shader.c_str();
const char* fShaderCode = fragment_shader.c_str();
// 2. compile shaders
// vertex shader
vertex_id = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_id, 1, &vShaderCode, NULL);
glCompileShader(vertex_id);
check_compile_errors(vertex_id, "VERTEX");
// fragment Shader
fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_id, 1, &fShaderCode, NULL);
glCompileShader(fragment_id);
check_compile_errors(fragment_id, "FRAGMENT");
// shader Program
program_id = glCreateProgram();
glAttachShader(program_id, vertex_id);
glAttachShader(program_id, fragment_id);
glLinkProgram(program_id);
check_compile_errors(program_id, "PROGRAM");
// delete the shaders as they're linked into our program now and no longer necessary
glDeleteShader(vertex_id);
glDeleteShader(fragment_id);
}

void shader_t::use() const{
glUseProgram(program_id);
}
Expand Down
2 changes: 2 additions & 0 deletions core/vertices_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class shader_t{

shader_t(const char* vertex_shader_path, const char* fragment_shader_path,
const char* view_key, const char* proj_key, const char* model_key);
shader_t(const std::string vertex_shader, const std::string fragment_shader,
const char* view_key, const char* proj_key, const char* model_key);
void use() const;
void clear_texture();
void bind_texture(const char* texture_key, class texture_t* texture);
Expand Down
198 changes: 198 additions & 0 deletions utils/preset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@

#include <cassert>
#include <cmath>
#include <cstdint>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtx/normal.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <string>

namespace Ez3DGL {
namespace preset {
Expand Down Expand Up @@ -138,5 +140,201 @@ namespace Ez3DGL {
return vgen_revolu_surf::generate(plane_num, outlines, glm::vec3(0.0, 1.0, 0.0));
}
};

class shader{
public:
static std::string vs_fragpos_normal_texcoord(){
return std::string(R"(
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoord;
out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoord = aTexCoord;
gl_Position = projection * view * vec4(FragPos, 1.0);
}
)");
}
static std::string fs_multiple_lights_shader(uint32_t max_light_num){
return std::string(R"(
#version 330 core
out vec4 frag_col;
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoord;
uniform vec3 viewPos;
// 材质
#define MAX_LIGHT_NUM )")+
std::to_string(max_light_num)+
std::string(R"(
#define MAX_MATERIAL_NUM 4
uniform int diffuse_num;
uniform int specular_num;
struct Material {
sampler2D diffuse[MAX_MATERIAL_NUM];
sampler2D specular[MAX_MATERIAL_NUM];
//TODO Emission
float shininess;
};
uniform Material material;
// 定向光
struct DirLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform DirLight lights_dir[MAX_LIGHT_NUM];
uniform int dir_light_num;
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(-light.direction);
// 漫反射着色
float diff = max(dot(normal, lightDir), 0.0);
// 镜面光着色
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// 合并结果
vec3 ambient = light.ambient * vec3(texture(material.diffuse[0], TexCoord));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse[0], TexCoord));
vec3 specular = light.specular * spec * vec3(texture(material.specular[0], TexCoord));
return (ambient + diffuse + specular);
}
// 点光源
struct PointLight {
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform PointLight lights_point[MAX_LIGHT_NUM];
uniform int point_light_num;
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// 漫反射着色
float diff = max(dot(normal, lightDir), 0.0);
// 镜面光着色
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// 衰减
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
// 合并结果
vec3 ambient = light.ambient * texture(material.diffuse[0], TexCoord).rgb;
vec3 diffuse = light.diffuse * diff * texture(material.diffuse[0], TexCoord).rgb;
vec3 specular = light.specular * spec * texture(material.specular[0], TexCoord).rgb;
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
}
// 聚光
struct SpotLight {
vec3 position;
vec3 direction;
float cutoff;
float cutoff_outer;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform SpotLight lights_spot[MAX_LIGHT_NUM];
uniform int spot_light_num;
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// spotlight intensity
float theta = dot(lightDir, normalize(-light.direction));
float epsilon = light.cutoff - light.cutoff_outer;
float intensity = clamp((theta - light.cutoff_outer) / epsilon, 0.0, 1.0);
// combine results
vec3 ambient = light.ambient * vec3(mix(texture(material.diffuse[0], TexCoord), texture(material.diffuse[1], TexCoord), 0.2));
vec3 diffuse = light.diffuse * diff * vec3(mix(texture(material.diffuse[0], TexCoord), texture(material.diffuse[1], TexCoord), 0.2));
vec3 specular = light.specular * spec * vec3(texture(material.specular[0], TexCoord));
ambient *= attenuation * intensity;
diffuse *= attenuation * intensity;
specular *= attenuation * intensity;
return (ambient + diffuse + specular);
}
void main()
{
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos);
// 第一阶段:定向光照
vec3 dir_result = vec3(0, 0, 0);
for(int i = 0; i < min(MAX_LIGHT_NUM, dir_light_num); i++)
dir_result += CalcDirLight(lights_dir[i], norm, viewDir);
// 第二阶段:点光源
vec3 point_result = vec3(0, 0, 0);
for(int i = 0; i < min(MAX_LIGHT_NUM, point_light_num); i++)
point_result += CalcPointLight(lights_point[i], norm, FragPos, viewDir);
// 第三阶段:聚光
vec3 spot_result = vec3(0, 0, 0);
for(int i = 0; i < min(MAX_LIGHT_NUM, spot_light_num); i++)
spot_result += CalcSpotLight(lights_spot[i], norm, FragPos, viewDir);
int light_num_sum = dir_light_num + point_light_num + spot_light_num;
vec3 result = dir_result + point_result + spot_result;
frag_col = vec4(result, 1.0);
}
)");
}
};
}
}

0 comments on commit 22e91f1

Please sign in to comment.