diff --git a/odin/sdl-opengl-rendering/src/frag.glsl b/odin/sdl-opengl-rendering/src/frag.glsl
index e5daf9f..58ae6e0 100644
--- a/odin/sdl-opengl-rendering/src/frag.glsl
+++ b/odin/sdl-opengl-rendering/src/frag.glsl
@@ -1,7 +1,9 @@
-#version 140
+#version 330
 
-out vec4 LFragment;
+out vec4 FragColor;
+
+in vec4 vertexColor;
 
 void main() {
-  LFragment = vec4( 1.0, 1.0, 1.0, 1.0 );
+  FragColor = vertexColor;
 }
diff --git a/odin/sdl-opengl-rendering/src/main.odin b/odin/sdl-opengl-rendering/src/main.odin
index 07c249d..3b4a6f6 100644
--- a/odin/sdl-opengl-rendering/src/main.odin
+++ b/odin/sdl-opengl-rendering/src/main.odin
@@ -9,22 +9,27 @@ State :: struct {
 	window:              ^sdl3.Window,
 	program:             u32,
 	vertex_pos_location: u32,
+	vao:                 u32,
 	vbo:                 u32,
 	ibo:                 u32,
+	wireframe:           bool,
 }
 
 init :: proc() -> (state: State, ok: bool) {
 	GL_MAJOR :: 3
-	GL_MINOR :: 1
+	GL_MINOR :: 3
 
 	sdl3.Init(sdl3.InitFlags{.VIDEO}) 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_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 != nil) or_return
 
+	sdl3.StartTextInput(state.window) or_return
+
 	gl_ctx := sdl3.GL_CreateContext(state.window)
 	(gl_ctx != nil) or_return
 
@@ -36,35 +41,48 @@ init :: proc() -> (state: State, ok: bool) {
 	) or_return
 	// 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
 	state.vertex_pos_location = u32(vertex_pos_location)
 
 	OpenGL.ClearColor(0, 0, 0, 1)
 
 	// VBO data
-	vertex_data := [?]f32{-0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5}
-	vbos: [1]u32
+	vertex_data := 2 * [?]f32{-0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5}
 
 	// IBO data
 	index_data := [?]u32{0, 1, 2, 3}
-	ibos: [1]u32
+
+
+	OpenGL.GenVertexArrays(1, &state.vao)
+	OpenGL.BindVertexArray(state.vao)
 
 	//Create VBO
-	OpenGL.GenBuffers(1, auto_cast &vbos)
-	OpenGL.BindBuffer(OpenGL.ARRAY_BUFFER, vbos[0])
+	OpenGL.GenBuffers(1, &state.vbo)
+	OpenGL.BindBuffer(OpenGL.ARRAY_BUFFER, state.vbo)
 	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.BindBuffer(OpenGL.ELEMENT_ARRAY_BUFFER, ibos[0])
+	OpenGL.EnableVertexAttribArray(state.vertex_pos_location)
+	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.ELEMENT_ARRAY_BUFFER,
 		4 * size_of(u32),
 		&index_data,
 		OpenGL.STATIC_DRAW,
 	)
-	state.ibo = ibos[0]
+
+	OpenGL.BindVertexArray(0)
+	OpenGL.DisableVertexAttribArray(state.vertex_pos_location)
 
 	return state, true
 }
@@ -75,25 +93,19 @@ render :: proc(state: State) {
 	OpenGL.UseProgram(state.program)
 	defer OpenGL.UseProgram(0)
 
-	OpenGL.EnableVertexAttribArray(state.vertex_pos_location)
-	defer OpenGL.DisableVertexAttribArray(state.vertex_pos_location)
+	if state.wireframe {
+		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.VertexAttribPointer(
-		state.vertex_pos_location,
-		2,
-		OpenGL.FLOAT,
-		false,
-		2 * size_of(f32),
-		0,
-	)
-
-	OpenGL.BindBuffer(OpenGL.ELEMENT_ARRAY_BUFFER, state.ibo)
+	OpenGL.BindVertexArray(state.vao)
 	OpenGL.DrawElements(OpenGL.TRIANGLE_FAN, 4, OpenGL.UNSIGNED_INT, nil)
 }
 
 close :: proc(state: State) {
 	OpenGL.DeleteProgram(state.program)
+	_ = sdl3.StopTextInput(state.window)
 	sdl3.DestroyWindow(state.window)
 	sdl3.Quit()
 }
@@ -105,23 +117,25 @@ main :: proc() {
 	defer close(state)
 
 	quit := false
-	log.debug("Created context")
 
 	for !quit {
-		sdl3.StartTextInput(state.window) or_break
 		event: sdl3.Event
 		for sdl3.PollEvent(&event) {
 			#partial switch event.type {
+			case .WINDOW_RESIZED:
+				OpenGL.Viewport(0, 0, event.window.data1, event.window.data2)
 			case .QUIT:
 				quit = true
+			case .TEXT_INPUT:
+				switch ([^]u8)(event.text.text)[0] {
+				case 'w':
+					state.wireframe = !state.wireframe
+				}
+				log.debug(event.text)
 			}
 		}
 
 		render(state)
 		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 ] );
diff --git a/odin/sdl-opengl-rendering/src/vert.glsl b/odin/sdl-opengl-rendering/src/vert.glsl
index a419f7c..3273106 100644
--- a/odin/sdl-opengl-rendering/src/vert.glsl
+++ b/odin/sdl-opengl-rendering/src/vert.glsl
@@ -1,7 +1,10 @@
-#version 140
+#version 330
 
-in vec2 LVertexPos2D;
+in vec2 aPos;
+
+out vec4 vertexColor;
 
 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);
 }