summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main.odin162
-rw-r--r--src/shader/shader.odin50
2 files changed, 212 insertions, 0 deletions
diff --git a/src/main.odin b/src/main.odin
index 75bd82e..47dd6d5 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -1,10 +1,15 @@
 package main
 import gl "vendor:OpenGL"
 import "vendor:glfw"
+import "vendor:stb/image"
 
 import "base:intrinsics"
 import "base:runtime"
+import "core:c/libc"
 import "core:fmt"
+import "core:os"
+
+import "shader"
 
 GL_MAJOR_VERSION :: 3
 GL_MINOR_VERSION :: 3
@@ -48,13 +53,170 @@ main :: proc() {
 	gl.Viewport(0, 0, 800, 600)
 	glfw.SetFramebufferSizeCallback(window, framebuffer_size_callback)
 
+	shdr, err := shader.shader_init("res/shaders/triangle.vs", "res/shaders/triangle.fs")
+	if err == shader.SHADER_LOAD_ERROR {
+		fmt.eprintln("Could not initialize shader")
+		return
+	}
+
+	vertices: []f32 = {
+		0.5,
+		0.5,
+		0.0,
+		1.0,
+		0.0,
+		0.0,
+		1.0,
+		1.0, // top right
+		0.5,
+		-0.5,
+		0.0,
+		0.0,
+		1.0,
+		0.0,
+		1.0,
+		0.0, // bottom right
+		-0.5,
+		-0.5,
+		0.0,
+		0.0,
+		0.0,
+		1.0,
+		0.0,
+		0.0, // bottom let
+		-0.5,
+		0.5,
+		0.0,
+		1.0,
+		1.0,
+		0.0,
+		0.0,
+		1.0,
+	}
+
+	indices := []i32{0, 1, 3, 1, 2, 3}
+
+	vbo, vao, ebo, texture1, texture2: u32
+	gl.GenVertexArrays(1, &vao)
+	gl.GenBuffers(1, &vbo)
+	gl.GenBuffers(1, &ebo)
+
+	gl.BindVertexArray(vao)
+	gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
+
+	gl.BufferData(
+		gl.ARRAY_BUFFER,
+		size_of(f32) * len(vertices),
+		raw_data(vertices),
+		gl.STATIC_DRAW,
+	)
+	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
+	gl.BufferData(
+		gl.ELEMENT_ARRAY_BUFFER,
+		size_of(i32) * len(indices),
+		raw_data(indices),
+		gl.STATIC_DRAW,
+	)
+
+
+	gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 8 * size_of(f32), 0)
+	gl.EnableVertexAttribArray(0)
+
+	gl.VertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, 8 * size_of(f32), 3 * size_of(f32))
+	gl.EnableVertexAttribArray(1)
+
+	gl.VertexAttribPointer(2, 2, gl.FLOAT, gl.FALSE, 8 * size_of(f32), 6 * size_of(f32))
+	gl.EnableVertexAttribArray(2)
+
+	gl.GenTextures(1, &texture1)
+	gl.BindTexture(gl.TEXTURE_2D, texture1)
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
+
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
+
+	width, height, nr_channels: libc.int
+	assert(os.is_file_path("res/images/container.jpg"))
+	data := image.load("res/images/container.jpg", &width, &height, &nr_channels, 0)
+
+	if data != nil {
+		gl.TexImage2D(
+			gl.TEXTURE_2D,
+			0,
+			gl.RGB,
+			i32(width),
+			i32(height),
+			0,
+			gl.RGB,
+			gl.UNSIGNED_BYTE,
+			data,
+		)
+		gl.GenerateMipmap(gl.TEXTURE_2D)
+	} else {
+		fmt.eprintln("Failed to load texture")
+		return
+	}
+	image.image_free(data)
+
+	gl.GenTextures(1, &texture2)
+	gl.BindTexture(gl.TEXTURE_2D, texture2)
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
+
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
+	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
+
+	image.set_flip_vertically_on_load(1)
+
+	assert(os.is_file_path("res/images/awesomeface.png"))
+	data = image.load("res/images/awesomeface.png", &width, &height, &nr_channels, 0)
+
+	if data != nil {
+		gl.TexImage2D(
+			gl.TEXTURE_2D,
+			0,
+			gl.RGBA,
+			i32(width),
+			i32(height),
+			0,
+			gl.RGBA,
+			gl.UNSIGNED_BYTE,
+			data,
+		)
+		gl.GenerateMipmap(gl.TEXTURE_2D)
+	} else {
+		fmt.eprintln("Failed to load texture")
+		return
+	}
+	image.image_free(data)
+
+	shader.use(shdr)
+	gl.Uniform1i(gl.GetUniformLocation(shdr.id, cstring("texture1")), i32(0))
+	gl.Uniform1i(gl.GetUniformLocation(shdr.id, cstring("texture2")), i32(1))
+
+	//gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE)
+
 	for !glfw.WindowShouldClose(window) {
 		process_input(&window)
 
 		gl.ClearColor(0.2, 0.3, 0.3, 1.0)
 		gl.Clear(gl.COLOR_BUFFER_BIT)
 
+		gl.ActiveTexture(gl.TEXTURE0)
+		gl.BindTexture(gl.TEXTURE_2D, texture1)
+		gl.ActiveTexture(gl.TEXTURE1)
+		gl.BindTexture(gl.TEXTURE_2D, texture2)
+
+		shader.use(shdr)
+		gl.BindVertexArray(vao)
+		gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
+
 		glfw.SwapBuffers(window)
 		glfw.PollEvents()
 	}
+
+	gl.DeleteBuffers(1, &ebo)
+	gl.DeleteVertexArrays(1, &vao)
+	gl.DeleteBuffers(1, &vbo)
 }
diff --git a/src/shader/shader.odin b/src/shader/shader.odin
new file mode 100644
index 0000000..171d7ad
--- /dev/null
+++ b/src/shader/shader.odin
@@ -0,0 +1,50 @@
+package shader
+
+import "core:os"
+import "core:strings"
+import gl "vendor:OpenGL"
+
+Shader :: struct {
+	id: u32,
+}
+
+SHADER_LOAD_ERROR :: -1
+SHADER_OK :: 0
+
+shader_init :: proc(vsp, fsp: string) -> (^Shader, int) {
+	assert(os.is_file_path(vsp))
+	assert(os.is_file_path(fsp))
+
+	program_id, ok := gl.load_shaders_file(vsp, fsp)
+
+	if !ok {
+		return nil, SHADER_LOAD_ERROR
+	}
+
+	shader := new(Shader)
+	shader.id = program_id
+
+	return shader, SHADER_OK
+}
+
+use :: proc(using shader: ^Shader) {
+	gl.UseProgram(id)
+}
+
+set_bool :: proc(using shader: ^Shader, name: cstring, value: bool) {
+	gl.Uniform1i(gl.GetUniformLocation(id, name), i32(value))
+}
+
+set_i32 :: proc(using shader: ^Shader, name: cstring, value: i32) {
+	gl.Uniform1i(gl.GetUniformLocation(id, name), value)
+}
+
+set_f32 :: proc(using shader: ^Shader, name: cstring, value: f32) {
+	gl.Uniform1f(gl.GetUniformLocation(id, name), value)
+}
+
+set_value :: proc {
+	set_i32,
+	set_f32,
+	set_bool,
+}