Successfully rendered a quad!
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#+private
|
||||
package renderer
|
||||
|
||||
import "core:strings"
|
||||
import "core:fmt"
|
||||
import gl "vendor:OpenGL"
|
||||
import win "core:sys/windows"
|
||||
@@ -13,6 +15,9 @@ when RENDER_BACKEND_OPENGL {
|
||||
}
|
||||
|
||||
backend: Backend_OpenGL_Windows
|
||||
|
||||
OPENGL_MAJOR :: 3
|
||||
OPENGL_MINOR :: 3
|
||||
|
||||
opengl_init :: proc(renderer: ^Renderer) -> bool {
|
||||
renderer.backend = &backend
|
||||
@@ -37,11 +42,28 @@ when RENDER_BACKEND_OPENGL {
|
||||
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")
|
||||
temp_context := win.wglCreateContext(backend.hdc)
|
||||
assert(temp_context != nil, "Failed to create temp OpenGL context")
|
||||
win.wglMakeCurrent(backend.hdc, temp_context)
|
||||
|
||||
win.wglCreateContextAttribsARB = transmute(win.CreateContextAttribsARBType)win.wglGetProcAddress("wglCreateContextAttribsARB")
|
||||
assert(win.wglCreateContextAttribsARB != nil, "wglCreateContextAttribsARB not available")
|
||||
|
||||
attribs := [?]i32 {
|
||||
win.WGL_CONTEXT_MAJOR_VERSION_ARB, OPENGL_MAJOR,
|
||||
win.WGL_CONTEXT_MINOR_VERSION_ARB, OPENGL_MINOR,
|
||||
win.WGL_CONTEXT_PROFILE_MASK_ARB,
|
||||
win.WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0
|
||||
}
|
||||
|
||||
backend.gl_context = win.wglCreateContextAttribsARB(backend.hdc, nil, raw_data(&attribs))
|
||||
assert(backend.gl_context != nil, fmt.tprintf("Failed to create OpenGL %v.%v core context", OPENGL_MAJOR, OPENGL_MINOR))
|
||||
|
||||
win.wglMakeCurrent(nil, nil)
|
||||
win.wglDeleteContext(temp_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)
|
||||
@@ -52,14 +74,13 @@ when RENDER_BACKEND_OPENGL {
|
||||
(^rawptr)(p)^ = addr
|
||||
})
|
||||
|
||||
|
||||
opengl_swap_buffers(renderer)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
opengl_viewport_changed :: proc(renderer: ^Renderer) {
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
opengl_clear_screen(renderer)
|
||||
|
||||
gl.Viewport(
|
||||
i32(renderer.viewport.x),
|
||||
@@ -77,10 +98,14 @@ when RENDER_BACKEND_OPENGL {
|
||||
1.0
|
||||
)
|
||||
}
|
||||
|
||||
opengl_clear_screen :: proc(renderer: ^Renderer) {
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
}
|
||||
|
||||
opengl_swap_buffers :: proc(renderer: ^Renderer) {
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
win.SwapBuffers(backend.hdc)
|
||||
opengl_clear_screen(renderer)
|
||||
}
|
||||
|
||||
opengl_destroy :: proc(renderer: ^Renderer) {
|
||||
@@ -90,4 +115,123 @@ when RENDER_BACKEND_OPENGL {
|
||||
|
||||
backend = {}
|
||||
}
|
||||
|
||||
Mesh_Backend :: Mesh_OpenGL
|
||||
Shader_Backend :: Shader_OpenGL
|
||||
Shader_Program_Backend :: Shader_Program_OpenGL
|
||||
|
||||
Mesh_OpenGL :: struct {
|
||||
vbo, vao, ebo: u32,
|
||||
}
|
||||
|
||||
Shader_OpenGL :: struct {
|
||||
handle: u32,
|
||||
}
|
||||
|
||||
Shader_Program_OpenGL :: struct {
|
||||
handle: u32,
|
||||
}
|
||||
|
||||
opengl_create_mesh :: proc(renderer: ^Renderer, vertices: []Vertex, indices: []Index) -> (Mesh_OpenGL, bool) {
|
||||
fmt.printfln("OPENGL: Creating mesh from vertices: %v.", vertices)
|
||||
|
||||
m: Mesh_OpenGL
|
||||
|
||||
gl.GenVertexArrays(1, &m.vao)
|
||||
gl.GenBuffers(1, &m.vbo)
|
||||
gl.GenBuffers(1, &m.ebo)
|
||||
|
||||
gl.BindVertexArray(m.vao)
|
||||
{
|
||||
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.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.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 3 * size_of(f32), 0)
|
||||
gl.EnableVertexAttribArray(0)
|
||||
|
||||
}
|
||||
gl.BindVertexArray(0)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||
|
||||
return m, true
|
||||
}
|
||||
|
||||
opengl_create_shader :: proc(renderer: ^Renderer, type: Shader_Type, data: []u8) -> (Shader_OpenGL, bool) {
|
||||
handle: u32
|
||||
|
||||
switch type {
|
||||
case .Vertex: {
|
||||
handle = gl.CreateShader(gl.VERTEX_SHADER)
|
||||
}
|
||||
case .Fragment: {
|
||||
handle = gl.CreateShader(gl.FRAGMENT_SHADER)
|
||||
}
|
||||
}
|
||||
|
||||
assert(handle != 0)
|
||||
|
||||
src := strings.clone_to_cstring(transmute(string)data, context.allocator)
|
||||
defer delete(src)
|
||||
gl.ShaderSource(handle, 1, &src, nil)
|
||||
|
||||
gl.CompileShader(handle)
|
||||
|
||||
success: i32
|
||||
info_log: [512]u8
|
||||
gl.GetShaderiv(handle, gl.COMPILE_STATUS, &success)
|
||||
if success != 1 {
|
||||
gl.GetShaderInfoLog(handle, 512, nil, raw_data(&info_log))
|
||||
fmt.printfln("OPENGL: Failed to compile shader of type %v. Log: '%v'.", type, info_log)
|
||||
|
||||
return {}, false
|
||||
}
|
||||
|
||||
s: Shader_OpenGL
|
||||
s.handle = handle
|
||||
return s, true
|
||||
}
|
||||
|
||||
opengl_delete_shader :: proc(renderer: ^Renderer, shader: ^Shader) {
|
||||
gl.DeleteShader(shader.backend.handle)
|
||||
}
|
||||
|
||||
opengl_create_shader_program :: proc(renderer: ^Renderer, vertex_shader, fragment_shader: ^Shader) -> (Shader_Program_OpenGL, bool) {
|
||||
handle := gl.CreateProgram()
|
||||
|
||||
gl.AttachShader(handle, vertex_shader.backend.handle)
|
||||
gl.AttachShader(handle, fragment_shader.backend.handle)
|
||||
gl.LinkProgram(handle)
|
||||
|
||||
success: i32
|
||||
info_log: [512]u8
|
||||
gl.GetProgramiv(handle, gl.LINK_STATUS, &success)
|
||||
if success != 1 {
|
||||
gl.GetProgramInfoLog(handle, 512, nil, raw_data(&info_log))
|
||||
fmt.printfln("OPENGL: Failed to create shader-program. Log: '%v'.", info_log)
|
||||
|
||||
return {}, false
|
||||
}
|
||||
|
||||
s: Shader_Program_OpenGL
|
||||
s.handle = handle
|
||||
return s, true
|
||||
}
|
||||
|
||||
opengl_delete_shader_program :: proc(renderer: ^Renderer, shader_program: ^Shader_Program) {
|
||||
gl.DeleteProgram(shader_program.backend.handle)
|
||||
}
|
||||
|
||||
opengl_activate_material :: proc(material: ^Material) {
|
||||
gl.UseProgram(material.shader_program.backend.handle)
|
||||
}
|
||||
|
||||
opengl_draw_mesh :: proc(mesh: ^Mesh) {
|
||||
gl.BindVertexArray(mesh.backend.vao)
|
||||
assert(mesh.amount_of_indices < u32(max(i32)))
|
||||
gl.DrawElements(gl.TRIANGLES, i32(mesh.amount_of_indices), gl.UNSIGNED_INT, nil)
|
||||
gl.BindVertexArray(0)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user