1
Fork 0

odin(sdl-opengl-rendering): Use a VAO

This commit is contained in:
prescientmoon 2025-03-30 16:41:14 +02:00
parent 41fdea4be2
commit 411d5d1ccb
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
3 changed files with 55 additions and 36 deletions
odin/sdl-opengl-rendering/src

View file

@ -1,7 +1,9 @@
#version 140 #version 330
out vec4 LFragment; out vec4 FragColor;
in vec4 vertexColor;
void main() { void main() {
LFragment = vec4( 1.0, 1.0, 1.0, 1.0 ); FragColor = vertexColor;
} }

View file

@ -9,22 +9,27 @@ State :: struct {
window: ^sdl3.Window, window: ^sdl3.Window,
program: u32, program: u32,
vertex_pos_location: u32, vertex_pos_location: u32,
vao: u32,
vbo: u32, vbo: u32,
ibo: u32, ibo: u32,
wireframe: bool,
} }
init :: proc() -> (state: State, ok: bool) { init :: proc() -> (state: State, ok: bool) {
GL_MAJOR :: 3 GL_MAJOR :: 3
GL_MINOR :: 1 GL_MINOR :: 3
sdl3.Init(sdl3.InitFlags{.VIDEO}) or_return sdl3.Init(sdl3.InitFlags{.VIDEO}) or_return
sdl3.GL_SetAttribute(.CONTEXT_MAJOR_VERSION, GL_MAJOR) or_return sdl3.GL_SetAttribute(.CONTEXT_MAJOR_VERSION, GL_MAJOR) or_return
sdl3.GL_SetAttribute(.CONTEXT_MINOR_VERSION, GL_MINOR) or_return sdl3.GL_SetAttribute(.CONTEXT_MINOR_VERSION, GL_MINOR) or_return
sdl3.GL_SetAttribute(.CONTEXT_PROFILE_MASK, c.int(sdl3.GL_CONTEXT_PROFILE_CORE)) or_return sdl3.GL_SetAttribute(.CONTEXT_PROFILE_MASK, c.int(sdl3.GL_CONTEXT_PROFILE_CORE)) or_return
sdl3.GL_SetSwapInterval(1) // vsync
state.window = sdl3.CreateWindow("SDL visual experiment", 640, 480, {.FULLSCREEN, .OPENGL}) state.window = sdl3.CreateWindow("SDL visual experiment", 640, 480, {.FULLSCREEN, .OPENGL})
(state.window != nil) or_return (state.window != nil) or_return
sdl3.StartTextInput(state.window) or_return
gl_ctx := sdl3.GL_CreateContext(state.window) gl_ctx := sdl3.GL_CreateContext(state.window)
(gl_ctx != nil) or_return (gl_ctx != nil) or_return
@ -36,35 +41,48 @@ init :: proc() -> (state: State, ok: bool) {
) or_return ) or_return
// log.debug("Doing Opengl stuff") // log.debug("Doing Opengl stuff")
vertex_pos_location := OpenGL.GetAttribLocation(state.program, "LVertexPos2D") vertex_pos_location := OpenGL.GetAttribLocation(state.program, "aPos")
(vertex_pos_location != -1) or_return (vertex_pos_location != -1) or_return
state.vertex_pos_location = u32(vertex_pos_location) state.vertex_pos_location = u32(vertex_pos_location)
OpenGL.ClearColor(0, 0, 0, 1) OpenGL.ClearColor(0, 0, 0, 1)
// VBO data // VBO data
vertex_data := [?]f32{-0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5} vertex_data := 2 * [?]f32{-0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5}
vbos: [1]u32
// IBO data // IBO data
index_data := [?]u32{0, 1, 2, 3} index_data := [?]u32{0, 1, 2, 3}
ibos: [1]u32
OpenGL.GenVertexArrays(1, &state.vao)
OpenGL.BindVertexArray(state.vao)
//Create VBO //Create VBO
OpenGL.GenBuffers(1, auto_cast &vbos) OpenGL.GenBuffers(1, &state.vbo)
OpenGL.BindBuffer(OpenGL.ARRAY_BUFFER, vbos[0]) OpenGL.BindBuffer(OpenGL.ARRAY_BUFFER, state.vbo)
OpenGL.BufferData(OpenGL.ARRAY_BUFFER, 2 * 4 * size_of(f32), &vertex_data, OpenGL.STATIC_DRAW) OpenGL.BufferData(OpenGL.ARRAY_BUFFER, 2 * 4 * size_of(f32), &vertex_data, OpenGL.STATIC_DRAW)
state.vbo = vbos[0]
OpenGL.GenBuffers(1, auto_cast &ibos) OpenGL.EnableVertexAttribArray(state.vertex_pos_location)
OpenGL.BindBuffer(OpenGL.ELEMENT_ARRAY_BUFFER, ibos[0]) OpenGL.VertexAttribPointer(
state.vertex_pos_location,
2,
OpenGL.FLOAT,
false,
2 * size_of(f32),
0,
)
OpenGL.GenBuffers(1, auto_cast &state.ibo)
OpenGL.BindBuffer(OpenGL.ELEMENT_ARRAY_BUFFER, state.ibo)
OpenGL.BufferData( OpenGL.BufferData(
OpenGL.ELEMENT_ARRAY_BUFFER, OpenGL.ELEMENT_ARRAY_BUFFER,
4 * size_of(u32), 4 * size_of(u32),
&index_data, &index_data,
OpenGL.STATIC_DRAW, OpenGL.STATIC_DRAW,
) )
state.ibo = ibos[0]
OpenGL.BindVertexArray(0)
OpenGL.DisableVertexAttribArray(state.vertex_pos_location)
return state, true return state, true
} }
@ -75,25 +93,19 @@ render :: proc(state: State) {
OpenGL.UseProgram(state.program) OpenGL.UseProgram(state.program)
defer OpenGL.UseProgram(0) defer OpenGL.UseProgram(0)
OpenGL.EnableVertexAttribArray(state.vertex_pos_location) if state.wireframe {
defer OpenGL.DisableVertexAttribArray(state.vertex_pos_location) OpenGL.PolygonMode(OpenGL.FRONT_AND_BACK, OpenGL.LINE)
} else {
OpenGL.PolygonMode(OpenGL.FRONT_AND_BACK, OpenGL.FILL)
}
OpenGL.BindBuffer(OpenGL.ARRAY_BUFFER, state.vbo) OpenGL.BindVertexArray(state.vao)
OpenGL.VertexAttribPointer(
state.vertex_pos_location,
2,
OpenGL.FLOAT,
false,
2 * size_of(f32),
0,
)
OpenGL.BindBuffer(OpenGL.ELEMENT_ARRAY_BUFFER, state.ibo)
OpenGL.DrawElements(OpenGL.TRIANGLE_FAN, 4, OpenGL.UNSIGNED_INT, nil) OpenGL.DrawElements(OpenGL.TRIANGLE_FAN, 4, OpenGL.UNSIGNED_INT, nil)
} }
close :: proc(state: State) { close :: proc(state: State) {
OpenGL.DeleteProgram(state.program) OpenGL.DeleteProgram(state.program)
_ = sdl3.StopTextInput(state.window)
sdl3.DestroyWindow(state.window) sdl3.DestroyWindow(state.window)
sdl3.Quit() sdl3.Quit()
} }
@ -105,23 +117,25 @@ main :: proc() {
defer close(state) defer close(state)
quit := false quit := false
log.debug("Created context")
for !quit { for !quit {
sdl3.StartTextInput(state.window) or_break
event: sdl3.Event event: sdl3.Event
for sdl3.PollEvent(&event) { for sdl3.PollEvent(&event) {
#partial switch event.type { #partial switch event.type {
case .WINDOW_RESIZED:
OpenGL.Viewport(0, 0, event.window.data1, event.window.data2)
case .QUIT: case .QUIT:
quit = true quit = true
case .TEXT_INPUT:
switch ([^]u8)(event.text.text)[0] {
case 'w':
state.wireframe = !state.wireframe
}
log.debug(event.text)
} }
} }
render(state) render(state)
sdl3.GL_SwapWindow(state.window) sdl3.GL_SwapWindow(state.window)
sdl3.StopTextInput(state.window) or_break
} }
} }
// //Handle keypress
// else if( e.type == SDL_EVENT_TEXT_INPUT )
// handleKeys( e.text.text[ 0 ] );

View file

@ -1,7 +1,10 @@
#version 140 #version 330
in vec2 LVertexPos2D; in vec2 aPos;
out vec4 vertexColor;
void main() { void main() {
gl_Position = vec4(LVertexPos2D.x, LVertexPos2D.y, 0, 1 ); gl_Position = vec4(aPos.x, aPos.y, 0, 1);
vertexColor = vec4((aPos.x + 1) / 2, (aPos.y + 1) / 2, 1, 1);
} }