Initial commit.
This commit is contained in:
90
renderer.odin
Normal file
90
renderer.odin
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package renderer
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
RENDER_BACKEND_OPENGL :: #config(RENDER_BACKEND_OPENGL, false)
|
||||||
|
RENDER_BACKEND_VULKAN :: #config(RENDER_BACKEND_VULKAN, false)
|
||||||
|
RENDER_BACKEND_DIRECTX11 :: #config(RENDER_BACKEND_DIRECTX11, false)
|
||||||
|
RENDER_BACKEND_METAL :: #config(RENDER_BACKEND_METAL, false)
|
||||||
|
|
||||||
|
Renderer :: struct {
|
||||||
|
api: Renderer_API,
|
||||||
|
|
||||||
|
viewport: Viewport,
|
||||||
|
surface_ptr: rawptr,
|
||||||
|
backend: rawptr,
|
||||||
|
}
|
||||||
|
|
||||||
|
Viewport :: struct {
|
||||||
|
x, y, width, height: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer_API :: enum {
|
||||||
|
OpenGL,
|
||||||
|
Vulkan,
|
||||||
|
DirectX11,
|
||||||
|
Metal,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
create :: proc(surface_ptr: rawptr) -> (^Renderer, bool) {
|
||||||
|
renderer := new(Renderer)
|
||||||
|
renderer.surface_ptr = surface_ptr
|
||||||
|
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
if !opengl_init(renderer) {
|
||||||
|
fmt.printfln("Failed to initialize OpenGL.")
|
||||||
|
destroy(renderer)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
destroy(renderer)
|
||||||
|
|
||||||
|
fmt.printfln("Unhandled backend or no backend selected.")
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: SS - Init renderer using 'api'.
|
||||||
|
return renderer, true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_viewport :: proc(renderer: ^Renderer, x, y, width, height: u16) {
|
||||||
|
fmt.printfln("Setting viewport to %v:%v, %vx%v.", x, y, width, height)
|
||||||
|
|
||||||
|
renderer.viewport = {
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
width = width,
|
||||||
|
height = height,
|
||||||
|
}
|
||||||
|
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
opengl_viewport_changed(renderer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_clear_color :: proc(renderer: ^Renderer, color: [3]u8) {
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
opengl_set_clear_color(renderer, color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_frame :: proc(renderer: ^Renderer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
swap_buffers :: proc(renderer: ^Renderer) {
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
opengl_swap_buffers(renderer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy :: proc(renderer: ^Renderer) {
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
opengl_destroy(renderer)
|
||||||
|
}
|
||||||
|
|
||||||
|
free(renderer)
|
||||||
|
renderer^ = {}
|
||||||
|
}
|
||||||
93
renderer_backend_opengl_windows.odin
Normal file
93
renderer_backend_opengl_windows.odin
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package renderer
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import gl "vendor:OpenGL"
|
||||||
|
import win "core:sys/windows"
|
||||||
|
|
||||||
|
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
Backend_OpenGL_Windows :: struct {
|
||||||
|
hwnd: win.HWND,
|
||||||
|
hdc: win.HDC,
|
||||||
|
gl_context: win.HGLRC,
|
||||||
|
}
|
||||||
|
|
||||||
|
backend: Backend_OpenGL_Windows
|
||||||
|
|
||||||
|
opengl_init :: proc(renderer: ^Renderer) -> bool {
|
||||||
|
renderer.backend = &backend
|
||||||
|
|
||||||
|
backend.hwnd = win.HWND(renderer.surface_ptr)
|
||||||
|
backend.hdc = win.GetDC(backend.hwnd)
|
||||||
|
|
||||||
|
pfd := win.PIXELFORMATDESCRIPTOR {
|
||||||
|
nSize = size_of(win.PIXELFORMATDESCRIPTOR),
|
||||||
|
nVersion = 1,
|
||||||
|
dwFlags = win.PFD_DRAW_TO_WINDOW | win.PFD_SUPPORT_OPENGL | win.PFD_DOUBLEBUFFER,
|
||||||
|
iPixelType = win.PFD_TYPE_RGBA,
|
||||||
|
cColorBits = 32,
|
||||||
|
cDepthBits = 24,
|
||||||
|
cStencilBits = 8,
|
||||||
|
iLayerType = win.PFD_MAIN_PLANE,
|
||||||
|
}
|
||||||
|
|
||||||
|
format_index := win.ChoosePixelFormat(backend.hdc, &pfd)
|
||||||
|
assert(format_index != 0, "ChoosePixelFormat failed")
|
||||||
|
|
||||||
|
set_pixel_format_ok := win.SetPixelFormat(backend.hdc, format_index, &pfd)
|
||||||
|
assert(set_pixel_format_ok == win.TRUE, "SetPixelFormat failed")
|
||||||
|
|
||||||
|
backend.gl_context = win.wglCreateContext(backend.hdc)
|
||||||
|
assert(backend.gl_context != nil, "Failed to create OpenGL context")
|
||||||
|
|
||||||
|
win.wglMakeCurrent(backend.hdc, backend.gl_context)
|
||||||
|
// fmt.printfln("GL Context: %v", backend.gl_context)
|
||||||
|
|
||||||
|
gl.load_up_to(3, 3, proc(p: rawptr, name: cstring) {
|
||||||
|
addr := win.wglGetProcAddress(name)
|
||||||
|
if addr == nil {
|
||||||
|
dll := win.LoadLibraryW(win.utf8_to_wstring("opengl32.dll"))
|
||||||
|
addr = win.GetProcAddress(dll, name)
|
||||||
|
}
|
||||||
|
(^rawptr)(p)^ = addr
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
opengl_swap_buffers(renderer)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_viewport_changed :: proc(renderer: ^Renderer) {
|
||||||
|
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
|
gl.Viewport(
|
||||||
|
i32(renderer.viewport.x),
|
||||||
|
i32(renderer.viewport.y),
|
||||||
|
i32(renderer.viewport.width),
|
||||||
|
i32(renderer.viewport.height)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_set_clear_color :: proc(renderer: ^Renderer, color: [3]u8) {
|
||||||
|
gl.ClearColor(
|
||||||
|
f32(color.r) / f32(max(u8)),
|
||||||
|
f32(color.g) / f32(max(u8)),
|
||||||
|
f32(color.b) / f32(max(u8)),
|
||||||
|
1.0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_swap_buffers :: proc(renderer: ^Renderer) {
|
||||||
|
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||||
|
win.SwapBuffers(backend.hdc)
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_destroy :: proc(renderer: ^Renderer) {
|
||||||
|
win.wglMakeCurrent(nil, nil)
|
||||||
|
win.wglDeleteContext(backend.gl_context)
|
||||||
|
win.ReleaseDC(backend.hwnd, backend.hdc)
|
||||||
|
|
||||||
|
backend = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user