opengl/learn_opengl/1_getting_started/2_hello_triangle

Licence This example has its own licence, rather than Odin's: opengl/learn_opengl/LICENSE
LearnOpenGL.com © 2025 by Joey de Vries is licensed under CC BY-NC 4.0. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc/4.0/ https://learnopengl.com https://x.com/JoeyDeVriez

Code

main.odin ¶
146 linesSource

1package main
2
3import gl "vendor:OpenGL"
4import "vendor:glfw"
5import "core:fmt"
6import "core:os"
7import "core:c"
8
9framebuffer_size_callback :: proc "c" (window: glfw.WindowHandle, width: i32, height: i32) {
10	gl.Viewport(0, 0, width, height)
11}
12
13processInput :: proc "c" (window: glfw.WindowHandle) {
14	if glfw.GetKey(window, glfw.KEY_ESCAPE) == glfw.PRESS {
15		glfw.SetWindowShouldClose(window, true)
16	}
17}
18
19vertexShaderSource: cstring = 
20`#version 330 core
21layout (location = 0) in vec3 aPos;
22void main()
23{
24	gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
25}`
26
27fragmentShaderSource: cstring = 
28`#version 330 core
29out vec4 FragColor;
30
31void main()
32{
33	FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
34}`
35
36SCR_WIDTH :: 800
37SCR_HEIGHT :: 600
38
39main :: proc() {
40	glfw.Init()
41	glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
42	glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
43	glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
44
45	window := glfw.CreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", nil, nil)
46	if window == nil {
47		fmt.println("Failed to create GLFW window")
48		glfw.Terminate()
49		os.exit(-1)
50	}
51	glfw.MakeContextCurrent(window)
52
53	gl.load_up_to(3, 3, glfw.gl_set_proc_address)
54
55	gl.Viewport(0, 0, SCR_WIDTH, SCR_HEIGHT)
56
57	glfw.SetFramebufferSizeCallback(window, framebuffer_size_callback)
58
59	success: i32
60	infoLog: [512]c.char
61
62	vertexShader := gl.CreateShader(gl.VERTEX_SHADER)
63	gl.ShaderSource(vertexShader, 1, &vertexShaderSource, nil)
64	gl.CompileShader(vertexShader)
65
66	gl.GetShaderiv(vertexShader, gl.COMPILE_STATUS, &success)
67	if success != 1 {
68		gl.GetShaderInfoLog(vertexShader, 512, nil, raw_data(&infoLog))
69	}
70
71	fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER)
72	gl.ShaderSource(fragmentShader, 1, &fragmentShaderSource, nil)
73	gl.CompileShader(fragmentShader)
74
75	gl.GetShaderiv(fragmentShader, gl.COMPILE_STATUS, &success)
76	if success != 1 {
77		gl.GetShaderInfoLog(fragmentShader, 512, nil, raw_data(&infoLog))
78		os.exit(-1)
79	}
80
81	shaderProgram := gl.CreateProgram()
82	gl.AttachShader(shaderProgram, vertexShader)
83	gl.AttachShader(shaderProgram, fragmentShader)
84	gl.LinkProgram(shaderProgram)
85
86	gl.GetProgramiv(fragmentShader, gl.LINK_STATUS, &success)
87	if success != 1 {
88		gl.GetProgramInfoLog(fragmentShader, 512, nil, raw_data(&infoLog))
89		os.exit(-1)
90	}
91
92	gl.DeleteShader(vertexShader)
93	gl.DeleteShader(fragmentShader)
94
95	vertices := [?]f32 {
96		 0.5,  0.5, 0.0, 
97         0.5, -0.5, 0.0,
98        -0.5, -0.5, 0.0,
99        -0.5,  0.5, 0.0,
100	}
101
102	indices := [?]u32 {
103		0, 1, 3,
104		1, 2, 3,
105	}
106
107	VBO, VAO, EBO: u32
108	gl.GenVertexArrays(1, &VAO)
109	gl.GenBuffers(1, &VBO)
110	gl.GenBuffers(1, &EBO)
111
112	gl.BindVertexArray(VAO)
113
114	gl.BindBuffer(gl.ARRAY_BUFFER, VBO)
115	gl.BufferData(gl.ARRAY_BUFFER, size_of(vertices), raw_data(&vertices), gl.STATIC_DRAW)
116
117	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, EBO)
118	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, size_of(indices), raw_data(&indices), gl.STATIC_DRAW)
119
120	gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 3 * size_of(f32), 0)
121	gl.EnableVertexAttribArray(0)
122	
123	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
124	gl.BindVertexArray(0)
125
126	for !glfw.WindowShouldClose(window) {
127		processInput(window)
128
129		gl.ClearColor(0.2, 0.3, 0.3, 1.0)
130		gl.Clear(gl.COLOR_BUFFER_BIT)
131
132		gl.UseProgram(shaderProgram)
133		gl.BindVertexArray(VAO)
134		gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
135
136		glfw.SwapBuffers(window)
137		glfw.PollEvents()
138	}
139
140	gl.DeleteVertexArrays(1, &VAO)
141	gl.DeleteBuffers(1, &VBO)
142	gl.DeleteBuffers(1, &EBO)
143	gl.DeleteProgram(shaderProgram)
144
145	glfw.Terminate()
146}

Declarations Used 61