implemented mvp for camera and tilemap rendering
This commit is contained in:
parent
972a4d86fa
commit
2981e05419
37
src/camera.c
37
src/camera.c
|
@ -5,16 +5,37 @@ Camera g_camera;
|
||||||
|
|
||||||
void camera_init() {
|
void camera_init() {
|
||||||
g_camera.centre = ZeroVector;
|
g_camera.centre = ZeroVector;
|
||||||
g_camera.width = 1;
|
g_camera.width = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_FRect render_calculate_unit_rect() {
|
static inline
|
||||||
// If the camera's width is 1, this rectangle should fill the width of the screen.
|
float _camera_height(Camera* self) {
|
||||||
// If the camera's width is 2, this rectangle should fill half the width of the screen.
|
return self->width * ((float)g_render_resolution.y / (float)g_render_resolution.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
float _one() {
|
||||||
|
return g_render_resolution.x / g_camera.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FRect camera_world_to_screen_space(Camera* self, SDL_FRect* world_space) {
|
||||||
|
float unit = _one();
|
||||||
return (SDL_FRect) {
|
return (SDL_FRect) {
|
||||||
.x = -g_camera.centre.x * g_render_resolution.x,
|
.x = (world_space->x - g_camera.centre.x + g_camera.width/2.0) * unit,
|
||||||
.y = -g_camera.centre.y * g_render_resolution.x,
|
.y = (world_space->y - g_camera.centre.y + _camera_height(&g_camera)/2.0) * unit,
|
||||||
.w = g_render_resolution.x / g_camera.width,
|
.w = world_space->w * unit,
|
||||||
.h = g_render_resolution.x / g_camera.width
|
.h = world_space->h * unit
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FRect camera_calculate_unit_rect() {
|
||||||
|
// If the camera's width is 1, this rectangle should fill the width of the screen.
|
||||||
|
// If the camera's width is 2, this rectangle should fill half the width of the screen.
|
||||||
|
float unit = _one();
|
||||||
|
return (SDL_FRect) {
|
||||||
|
.x = (-g_camera.centre.x + g_camera.width/2) * unit,
|
||||||
|
.y = (-g_camera.centre.y + _camera_height(&g_camera)/2) * unit,
|
||||||
|
.w = unit,
|
||||||
|
.h = unit
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ extern void camera_init();
|
||||||
// generate a screen-space rectangle that is exactly 1x1 in world units.
|
// generate a screen-space rectangle that is exactly 1x1 in world units.
|
||||||
// With it's centre on the world origin.
|
// With it's centre on the world origin.
|
||||||
extern SDL_FRect camera_calculate_world_unit_rect(Camera* self);
|
extern SDL_FRect camera_calculate_world_unit_rect(Camera* self);
|
||||||
extern SDL_FRect camera_to_world_space(Camera* self, SDL_FRect* camera_space);
|
extern SDL_FRect camera_screen_to_world_space(Camera* self, SDL_FRect* camera_space);
|
||||||
extern SDL_FRect camera_world_to_camera_space(Camera* self, SDL_FRect* world_space);
|
extern SDL_FRect camera_world_to_screen_space(Camera* self, SDL_FRect* world_space);
|
||||||
|
|
||||||
#endif // !_fencer_camera_h
|
#endif // !_fencer_camera_h
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include "program.h"
|
#include "program.h"
|
||||||
|
#include "tilemap.h"
|
||||||
|
#include "camera.h"
|
||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
#include <SDL2/SDL_image.h>
|
#include <SDL2/SDL_image.h>
|
||||||
#include "tilemap.h"
|
|
||||||
|
|
||||||
SDL_Window* g_window;
|
SDL_Window* g_window;
|
||||||
double g_delta_time;
|
double g_delta_time;
|
||||||
|
@ -22,6 +23,7 @@ int program_run(const struct ProgramSettings* settings) {
|
||||||
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE);
|
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
render_init(g_window, settings);
|
render_init(g_window, settings);
|
||||||
|
camera_init();
|
||||||
|
|
||||||
struct Tilemap map = tilemap_load("resources/box.tilemap.xml");
|
struct Tilemap map = tilemap_load("resources/box.tilemap.xml");
|
||||||
struct Tileset set = {
|
struct Tileset set = {
|
||||||
|
|
|
@ -171,14 +171,16 @@ void tilemap_render(struct Tilemap* self) {
|
||||||
size_t num_tiles = self->dimensions.x * self->dimensions.y;
|
size_t num_tiles = self->dimensions.x * self->dimensions.y;
|
||||||
|
|
||||||
SDL_Rect source_rect = {0, 0, self->tileset.tile_size.x, self->tileset.tile_size.y};
|
SDL_Rect source_rect = {0, 0, self->tileset.tile_size.x, self->tileset.tile_size.y};
|
||||||
SDL_FRect dest_rect = { .w = 1, .h = 1 };
|
SDL_FRect world_dest_rect = { .w = 1, .h = 1 };
|
||||||
|
|
||||||
for(int i = 0; i < num_tiles; ++i) {
|
for(int i = 0; i < num_tiles; ++i) {
|
||||||
source_rect = tileset_index_to_rect(&self->tileset, self->tiles[i]);
|
source_rect = tileset_index_to_rect(&self->tileset, self->tiles[i]);
|
||||||
|
|
||||||
dest_rect.x = (i % self->dimensions.x) * dest_rect.w;
|
world_dest_rect.x = (i % self->dimensions.x) * world_dest_rect.w;
|
||||||
dest_rect.y = (float)floor((float)i / self->dimensions.y) * dest_rect.h;
|
world_dest_rect.y = (float)floor((float)i / self->dimensions.y) * world_dest_rect.h;
|
||||||
|
|
||||||
SDL_RenderCopyF(g_renderer, self->tileset.texture, &source_rect, &dest_rect);
|
SDL_FRect camera_dest_rect = camera_world_to_screen_space(&g_camera, &world_dest_rect);
|
||||||
|
|
||||||
|
SDL_RenderCopyF(g_renderer, self->tileset.texture, &source_rect, &camera_dest_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue