Start working on graphics
This commit is contained in:
parent
1ea89fb2c9
commit
aaa9f3e3ab
22
assets/shaders/light_ps.glsl
Normal file
22
assets/shaders/light_ps.glsl
Normal file
@ -0,0 +1,22 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// in vec3 worldPosition;
|
||||
// in vec3 worldNormal;
|
||||
|
||||
// Input uniform values
|
||||
// uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
void main()
|
||||
{
|
||||
finalColor = colDiffuse*fragColor;
|
||||
}
|
37
assets/shaders/lit_ps.glsl
Normal file
37
assets/shaders/lit_ps.glsl
Normal file
@ -0,0 +1,37 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// in vec3 worldPosition;
|
||||
in vec3 worldNormal;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
uniform vec3 ambient;
|
||||
uniform vec3 lightDir;
|
||||
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// final color is the color from the texture
|
||||
// times the tint color (colDiffuse)
|
||||
// times the fragment color (interpolated vertex color)
|
||||
|
||||
float NDotL = dot(lightDir, -worldNormal);
|
||||
float toon = 0.5 * smoothstep(0.66, 0.67, NDotL) + 0.5;
|
||||
vec3 light = mix(vec3(0), vec3(1), toon);
|
||||
|
||||
finalColor = texelColor*colDiffuse*fragColor * vec4(light, 1);
|
||||
}
|
31
assets/shaders/lit_vs.glsl
Normal file
31
assets/shaders/lit_vs.glsl
Normal file
@ -0,0 +1,31 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
out vec3 worldPosition;
|
||||
out vec3 worldNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
worldPosition = (matModel * vec4(vertexPosition, 1.0)).xyz;
|
||||
worldNormal = mat3(matModel) * vertexNormal;
|
||||
}
|
@ -36,7 +36,7 @@ esac
|
||||
|
||||
# Build the game.
|
||||
echo "Building game$DLL_EXT"
|
||||
odin build game -extra-linker-flags:"$EXTRA_LINKER_FLAGS" -define:RAYLIB_SHARED=true -define:PHYSFS_SHARED=true -define:TRACY_ENABLE=true -collection:libs=./libs -collection:common=./common -collection:game=./game -build-mode:dll -out:game_tmp$DLL_EXT -strict-style -vet -debug -o:speed
|
||||
odin build game -extra-linker-flags:"$EXTRA_LINKER_FLAGS" -define:RAYLIB_SHARED=true -define:GLFW_SHARED=true -define:PHYSFS_SHARED=true -define:TRACY_ENABLE=true -collection:libs=./libs -collection:common=./common -collection:game=./game -build-mode:dll -out:game_tmp$DLL_EXT -strict-style -vet -debug -o:speed
|
||||
|
||||
# Need to use a temp file on Linux because it first writes an empty `game.so`, which the game will load before it is actually fully written.
|
||||
mv game_tmp$DLL_EXT game$DLL_EXT
|
||||
|
@ -48,6 +48,7 @@ Curve_2D :: [][2]f32
|
||||
Asset_Manager :: struct {
|
||||
textures: Asset_Cache(rl.Texture2D),
|
||||
models: Asset_Cache(rl.Model),
|
||||
shaders: Asset_Cache(Loaded_Shader),
|
||||
curves_1d: Asset_Cache([]f32),
|
||||
curves_2d: Asset_Cache(Curve_2D),
|
||||
bvhs: map[cstring]Loaded_BVH,
|
||||
@ -59,8 +60,12 @@ Asset_Cache_Entry :: struct($E: typeid) {
|
||||
modtime: i64,
|
||||
}
|
||||
|
||||
Asset_Cache_Loader_Payload :: union {
|
||||
cstring,
|
||||
}
|
||||
|
||||
Asset_Cache_Loader :: struct($E: typeid) {
|
||||
load: proc(path: cstring) -> (E, bool),
|
||||
load: proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (E, bool),
|
||||
unload: proc(value: E),
|
||||
}
|
||||
|
||||
@ -69,8 +74,37 @@ Asset_Cache :: struct($E: typeid) {
|
||||
loader: Asset_Cache_Loader(E),
|
||||
}
|
||||
|
||||
|
||||
Shader_Location :: enum {
|
||||
Ambient,
|
||||
LightDir,
|
||||
}
|
||||
Shader_Location_Set :: bit_set[Shader_Location]
|
||||
Shader_Location_Array :: [Shader_Location]i32
|
||||
|
||||
SHADER_LOCATION_NAMES := [Shader_Location]cstring {
|
||||
.Ambient = "ambient",
|
||||
.LightDir = "lightDir",
|
||||
}
|
||||
|
||||
Loaded_Shader :: struct {
|
||||
shader: rl.Shader,
|
||||
location_set: Shader_Location_Set,
|
||||
locations: Shader_Location_Array,
|
||||
}
|
||||
|
||||
SHADER_LOADER :: Asset_Cache_Loader(Loaded_Shader) {
|
||||
load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (Loaded_Shader, bool) {
|
||||
shader := rl.LoadShader(path, payload.(cstring))
|
||||
return Loaded_Shader{shader = shader}, rl.IsShaderValid(shader)
|
||||
},
|
||||
unload = proc(shader: Loaded_Shader) {
|
||||
rl.UnloadShader(shader.shader)
|
||||
},
|
||||
}
|
||||
|
||||
MODEL_LOADER :: Asset_Cache_Loader(rl.Model) {
|
||||
load = proc(path: cstring) -> (rl.Model, bool) {
|
||||
load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Model, bool) {
|
||||
model := rl.LoadModel(path)
|
||||
return model, rl.IsModelValid(model)
|
||||
},
|
||||
@ -80,7 +114,7 @@ MODEL_LOADER :: Asset_Cache_Loader(rl.Model) {
|
||||
}
|
||||
|
||||
TEXTURE_LOADER :: Asset_Cache_Loader(rl.Texture2D) {
|
||||
load = proc(path: cstring) -> (rl.Texture2D, bool) {
|
||||
load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Texture2D, bool) {
|
||||
texture := rl.LoadTexture(path)
|
||||
return texture, rl.IsTextureValid(texture)
|
||||
},
|
||||
@ -90,7 +124,7 @@ TEXTURE_LOADER :: Asset_Cache_Loader(rl.Texture2D) {
|
||||
}
|
||||
|
||||
CURVE_1D_CSV_LOADER :: Asset_Cache_Loader([]f32) {
|
||||
load = proc(path: cstring) -> ([]f32, bool) {
|
||||
load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> ([]f32, bool) {
|
||||
data, err := physfs.read_entire_file(string(path), context.temp_allocator)
|
||||
if err != nil {
|
||||
log.errorf("Failed to read curve: %s, %v", path, err)
|
||||
@ -111,7 +145,7 @@ CURVE_1D_CSV_LOADER :: Asset_Cache_Loader([]f32) {
|
||||
}
|
||||
|
||||
CURVE_2D_CSV_LOADER :: Asset_Cache_Loader(Curve_2D) {
|
||||
load = proc(path: cstring) -> (Curve_2D, bool) {
|
||||
load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (Curve_2D, bool) {
|
||||
data, err := physfs.read_entire_file(string(path), context.temp_allocator)
|
||||
if err != nil {
|
||||
log.errorf("Failed to read curve: %s, %v", path, err)
|
||||
@ -135,6 +169,9 @@ assetman_init :: proc(assetman: ^Asset_Manager) {
|
||||
assetman.models = {
|
||||
loader = MODEL_LOADER,
|
||||
}
|
||||
assetman.shaders = {
|
||||
loader = SHADER_LOADER,
|
||||
}
|
||||
assetman.textures = {
|
||||
loader = TEXTURE_LOADER,
|
||||
}
|
||||
@ -156,6 +193,7 @@ Asset_Cache_Result :: enum {
|
||||
assetcache_fetch_or_load :: proc(
|
||||
ac: ^$T/Asset_Cache($E),
|
||||
path: cstring,
|
||||
payload: Asset_Cache_Loader_Payload = nil,
|
||||
) -> (
|
||||
value: E,
|
||||
modtime: i64,
|
||||
@ -174,7 +212,7 @@ assetcache_fetch_or_load :: proc(
|
||||
} else {
|
||||
// Try to load the new version
|
||||
|
||||
new_value, ok := ac.loader.load(path)
|
||||
new_value, ok := ac.loader.load(path, payload)
|
||||
|
||||
if ok {
|
||||
result = .Reloaded
|
||||
@ -197,7 +235,7 @@ assetcache_fetch_or_load :: proc(
|
||||
} else {
|
||||
modtime = physfs.getLastModTime(path)
|
||||
ok: bool
|
||||
value, ok = ac.loader.load(path)
|
||||
value, ok = ac.loader.load(path, payload)
|
||||
|
||||
if ok {
|
||||
ac.cache[path] = {
|
||||
@ -256,6 +294,29 @@ get_model :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Model {
|
||||
return model
|
||||
}
|
||||
|
||||
get_shader :: proc(
|
||||
assetman: ^Asset_Manager,
|
||||
vs_path: cstring,
|
||||
ps_path: cstring,
|
||||
location_set: Shader_Location_Set,
|
||||
) -> Loaded_Shader {
|
||||
loaded_shader, _, result := assetcache_fetch_or_load(&assetman.shaders, vs_path, ps_path)
|
||||
|
||||
if location_set > loaded_shader.location_set || result == .Loaded || result == .Reloaded {
|
||||
loaded_shader.location_set = location_set
|
||||
loaded_shader.locations = {}
|
||||
|
||||
for location in location_set {
|
||||
loaded_shader.locations[location] = rl.GetShaderLocation(
|
||||
loaded_shader.shader,
|
||||
SHADER_LOCATION_NAMES[location],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return loaded_shader
|
||||
}
|
||||
|
||||
null_bvhs: []bvh.BVH
|
||||
|
||||
get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> Loaded_BVH {
|
||||
@ -702,6 +763,7 @@ shutdown :: proc(assetman: ^Asset_Manager) {
|
||||
|
||||
assetcache_destroy(&assetman.textures)
|
||||
assetcache_destroy(&assetman.models)
|
||||
assetcache_destroy(&assetman.shaders)
|
||||
assetcache_destroy(&assetman.curves_1d)
|
||||
assetcache_destroy(&assetman.curves_2d)
|
||||
|
||||
|
@ -26,6 +26,7 @@ import "game:halfedge"
|
||||
import "game:physics"
|
||||
import "game:physics/bvh"
|
||||
import "game:physics/collision"
|
||||
import "game:render"
|
||||
import "libs:tracy"
|
||||
import "ui"
|
||||
import rl "vendor:raylib"
|
||||
@ -777,7 +778,9 @@ draw :: proc() {
|
||||
|
||||
if !g_mem.editor {
|
||||
car_matrix := rl.QuaternionToMatrix(car_body.q)
|
||||
car_model.transform = car_matrix
|
||||
car_matrix =
|
||||
(auto_cast linalg.matrix4_translate_f32(physics.body_get_shape_pos(car_body))) *
|
||||
car_matrix
|
||||
|
||||
if !runtime_world.pause {
|
||||
if runtime_world.rewind_simulation {
|
||||
@ -796,7 +799,30 @@ draw :: proc() {
|
||||
}
|
||||
}
|
||||
|
||||
rl.DrawModel(car_model, physics.body_get_shape_pos(car_body), 1, rl.WHITE)
|
||||
basic_shader := assets.get_shader(
|
||||
&g_mem.assetman,
|
||||
"assets/shaders/lit_vs.glsl",
|
||||
"assets/shaders/lit_ps.glsl",
|
||||
{.Ambient, .LightDir},
|
||||
)
|
||||
light_dir := linalg.normalize(rl.Vector3{1, -1, 0})
|
||||
ambient := linalg.normalize(rl.Vector3{0.1, 0.1, 0.1})
|
||||
rl.SetShaderValue(
|
||||
basic_shader.shader,
|
||||
basic_shader.locations[.LightDir],
|
||||
&light_dir,
|
||||
.VEC3,
|
||||
)
|
||||
rl.SetShaderValue(
|
||||
basic_shader.shader,
|
||||
basic_shader.locations[.Ambient],
|
||||
&ambient,
|
||||
.VEC3,
|
||||
)
|
||||
|
||||
render.draw_model(car_model, basic_shader.shader, car_matrix)
|
||||
|
||||
render.draw_point_light(0, 2, rl.YELLOW)
|
||||
}
|
||||
|
||||
{
|
||||
@ -1158,6 +1184,8 @@ game_memory_size :: proc() -> int {
|
||||
game_hot_reloaded :: proc(mem: rawptr) {
|
||||
g_mem = (^Game_Memory)(mem)
|
||||
|
||||
render.init()
|
||||
|
||||
g_mem.runtime_world.orbit_camera.distance = 4
|
||||
}
|
||||
|
||||
|
34
game/render/render.odin
Normal file
34
game/render/render.odin
Normal file
@ -0,0 +1,34 @@
|
||||
package render
|
||||
|
||||
import gl "vendor:OpenGL"
|
||||
import glfw "vendor:glfw"
|
||||
import rl "vendor:raylib"
|
||||
import rlgl "vendor:raylib/rlgl"
|
||||
|
||||
init :: proc() {
|
||||
gl.load_up_to(3, 3, glfw.gl_set_proc_address)
|
||||
}
|
||||
|
||||
draw_model :: proc(model: rl.Model, shader: rl.Shader, transform: rl.Matrix) {
|
||||
model := model
|
||||
for i in 0 ..< model.materialCount {
|
||||
model.materials[i].shader = shader
|
||||
}
|
||||
model.transform = transform
|
||||
|
||||
rl.DrawModel(model, rl.Vector3{}, 1, rl.WHITE)
|
||||
}
|
||||
|
||||
draw_point_light :: proc(pos: rl.Vector3, radius: f32, color: rl.Color) {
|
||||
rlgl.DrawRenderBatchActive()
|
||||
|
||||
gl.StencilFunc(gl.ALWAYS, 1, 0)
|
||||
defer gl.StencilFunc(gl.ALWAYS, 0, 0)
|
||||
|
||||
rlgl.SetCullFace(.FRONT)
|
||||
rl.DrawSphere(pos, radius, color)
|
||||
|
||||
rlgl.DrawRenderBatchActive()
|
||||
rlgl.SetCullFace(.BACK)
|
||||
// rl.DrawMesh(mesh, rl.LoadMaterialDefault(), transform)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user