Work on passes/pipeline, render targets

This commit is contained in:
2026-01-26 20:45:29 +01:00
parent 6b2d76bd8a
commit bd4b81d434
7 changed files with 764 additions and 160 deletions

View File

@@ -6,44 +6,134 @@ import "vendor:stb/image"
import "core:fmt"
Texture :: struct {
width, height, channels, depth: u32,
width, height, depth, channels: u16,
format: Texture_Format,
filter_mode: Texture_Filter_Mode,
wrap_mode: Texture_Wrap_Mode,
is_depth: bool,
backend: Texture_Backend,
}
Texture_Format :: enum {
RGBA8,
RGBA16F,
R11G11B10F,
R8,
R16F,
R32F,
Depth16,
Depth24,
Depth32F,
Depth24_Stencil8,
Depth32F_Stencil8,
}
Render_Target :: struct {
color_texture, depth_texture: ^Texture,
backend: Render_Target_Backend,
}
Texture_Filter_Mode :: enum {
Nearest,
Linear,
Nearest_MipMap,
Linear_MipMap,
}
Texture_Wrap_Mode :: enum {
Clamp,
Repeat,
Mirror,
}
create_texture :: proc {
create_texture_from_path,
create_texture_raw,
}
create_texture_from_path :: proc(renderer: ^Renderer, path: string) -> (Texture, bool) {
width, height, depth, channels: c.int
path_cstr := strings.clone_to_cstring(path)
defer delete(path_cstr)
image.set_flip_vertically_on_load(1) // NOTE: SS - This should not necessarily happen on all graphics-apis.
data := image.load(path_cstr, &width, &height, &channels, desired_channels = 0)
if data == nil {
return {}, false
}
depth = 8
create_texture_from_path :: proc(renderer: ^Renderer, path: string, filter_mode := Texture_Filter_Mode.Linear, wrap_mode := Texture_Wrap_Mode.Repeat) -> (Texture, bool) {
width, height, channels, depth: c.int
path_cstr := strings.clone_to_cstring(path)
defer delete(path_cstr)
image.set_flip_vertically_on_load(1)
data := image.load(path_cstr, &width, &height, &channels, desired_channels = 0)
if data == nil {
return {}, false
}
depth = 8
t: Texture
t.width = u16(width)
t.height = u16(height)
t.filter_mode = filter_mode
t.wrap_mode = wrap_mode
t.depth = u16(depth)
t.channels = u16(channels)
switch channels {
case 1: {
t.format = .R8
}
case 3: {
t.format = .RGBA8
}
case 4: {
t.format = .RGBA8
}
case: {
t.format = .RGBA8
}
}
when RENDER_BACKEND_OPENGL {
if !opengl_load_texture(renderer, &t, data) {
return {}, false
}
}
return t, true
}
create_texture_raw :: proc(renderer: ^Renderer, width, height: u16, format: Texture_Format, filter_mode: Texture_Filter_Mode, wrap_mode: Texture_Wrap_Mode, is_depth: bool = false) -> (Texture, bool) { t: Texture
t.width = width
t.height = height
t.format = format
t.filter_mode = filter_mode
t.wrap_mode = wrap_mode
t.is_depth = is_depth
t: Texture
t.width = u32(width)
t.height = u32(height)
t.channels = u32(channels)
t.depth = u32(depth)
when RENDER_BACKEND_OPENGL {
if !opengl_load_texture(renderer, &t, data) {
if !opengl_load_texture(renderer, &t, nil) {
return {}, false
}
} else {
#assert(false)
}
return t, true
}
create_render_target :: proc(renderer: ^Renderer, color_texture, depth_texture: ^Texture) -> (Render_Target, bool) {
rt: Render_Target
rt.color_texture = color_texture
rt.depth_texture = depth_texture
when RENDER_BACKEND_OPENGL {
if !opengl_create_render_target(renderer, &rt) {
return {}, false
}
}
else {
#assert(false)
}
return t, true
return rt, true
}
delete_texture :: proc(renderer: ^Renderer, texture: ^Texture) {
when RENDER_BACKEND_OPENGL {
opengl_delete_texture(renderer, texture)