Fix UV mapping

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2026-05-05 02:06:03 +0200
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2026-05-05 02:09:08 +0200
Commit 18d2880823e1f657813cc9198a927f48315456ea (patch)
-rw-r--r-- all.h 2
-rw-r--r-- assets.c 3
-rw-r--r-- main.c 9
-rw-r--r-- map.c 60
4 files changed, 60 insertions, 14 deletions
diff --git a/all.h b/all.h
...
152
void poly_free(Polygon p);
152
void poly_free(Polygon p);
153
Polygon poly_clip(Polygon poly, Plane plane);
153
Polygon poly_clip(Polygon poly, Plane plane);
154
Polygon create_large_quad(Plane plane);
154
Polygon create_large_quad(Plane plane);
155
Vector2 get_uv(Vector3 p, MapPlane *mp, Plane plane);
155
Vector2 get_uv(Vector3 p, MapPlane *mp, Plane plane, int texWidth, int texHeight);
156
  
156
  
157
// Interface
157
// Interface
158
void draw_crosshair(void);
158
void draw_crosshair(void);
...
diff --git a/assets.c b/assets.c
...
49
		tex = LoadTextureFromImage(img);
49
		tex = LoadTextureFromImage(img);
50
		UnloadImage(img);
50
		UnloadImage(img);
51
	} else {
51
	} else {
52
		GenTextureMipmaps(&tex);
52
		SetTextureFilter(tex, TEXTURE_FILTER_POINT);
53
		SetTextureFilter(tex, TEXTURE_FILTER_BILINEAR);
  
54
		SetTextureWrap(tex, TEXTURE_WRAP_REPEAT);
53
		SetTextureWrap(tex, TEXTURE_WRAP_REPEAT);
55
	}
54
	}
56
  
55
  
...
diff --git a/main.c b/main.c
...
7
int main(int argc, char *argv[]) {
7
int main(int argc, char *argv[]) {
8
	stringb map_path;
8
	stringb map_path;
9
	sb_init(&map_path, 256);
9
	sb_init(&map_path, 256);
10
	sb_append_cstr(&map_path, "maps/demo3.map");
10
	sb_append_cstr(&map_path, "maps/demo4.map");
11
  
11
  
12
	bool skip_title = false;
12
	bool skip_title = false;
13
	int target_fps = -1;
13
	int target_fps = -1;
...
96
		}
96
		}
97
		if (IsKeyPressed(KEY_THREE)) {
97
		if (IsKeyPressed(KEY_THREE)) {
98
			if (load_map("maps/demo3.map")) {
98
			if (load_map("maps/demo3.map")) {
  
99
				game.mode = STATE_PLAYING;
  
100
				game.cursor_captured = true;
  
101
				DisableCursor();
  
102
			}
  
103
		}
  
104
		if (IsKeyPressed(KEY_FOUR)) {
  
105
			if (load_map("maps/demo4.map")) {
99
				game.mode = STATE_PLAYING;
106
				game.mode = STATE_PLAYING;
100
				game.cursor_captured = true;
107
				game.cursor_captured = true;
101
				DisableCursor();
108
				DisableCursor();
...
diff --git a/map.c b/map.c
...
235
	return poly;
235
	return poly;
236
}
236
}
237
  
237
  
238
Vector2 get_uv(Vector3 p, MapPlane *mp, Plane plane) {
238
Vector2 get_uv(Vector3 p, MapPlane *mp, Plane plane, int texWidth, int texHeight) {
  
239
	// Map coordinate system: X right, Y forward, Z up
  
240
	// Raylib coordinate system: X right, Y up, Z back
  
241
	// Conversion: Raylib.x = Map.x, Raylib.y = Map.z, Raylib.z = -Map.y
  
242
  
  
243
	// Map coordinates from Raylib coordinates:
  
244
	float mx = p.x;
  
245
	float my = -p.z;
  
246
	float mz = p.y;
  
247
  
  
248
	// Map normal from Raylib normal:
239
	Vector3 n = plane.normal;
249
	Vector3 n = plane.normal;
240
	Vector3 up = (fabsf(n.y) < 0.999f) ? (Vector3){ 0, 1, 0 } : (Vector3){ 1, 0, 0 };
250
	float nx = n.x;
241
	Vector3 right = Vector3Normalize(Vector3CrossProduct(up, n));
251
	float ny = -n.z;
242
	up = Vector3CrossProduct(n, right);
252
	float nz = n.y;
  
253
  
  
254
	float u = 0, v = 0;
  
255
  
  
256
	// Quake Standard axis projection
  
257
	if (fabsf(nz) >= fabsf(nx) && fabsf(nz) >= fabsf(ny)) {
  
258
		u = mx;
  
259
		v = -my;
  
260
	} else if (fabsf(nx) >= fabsf(ny) && fabsf(nx) >= fabsf(nz)) {
  
261
		u = my;
  
262
		v = -mz;
  
263
	} else { // ny is dominant
  
264
		u = mx;
  
265
		v = -mz;
  
266
	}
243
  
267
  
244
	float u = Vector3DotProduct(p, right) * (1.0f / (mp->scale[0] ? mp->scale[0] : 1.0f)) + mp->shift[0];
268
	// Apply rotation
245
	float v = Vector3DotProduct(p, up) * (1.0f / (mp->scale[1] ? mp->scale[1] : 1.0f)) + mp->shift[1];
269
	if (mp->rotate != 0.0f) {
  
270
		float angle = mp->rotate * (PI / 180.0f);
  
271
		float sinA = sinf(angle);
  
272
		float cosA = cosf(angle);
  
273
		float ru = u * cosA - v * sinA;
  
274
		float rv = u * sinA + v * cosA;
  
275
		u = ru;
  
276
		v = rv;
  
277
	}
246
  
278
  
247
	return (Vector2){ u / 64.0f, v / 64.0f };
279
	// Apply scale, shift
  
280
	float scaleU = mp->scale[0] ? mp->scale[0] : 1.0f;
  
281
	float scaleV = mp->scale[1] ? mp->scale[1] : 1.0f;
  
282
  
  
283
	u = u / scaleU + mp->shift[0];
  
284
	v = v / scaleV + mp->shift[1];
  
285
  
  
286
	return (Vector2){ u / (float)texWidth, v / (float)texHeight };
248
}
287
}
249
  
288
  
250
void unload_map(void) {
289
void unload_map(void) {
...
355
							array_push(group->vertices, v0.x); array_push(group->vertices, v0.y); array_push(group->vertices, v0.z);
394
							array_push(group->vertices, v0.x); array_push(group->vertices, v0.y); array_push(group->vertices, v0.z);
356
							array_push(group->vertices, v1.x); array_push(group->vertices, v1.y); array_push(group->vertices, v1.z);
395
							array_push(group->vertices, v1.x); array_push(group->vertices, v1.y); array_push(group->vertices, v1.z);
357
							array_push(group->vertices, v2.x); array_push(group->vertices, v2.y); array_push(group->vertices, v2.z);
396
							array_push(group->vertices, v2.x); array_push(group->vertices, v2.y); array_push(group->vertices, v2.z);
358
							Vector2 uv0 = get_uv(v0, mp, plane);
397
							Texture2D tex = get_texture(mp->texture);
359
							Vector2 uv1 = get_uv(v1, mp, plane);
398
							Vector2 uv0 = get_uv(v0, mp, plane, tex.width, tex.height);
360
							Vector2 uv2 = get_uv(v2, mp, plane);
399
							Vector2 uv1 = get_uv(v1, mp, plane, tex.width, tex.height);
  
400
							Vector2 uv2 = get_uv(v2, mp, plane, tex.width, tex.height);
361
							array_push(group->texcoords, uv0.x); array_push(group->texcoords, uv0.y);
401
							array_push(group->texcoords, uv0.x); array_push(group->texcoords, uv0.y);
362
							array_push(group->texcoords, uv1.x); array_push(group->texcoords, uv1.y);
402
							array_push(group->texcoords, uv1.x); array_push(group->texcoords, uv1.y);
363
							array_push(group->texcoords, uv2.x); array_push(group->texcoords, uv2.y);
403
							array_push(group->texcoords, uv2.x); array_push(group->texcoords, uv2.y);
...