summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2023-04-23 03:13:02 +0100
committerdavidovski <david@davidovski.xyz>2023-04-23 03:13:02 +0100
commitbb3034a4cb0f793e31608ebee4eff2ef8c1f8379 (patch)
tree5f5bddfc45bf75a0be004cdf6de1a05e7cb351dd
Pass tilemap to shader
-rw-r--r--Makefile15
-rw-r--r--README.md8
-rw-r--r--tiled.c90
-rw-r--r--tiled.glsl57
-rw-r--r--tiles.pngbin0 -> 875 bytes
5 files changed, 170 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2a5ece6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+PROG=tiled
+CC=gcc
+FLAGS=-lm -lraylib
+
+.DEFAULT_GOAL := build
+
+install: ${PROG}
+ cp ${PROG} ${PREFIX}/bin/
+
+build: ${PROG}.c
+ ${CC} ${PROG}.c -o ${PROG} ${FLAGS}
+
+clean: ${PROG}
+ rm ${PROG}
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..dde036b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+# Tiled Rendering
+
+Experimenting with rendering a tilemap using shaders
+
+## Requirements
+
+- C Compiler
+- raylib
diff --git a/tiled.c b/tiled.c
new file mode 100644
index 0000000..f3e34f2
--- /dev/null
+++ b/tiled.c
@@ -0,0 +1,90 @@
+#include <raylib.h>
+
+#define SCREEN_W 1280
+#define SCREEN_H 720
+
+#define MAP_W 4
+#define MAP_H 4
+
+const int tilemap[MAP_H][MAP_W] = {
+ {0, 0, 0, 0},
+ {0, 0, 3, 3},
+ {3, 3, 1, 1},
+ {1, 1, 2, 2}
+};
+
+
+int main() {
+ InitWindow(SCREEN_W, SCREEN_H, "tiled");
+
+ Shader shader = LoadShader(0, "tiled.glsl");
+
+ RenderTexture2D target = LoadRenderTexture(SCREEN_W, SCREEN_H);
+
+ float resolution[2] = {SCREEN_W, SCREEN_H};
+ float offset[2] = {0, 0};
+ float zoom = 1.0f;
+ Texture atlas = LoadTexture("tiles.png");
+ // size of the tile atlas grid in tiles
+ int atlasSize[2] = {2, 2};
+
+ int resolutionLoc = GetShaderLocation(shader, "resolution");
+ int locationLoc = GetShaderLocation(shader, "offset");
+ int zoomLoc = GetShaderLocation(shader, "zoom");
+ int atlasSizeLoc = GetShaderLocation(shader, "atlasSize");
+
+ int tilemapLoc[MAP_W][MAP_H]= {};
+ for (int x = 0; x < MAP_W; x++) {
+ for (int y = 0; y < MAP_H; y++) {
+ tilemapLoc[y][x] = GetShaderLocation(shader, TextFormat("tilemap[%d][%d]", y, x));
+ }
+ }
+
+
+ int textureLoc = GetShaderLocation(shader, "texture1");
+
+ while (!WindowShouldClose()) {
+ if (IsKeyDown(KEY_UP)) offset[1] += zoom * 0.01f;
+ if (IsKeyDown(KEY_DOWN)) offset[1] -= zoom * 0.01f;
+ if (IsKeyDown(KEY_RIGHT)) offset[0] -= zoom * 0.01f;
+ if (IsKeyDown(KEY_LEFT)) offset[0] += zoom * 0.01f;
+
+ if (IsKeyDown(KEY_W)) zoom -= zoom * 0.01f;
+ if (IsKeyDown(KEY_S)) zoom += zoom * 0.01f;
+
+ SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
+ SetShaderValue(shader, locationLoc, &offset, SHADER_UNIFORM_VEC2);
+ SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
+ SetShaderValue(shader, atlasSizeLoc, &atlasSize, SHADER_UNIFORM_IVEC2);
+ for (int x = 0; x < MAP_W; x++) {
+ for (int y = 0; y < MAP_H; y++) {
+ SetShaderValue(shader, tilemapLoc[y][x], &tilemap[y][x], SHADER_UNIFORM_INT);
+ }
+ }
+
+ BeginDrawing();
+
+ ClearBackground(LIGHTGRAY);
+
+ BeginTextureMode(target);
+ DrawRectangle(0, 0, SCREEN_W, SCREEN_H, BLACK);
+ EndTextureMode();
+
+ BeginShaderMode(shader);
+ SetShaderValueTexture(shader, textureLoc, atlas);
+
+ // draw the base image to texture0
+ DrawTexture(target.texture, 0, 0, WHITE);
+ EndShaderMode();
+
+ EndDrawing();
+ }
+
+ UnloadShader(shader);
+ UnloadRenderTexture(target);
+ UnloadTexture(atlas);
+
+ CloseWindow();
+
+ return 0;
+}
diff --git a/tiled.glsl b/tiled.glsl
new file mode 100644
index 0000000..2a0e5d9
--- /dev/null
+++ b/tiled.glsl
@@ -0,0 +1,57 @@
+#version 430
+precision highp float;
+
+in vec3 vertexPos;
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+uniform sampler2D texture0;
+uniform sampler2D texture1;
+
+uniform vec2 resolution;
+uniform vec2 offset;
+uniform float zoom;
+uniform ivec2 atlasSize;
+uniform int tilemap[4][4];
+
+out vec4 finalColor;
+
+ivec2 calcTileOffset(int tileIndex) {
+ tileIndex -= 1;
+ int x = tileIndex % atlasSize.x;
+ int y = (tileIndex - x) / atlasSize.y;
+ return ivec2(x, y);
+}
+
+vec4 tile(vec2 coords, int tileIndex) {
+ ivec2 texSize = textureSize(texture1, 1);
+
+ // for now just render the first tile
+
+
+ vec2 tileSize = texSize / atlasSize;
+
+ if (tileIndex == 0
+ || coords.x > tileSize.x
+ || coords.x < 0
+ || coords.y > tileSize.y
+ || coords.y < 0) {
+ return vec4(0.0f, 0.0f, 0.0f, 0.0f);
+ } else {
+ ivec2 tileOffset = calcTileOffset(tileIndex);
+ vec2 texCoords = coords + (tileOffset*tileSize);
+ texCoords /= texSize;
+
+ return texture(texture1, texCoords);
+ }
+}
+
+void main() {
+ vec2 uv = fragTexCoord;
+ uv.x *= resolution.x / resolution.y;
+
+ uv *= zoom;
+ uv -= offset;
+
+ finalColor = tile(uv, tilemap[2][2]);
+}
diff --git a/tiles.png b/tiles.png
new file mode 100644
index 0000000..3a86dc4
--- /dev/null
+++ b/tiles.png
Binary files differ