commit af6ac03f1b4677f5e225fa5e614f7fa8022ac7b6
parent 7c6c6306a7bffb0d09ebc80f04e5aef237767a71
Author: amin <dev@aminmesbah.com>
Date: Tue, 16 Jul 2019 00:29:55 +0000
Load tile textures from a tileset
FossilOrigin-Name: 9fd417b44aba46077ffaca5014e1e9dc1328943cea31bf1a20cd3f5fb15fe168
Diffstat:
6 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/shader/main_f.glsl b/shader/main_f.glsl
@@ -2,8 +2,9 @@
// NOTE(amin): this is necessary for webgl compat
precision highp float;
+precision highp sampler2DArray;
-// TODO: dynamically instert the version header after loading the file
+// TODO: dynamically insert the version header after loading the file
in vec4 vertex_color;
in vec2 tex_coord;
@@ -11,9 +12,12 @@ in vec2 tex_coord;
out vec4 frag_color;
uniform float tex_interp;
-uniform sampler2D main_texture;
+uniform sampler2DArray tileset;
void main()
{
- frag_color = mix(vertex_color, texture(main_texture, tex_coord), tex_interp);
+ // TODO: make this an input
+ float tile_id = 16.0f;
+ vec4 tile_texel = texture(tileset, vec3(tex_coord, tile_id));
+ frag_color = mix(vertex_color, tile_texel, tex_interp);
}
diff --git a/shader/main_v.glsl b/shader/main_v.glsl
@@ -1,6 +1,6 @@
#version 300 es
-// TODO: dynamically instert the version header after loading the file
+// TODO: dynamically insert the version header after loading the file
layout (location = 0) in vec2 position;
layout (location = 1) in vec2 a_tex_coords;
diff --git a/src/game.c b/src/game.c
@@ -183,6 +183,7 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
struct Shader main_shader = {0};
if (!shader_compile(v_source, f_source, &main_shader))
{
+ exit(1);
// TODO: handle error
}
platform.platform_memory_free(v_source);
diff --git a/src/platform_linux.c b/src/platform_linux.c
@@ -30,8 +30,8 @@ int main(void)
return -1;
}
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
diff --git a/src/platform_windows.c b/src/platform_windows.c
@@ -31,8 +31,8 @@ int main(void)
return -1;
}
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
diff --git a/src/render.c b/src/render.c
@@ -50,16 +50,62 @@ internal void renderer_init(struct RendererState *renderer, struct Image *images
for (u32 i = 0; i < num_images; i++)
{
struct Image img = images[i];
+ u8 bytes_per_texel = 4;
+ v2u tile_dim = {64, 64};
+ v2u tileset_dim = {img.dim.x / tile_dim.x, img.dim.y / tile_dim.y};
+
u32 texture_id;
glGenTextures(1, &texture_id);
- glBindTexture(GL_TEXTURE_2D, texture_id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.dim.width, img.dim.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data);
- glGenerateMipmap(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, texture_id);
+ glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, tile_dim.x, tile_dim.y, tileset_dim.x * tileset_dim.y);
+ size_t marker = mem_st_get_marker(allocator);
+ {
+ u8 *tile_data = mem_st_alloc_buffer(allocator, u8, tile_dim.x * tile_dim.y * bytes_per_texel);
+ for (u32 tile_y = 0; tile_y < tileset_dim.y; tile_y++)
+ {
+ for (u32 tile_x = 0; tile_x < tileset_dim.x; tile_x++)
+ {
+ // NOTE(amin): We must copy the disparate interleaved
+ // texels associated with a given tile in the image to a
+ // contiguous memory region.
+ for (u32 texel_y = 0; texel_y < tile_dim.y; texel_y++)
+ {
+ for (u32 texel_x = 0; texel_x < tile_dim.x; texel_x++)
+ {
+ v2u texel_index_in_image = {
+ (tile_x * tile_dim.x) + texel_x,
+ (tile_y * tile_dim.y) + texel_y,
+ };
+ assert(texel_index_in_image.x < tileset_dim.x * tile_dim.x);
+ assert(texel_index_in_image.y < tileset_dim.y * tile_dim.y);
+ u32 linearized_texel_i = texel_index_in_image.x + (texel_index_in_image.y * tileset_dim.x * tile_dim.x);
+ u32 *texel = (u32 *)(img.data + (linearized_texel_i * bytes_per_texel));
+ ((u32 *)tile_data)[texel_x + (texel_y * tile_dim.x)] = *texel;
+ }
+ }
+ u32 tile_id = tile_x + (tile_y * tileset_dim.x);
+ glTexSubImage3D(
+ GL_TEXTURE_2D_ARRAY,
+ 0, 0, 0,
+ tile_id,
+ tile_dim.x,
+ tile_dim.y,
+ 1,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ tile_data);
+ }
+ }
+ }
+ mem_st_free_to_marker(allocator, marker);
+
+ // TODO: fix the _hideous_ aliasing that happens when scaling down.
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
glActiveTexture(GL_TEXTURE0);
}