Textured quad.
This commit is contained in:
@@ -2,5 +2,6 @@ package renderer
|
|||||||
|
|
||||||
Material :: struct {
|
Material :: struct {
|
||||||
shader_program: Shader_Program,
|
shader_program: Shader_Program,
|
||||||
|
texture: Texture, // Diffuse, normal etc later.
|
||||||
// uniforms, textures, etc.
|
// uniforms, textures, etc.
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,8 @@ Mesh :: struct {
|
|||||||
Mesh_Handle :: distinct u32
|
Mesh_Handle :: distinct u32
|
||||||
Buffer_Handle :: distinct u32
|
Buffer_Handle :: distinct u32
|
||||||
|
|
||||||
Vertex :: distinct [3]f32
|
|
||||||
Index :: distinct u32
|
|
||||||
|
|
||||||
|
create_mesh :: proc(renderer: ^Renderer, vertices: []f32, indices: []u32) -> (Mesh, bool) { // TODO: SS - Should probably return a Mesh_Handle.
|
||||||
create_mesh :: proc(renderer: ^Renderer, vertices: []Vertex, indices: []Index) -> (Mesh, bool) { // TODO: SS - Should probably return a Mesh_Handle.
|
|
||||||
mesh: Mesh
|
mesh: Mesh
|
||||||
|
|
||||||
if len(vertices) == 0 {
|
if len(vertices) == 0 {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package renderer
|
|||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
|
||||||
MAX_DRAW_COMMANDS_PER_PASS :: 4096
|
MAX_DRAW_COMMANDS_PER_PASS :: 1024
|
||||||
|
|
||||||
Pass :: struct {
|
Pass :: struct {
|
||||||
name: string,
|
name: string,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ set_pipeline :: proc(renderer: ^Renderer, passes: []^Pass) {
|
|||||||
pipeline.passes[pipeline.amount_of_passes] = pass
|
pipeline.passes[pipeline.amount_of_passes] = pass
|
||||||
pipeline.amount_of_passes += 1
|
pipeline.amount_of_passes += 1
|
||||||
|
|
||||||
log.infof("Successfully added pass '%v' to pipeline.", pass.name)
|
// log.infof("Successfully added pass '%v' to pipeline.", pass.name)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#+private
|
#+private
|
||||||
package renderer
|
package renderer
|
||||||
|
|
||||||
|
import "core:bytes"
|
||||||
|
import "core:slice"
|
||||||
|
import "core:image"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import gl "vendor:OpenGL"
|
import gl "vendor:OpenGL"
|
||||||
@@ -119,6 +122,7 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
Mesh_Backend :: Mesh_OpenGL
|
Mesh_Backend :: Mesh_OpenGL
|
||||||
Shader_Backend :: Shader_OpenGL
|
Shader_Backend :: Shader_OpenGL
|
||||||
Shader_Program_Backend :: Shader_Program_OpenGL
|
Shader_Program_Backend :: Shader_Program_OpenGL
|
||||||
|
Texture_Backend :: Texture_OpenGL
|
||||||
|
|
||||||
Mesh_OpenGL :: struct {
|
Mesh_OpenGL :: struct {
|
||||||
vbo, vao, ebo: u32,
|
vbo, vao, ebo: u32,
|
||||||
@@ -132,8 +136,12 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
handle: u32,
|
handle: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
opengl_create_mesh :: proc(renderer: ^Renderer, vertices: []Vertex, indices: []Index) -> (Mesh_OpenGL, bool) {
|
Texture_OpenGL :: struct {
|
||||||
fmt.printfln("OPENGL: Creating mesh from vertices: %v.", vertices)
|
handle: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_create_mesh :: proc(renderer: ^Renderer, vertices: []f32, indices: []u32) -> (Mesh_OpenGL, bool) {
|
||||||
|
// fmt.printfln("OPENGL: Creating mesh from vertices: %v.", vertices)
|
||||||
|
|
||||||
m: Mesh_OpenGL
|
m: Mesh_OpenGL
|
||||||
|
|
||||||
@@ -144,13 +152,19 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
gl.BindVertexArray(m.vao)
|
gl.BindVertexArray(m.vao)
|
||||||
{
|
{
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, m.vbo)
|
gl.BindBuffer(gl.ARRAY_BUFFER, m.vbo)
|
||||||
gl.BufferData(gl.ARRAY_BUFFER, len(vertices) * size_of(Vertex), raw_data(&vertices[0]), gl.STATIC_DRAW)
|
gl.BufferData(gl.ARRAY_BUFFER, len(vertices) * size_of(f32), raw_data(vertices), gl.STATIC_DRAW)
|
||||||
|
|
||||||
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, m.ebo)
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, m.ebo)
|
||||||
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices) * size_of(Index), raw_data(indices), gl.STATIC_DRAW)
|
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices) * size_of(u32), raw_data(indices), gl.STATIC_DRAW)
|
||||||
|
|
||||||
gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 3 * size_of(f32), 0)
|
gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 8 * size_of(f32), uintptr(0))
|
||||||
gl.EnableVertexAttribArray(0)
|
gl.EnableVertexAttribArray(0)
|
||||||
|
|
||||||
|
gl.VertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, 8 * size_of(f32), uintptr(3 * size_of(f32)))
|
||||||
|
gl.EnableVertexAttribArray(1)
|
||||||
|
|
||||||
|
gl.VertexAttribPointer(2, 2, gl.FLOAT, gl.FALSE, 8 * size_of(f32), uintptr(6 * size_of(f32)))
|
||||||
|
gl.EnableVertexAttribArray(2)
|
||||||
|
|
||||||
}
|
}
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
@@ -226,12 +240,83 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
|
|
||||||
opengl_activate_material :: proc(material: ^Material) {
|
opengl_activate_material :: proc(material: ^Material) {
|
||||||
gl.UseProgram(material.shader_program.backend.handle)
|
gl.UseProgram(material.shader_program.backend.handle)
|
||||||
|
|
||||||
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, material.texture.backend.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
opengl_draw_mesh :: proc(mesh: ^Mesh) {
|
opengl_draw_mesh :: proc(mesh: ^Mesh) {
|
||||||
gl.BindVertexArray(mesh.backend.vao)
|
gl.BindVertexArray(mesh.backend.vao)
|
||||||
assert(mesh.amount_of_indices < u32(max(i32)))
|
assert(mesh.amount_of_indices < u32(max(i32)))
|
||||||
gl.DrawElements(gl.TRIANGLES, i32(mesh.amount_of_indices), gl.UNSIGNED_INT, nil)
|
gl.DrawElements(gl.TRIANGLES, i32(mesh.amount_of_indices), gl.UNSIGNED_INT, nil)
|
||||||
gl.BindVertexArray(0)
|
}
|
||||||
|
|
||||||
|
opengl_load_texture :: proc(renderer: ^Renderer, t: ^Texture, pixels: rawptr) -> bool {
|
||||||
|
handle: u32
|
||||||
|
gl.GenTextures(1, &handle)
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, handle)
|
||||||
|
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
|
|
||||||
|
type := gl.UNSIGNED_BYTE
|
||||||
|
switch t.depth {
|
||||||
|
case 8: type = gl.UNSIGNED_BYTE
|
||||||
|
case 16: type = gl.UNSIGNED_SHORT
|
||||||
|
case 32: type = gl.UNSIGNED_INT
|
||||||
|
}
|
||||||
|
|
||||||
|
format := gl.RGBA
|
||||||
|
switch t.channels {
|
||||||
|
case 1: format = gl.RED
|
||||||
|
case 2: format = gl.RG
|
||||||
|
case 3: format = gl.RGB
|
||||||
|
case 4: format = gl.RGBA
|
||||||
|
}
|
||||||
|
|
||||||
|
internal := gl.RGBA8
|
||||||
|
|
||||||
|
if t.depth == 8 {
|
||||||
|
switch t.channels {
|
||||||
|
case 1: internal = gl.R8
|
||||||
|
case 2: internal = gl.RG8
|
||||||
|
case 3: internal = gl.RGB8
|
||||||
|
case 4: internal = gl.RGBA8
|
||||||
|
}
|
||||||
|
} else if t.depth == 16 {
|
||||||
|
switch t.channels {
|
||||||
|
case 1: internal = gl.R16
|
||||||
|
case 2: internal = gl.RG16
|
||||||
|
case 3: internal = gl.RGB16
|
||||||
|
case 4: internal = gl.RGBA16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// bytes.reverse(bytes.buffer_to_bytes(img.pixels))
|
||||||
|
|
||||||
|
gl.TexImage2D(
|
||||||
|
target = gl.TEXTURE_2D,
|
||||||
|
level = 0,
|
||||||
|
internalformat = i32(internal),
|
||||||
|
width = i32(t.width),
|
||||||
|
height = i32(t.height),
|
||||||
|
border = 0,
|
||||||
|
format = u32(format),
|
||||||
|
type = u32(type),
|
||||||
|
pixels = pixels,
|
||||||
|
// pixels = &pixels[0]
|
||||||
|
// pixels = &bytes.reverse(bytes.buffer_to_bytes(&img.pixels))[0]
|
||||||
|
)
|
||||||
|
|
||||||
|
gl.GenerateMipmap(gl.TEXTURE_2D)
|
||||||
|
|
||||||
|
t.backend = Texture_OpenGL { handle = handle }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_delete_texture :: proc(renderer: ^Renderer, t: ^Texture) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
54
texture.odin
Normal file
54
texture.odin
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package renderer
|
||||||
|
|
||||||
|
import "core:strings"
|
||||||
|
import "core:c"
|
||||||
|
import "vendor:stb/image"
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
Texture :: struct {
|
||||||
|
width, height, channels, depth: u32,
|
||||||
|
backend: Texture_Backend,
|
||||||
|
}
|
||||||
|
|
||||||
|
create_texture :: proc {
|
||||||
|
create_texture_from_path,
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return {}, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#assert(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, true
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_texture :: proc(renderer: ^Renderer, texture: ^Texture) {
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
opengl_delete_texture(renderer, texture)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#assert(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user