// main draw loop
gl.clear_color(0.1, 0.0, 0.2, 1.0)
gl.clear(.color_buffer_bit)
state.draw_quad()
state.draw_tri()
fn create_shader(vert_src, frag_src string) u32 {
// vertex shader
vert := gl.create_shader(.vertex_shader)
gl.shader_source(vert, vert_src)
gl.compile_shader(vert)
if gl.get_shader_compile_status(vert) == 0 {
log := gl.get_shader_info_log(vert)
println('shader $vert compilation failed')
println(log)
exit(1)
}
// fragment shader
frag := gl.create_shader(.fragment_shader)
gl.shader_source(frag, frag_src)
gl.compile_shader(frag)
if gl.get_shader_compile_status(frag) == 0 {
log := gl.get_shader_info_log(frag)
println('fragment $frag shader compilation failed')
println(log)
exit(1)
}
// link shaders
shader_program := gl.create_program()
gl.attach_shader(shader_program, vert)
gl.attach_shader(shader_program, frag)
gl.link_program(shader_program)
// check for linking errors
success := gl.get_program_link_status(shader_program)
if success == 0 {
log := gl.get_program_info_log(shader_program)
println('shader compilation failed')
println('vertex source = $vert_src')
println('fragment source = $frag_src')
println(log)
exit(1)
}
gl.delete_shader(vert)
gl.delete_shader(frag)
return shader_program
}
fn (state mut AppState) create_buffers() {
vertex_data := [
// positions // colors // texture coords
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 left
-0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0 // top left
]!
index_data := [
u16(0), 1, 3, 1, 2, 3
]!
state.vao = gl.gen_vertex_array()
gl.bind_vertex_array(state.vao)
state.vbo = gl.gen_buffer()
gl.bind_buffer(.array_buffer, state.vbo)
gl.buffer_data_f32(.array_buffer, vertex_data, .static_draw)
state.ibo = gl.gen_buffer()
gl.bind_buffer(.element_array_buffer, state.ibo)
gl.buffer_data_u16(.element_array_buffer, index_data, .static_draw)
// position attribute
gl.vertex_attrib_pointer(0, 3, .float, .gl_false, 8 * sizeof(f32), C.NULL)
gl.enable_vertex_attrib_array(0)
// color attribute
gl.vertex_attrib_pointer(1, 3, .float, .gl_false, 8 * sizeof(f32), (3 * sizeof(f32)))
gl.enable_vertex_attrib_array(1)
// texture coord attribute
gl.vertex_attrib_pointer(2, 2, .float, .gl_false, 8 * sizeof(f32), (6 * sizeof(f32)))
gl.enable_vertex_attrib_array(2)
}
fn create_tri_buffers() Mesh {
vertex_data := [
// positions // tex coords // colors
-1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, // bottom left
1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, // bottom right
0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0 // top
]!
index_data := [
u16(0), 1, 2
]!
vao := gl.gen_vertex_array()
gl.bind_vertex_array(vao)
vbo := gl.gen_buffer()
gl.bind_buffer(.array_buffer, vbo)
gl.buffer_data_f32(.array_buffer, vertex_data, .static_draw)
ibo := gl.gen_buffer()
gl.bind_buffer(.element_array_buffer, ibo)
gl.buffer_data_u16(.element_array_buffer, index_data, .static_draw)
// position attribute
gl.vertex_attrib_pointer(0, 2, .float, .gl_false, 8 * sizeof(f32), C.NULL)
gl.enable_vertex_attrib_array(0)
// texture coord attribute
gl.vertex_attrib_pointer(2, 2, .float, .gl_false, 8 * sizeof(f32), 2 * sizeof(f32))
gl.enable_vertex_attrib_array(2)
// color attribute
gl.vertex_attrib_pointer(2, 4, .float, .gl_false, 8 * sizeof(f32), 2 * sizeof(f32))
gl.enable_vertex_attrib_array(2)
return Mesh { vao, vbo, ibo }
}
fn (state mut AppState) load_textures() {
image.set_flip_vertically_on_load(true)
state.tex = gl.gen_texture()
gl.bind_texture(.texture_2d, state.tex)
// set the texture wrapping parameters
gl.tex_parameteri(.texture_2d, .texture_wrap_s, C.GL_REPEAT)
gl.tex_parameteri(.texture_2d, .texture_wrap_t, C.GL_REPEAT)
// set texture filtering parameters
gl.tex_parameteri(.texture_2d, .texture_min_filter, C.GL_LINEAR)
gl.tex_parameteri(.texture_2d, .texture_mag_filter, C.GL_LINEAR)
img := image.load('assets/container.jpg')
gl.tex_image_2d(.texture_2d, 0, .rgb, img.width, img.height, 0, .rgb, .unsigned_byte, img.data)
img.free()
state.tex2 = gl.gen_texture()
gl.bind_texture(.texture_2d, state.tex2)
// set the texture wrapping parameters
gl.tex_parameteri(.texture_2d, .texture_wrap_s, C.GL_REPEAT)
gl.tex_parameteri(.texture_2d, .texture_wrap_t, C.GL_REPEAT)
// set texture filtering parameters
gl.tex_parameteri(.texture_2d, .texture_min_filter, C.GL_LINEAR)
gl.tex_parameteri(.texture_2d, .texture_mag_filter, C.GL_LINEAR)
img2 := image.load('assets/face.png')
gl.tex_image_2d(.texture_2d, 0, .rgba, img2.width, img2.height, 0, .rgba, .unsigned_byte, img2.data)
img2.free()
gl.use_program(state.program1)
gl.uniform1i(gl.get_uniform_location(state.program1, "texture1"), 0)
gl.uniform1i(gl.get_uniform_location(state.program1, "texture2"), 1)
}
fn (state AppState) draw_quad() {
gl.use_program(state.program1)
gl.active_texture(.texture0)
gl.bind_texture(.texture_2d, state.tex)
gl.active_texture(.texture1)
gl.bind_texture(.texture_2d, state.tex2)
gl.bind_vertex_array(state.vao)
gl.draw_elements(.triangle_fan, 6, .unsigned_short, C.NULL)
}
fn (state AppState) draw_tri() {
gl.use_program(state.program2)
gl.active_texture(.texture0)
gl.bind_texture(.texture_2d, 0)
gl.active_texture(.texture1)
gl.bind_texture(.texture_2d, 0)
gl.bind_vertex_array(state.tri_mesh.vao)
gl.draw_elements(.triangle_fan, 3, .unsigned_short, C.NULL)
}