1package main
2
3import "core:fmt"
4import glm "core:math/linalg/glsl"
5import "core:time"
6
7import SDL "vendor:sdl2"
8import gl "vendor:OpenGL"
9
10GL_VERSION_MAJOR :: 3
11GL_VERSION_MINOR :: 3
12
13main :: proc() {
14 WINDOW_WIDTH :: 854
15 WINDOW_HEIGHT :: 480
16
17 SDL.Init({.VIDEO})
18 defer SDL.Quit()
19
20 window := SDL.CreateWindow("Odin SDL2 Demo", SDL.WINDOWPOS_UNDEFINED, SDL.WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, {.OPENGL})
21 if window == nil {
22 fmt.eprintln("Failed to create window")
23 return
24 }
25 defer SDL.DestroyWindow(window)
26
27 SDL.GL_SetAttribute(.CONTEXT_PROFILE_MASK, i32(SDL.GLprofile.CORE))
28 SDL.GL_SetAttribute(.CONTEXT_MAJOR_VERSION, GL_VERSION_MAJOR)
29 SDL.GL_SetAttribute(.CONTEXT_MINOR_VERSION, GL_VERSION_MINOR)
30
31 gl_context := SDL.GL_CreateContext(window)
32 defer SDL.GL_DeleteContext(gl_context)
33
34
35 gl.load_up_to(GL_VERSION_MAJOR, GL_VERSION_MINOR, SDL.gl_set_proc_address)
36
37
38 program, program_ok := gl.load_shaders_source(vertex_source, fragment_source)
39 if !program_ok {
40 fmt.eprintln("Failed to create GLSL program")
41 return
42 }
43 defer gl.DeleteProgram(program)
44
45 gl.UseProgram(program)
46
47 uniforms := gl.get_uniforms_from_program(program)
48 defer delete(uniforms)
49
50 vao: u32
51 gl.GenVertexArrays(1, &vao); defer gl.DeleteVertexArrays(1, &vao)
52 gl.BindVertexArray(vao)
53
54
55 vbo, ebo: u32
56 gl.GenBuffers(1, &vbo); defer gl.DeleteBuffers(1, &vbo)
57 gl.GenBuffers(1, &ebo); defer gl.DeleteBuffers(1, &ebo)
58
59
60 Vertex :: struct {
61 pos: glm.vec3,
62 col: glm.vec4,
63 }
64
65 vertices := []Vertex{
66 {{-0.5, +0.5, 0}, {1.0, 0.0, 0.0, 0.75}},
67 {{-0.5, -0.5, 0}, {1.0, 1.0, 0.0, 0.75}},
68 {{+0.5, -0.5, 0}, {0.0, 1.0, 0.0, 0.75}},
69 {{+0.5, +0.5, 0}, {0.0, 0.0, 1.0, 0.75}},
70 }
71
72 indices := []u16{
73 0, 1, 2,
74 2, 3, 0,
75 }
76
77 gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
78 gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*size_of(vertices[0]), raw_data(vertices), gl.STATIC_DRAW)
79 gl.EnableVertexAttribArray(0)
80 gl.EnableVertexAttribArray(1)
81 gl.VertexAttribPointer(0, 3, gl.FLOAT, false, size_of(Vertex), offset_of(Vertex, pos))
82 gl.VertexAttribPointer(1, 4, gl.FLOAT, false, size_of(Vertex), offset_of(Vertex, col))
83
84 gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
85 gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*size_of(indices[0]), raw_data(indices), gl.STATIC_DRAW)
86
87
88 start_tick := time.tick_now()
89
90 loop: for {
91 duration := time.tick_since(start_tick)
92 t := f32(time.duration_seconds(duration))
93
94
95 event: SDL.Event
96 for SDL.PollEvent(&event) {
97
98 #partial switch event.type {
99 case .KEYDOWN:
100 #partial switch event.key.keysym.sym {
101 case .ESCAPE:
102
103 break loop
104 }
105 case .QUIT:
106
107 break loop
108 }
109 }
110
111
112 pos := glm.vec3{
113 glm.cos(t*2),
114 glm.sin(t*2),
115 0,
116 }
117
118
119 pos *= 0.3
120
121
122
123 model := glm.mat4{
124 0.5, 0, 0, 0,
125 0, 0.5, 0, 0,
126 0, 0, 0.5, 0,
127 0, 0, 0, 1,
128 }
129
130
131 model[0, 3] = -pos.x
132 model[1, 3] = -pos.y
133 model[2, 3] = -pos.z
134
135
136 model[3].yzx = pos.yzx
137
138 model = model * glm.mat4Rotate({0, 1, 1}, t)
139
140 view := glm.mat4LookAt({0, -1, +1}, {0, 0, 0}, {0, 0, 1})
141 proj := glm.mat4Perspective(45, 1.3, 0.1, 100.0)
142
143
144 u_transform := proj * view * model
145
146
147 gl.UniformMatrix4fv(uniforms["u_transform"].location, 1, false, &u_transform[0, 0])
148
149 gl.Viewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
150 gl.ClearColor(0.5, 0.7, 1.0, 1.0)
151 gl.Clear(gl.COLOR_BUFFER_BIT)
152
153 gl.DrawElements(gl.TRIANGLES, i32(len(indices)), gl.UNSIGNED_SHORT, nil)
154
155 SDL.GL_SwapWindow(window)
156 }
157}
158
159
160vertex_source := `#version 330 core
161
162layout(location=0) in vec3 a_position;
163layout(location=1) in vec4 a_color;
164
165out vec4 v_color;
166
167uniform mat4 u_transform;
168
169void main() {
170 gl_Position = u_transform * vec4(a_position, 1.0);
171 v_color = a_color;
172}
173`
174
175fragment_source := `#version 330 core
176
177in vec4 v_color;
178
179out vec4 o_color;
180
181void main() {
182 o_color = v_color;
183}
184`