gfx: experimental 3d rendering

isolation_bkp/dynres
Dominik Madarász 2021-08-11 19:38:24 +02:00
parent 76e4e81281
commit 3b54750127
4 changed files with 223 additions and 3 deletions

View File

@ -5,7 +5,7 @@ if (NOT raylib_FOUND)
FetchContent_Declare(
raylib
URL https://github.com/raysan5/raylib/archive/master.tar.gz
URL https://github.com/zpl-c/raylib/archive/master.tar.gz
)
FetchContent_GetProperties(raylib)

View File

@ -18,7 +18,7 @@ static uint16_t screenHeight = 900;
static float target_zoom = 1.5f;
static bool request_shutdown;
#include "renderer_v0.c"
#include "renderer_3d.c"
void platform_init() {
InitWindow(screenWidth, screenHeight, "eco2d");

View File

@ -0,0 +1,141 @@
static Camera3D render_camera;
static float zoom_overlay_tran = 0.0f;
static float cam_zoom = 1.5f;
#define CAM_OVERLAY_ZOOM_LEVEL 0.80f
float zpl_lerp(float,float,float);
float zpl_to_degrees(float);
void display_conn_status() {
if (game_is_networked()) {
if (network_client_is_connected()) {
DrawText("Connection: online", 5, 5, 12, GREEN);
} else {
DrawText("Connection: offline", 5, 5, 12, RED);
}
} else {
DrawText("Connection: single-player", 5, 5, 12, BLUE);
}
}
void DEBUG_draw_ground(uint64_t key, entity_view * data) {
(void)key;
switch (data->kind) {
case EKIND_CHUNK: {
world_view *view = game_world_view_get_active();
int32_t size = view->chunk_size * WORLD_BLOCK_SIZE;
int32_t half_size = size >> 1;
int16_t offset = 0;
float x = data->x * size + offset;
float y = data->y * size + offset;
RenderTexture2D tex = GetChunkTexture(key);
DrawCubeTexture(tex.texture, (Vector3){x+half_size, 0.0f, y+half_size}, size, 1.0f, size, WHITE);
}break;
default:break;
}
}
static inline float lerp(float a, float b, float t) { return a * (1.0f - t) + b * t; }
void DEBUG_draw_entities(uint64_t key, entity_view * data) {
(void)key;
uint16_t size = 16;
uint16_t ground_offset = 30;
switch (data->kind) {
case EKIND_DEMO_NPC: {
float x = data->x;
float y = data->y;
DrawSphere((Vector3){x,ground_offset,y}, size, ColorAlpha(BLUE, data->tran_time));
}break;
case EKIND_PLAYER: {
float x = data->x;
float y = data->y;
DrawSphere((Vector3){x,ground_offset,y}, size, ColorAlpha(YELLOW, data->tran_time));
}break;
case EKIND_MACRO_BOT: {
float x = data->x;
float y = data->y;
DrawSphere((Vector3){x,ground_offset,y}, size, ColorAlpha(PURPLE, data->tran_time));
}break;
default:break;
}
}
void DEBUG_draw_entities_low(uint64_t key, entity_view * data) {
(void)key;
switch (data->kind) {
case EKIND_VEHICLE: {
float x = data->x;
float y = data->y;
float const w = 280;
float const h = 150;
EcoDrawCube((Vector3){x,15.0f,y}, w/2.0f, 10.f, h/2.0f, -zpl_to_degrees(data->heading), ColorAlpha(RED, data->tran_time));
}break;
default:break;
}
}
void renderer_draw(void) {
cam_zoom = zpl_lerp(cam_zoom, target_zoom, 0.18);
camera_update();
camera game_camera = camera_get();
#if 1
render_camera.position = (Vector3){game_camera.x, 260.0f*(10.0f-cam_zoom), game_camera.y+50.0f*(10.0f-cam_zoom/2.0f)};
render_camera.target = (Vector3){game_camera.x, 0.0f, game_camera.y};
#else
UpdateCamera(&render_camera);
#endif
ClearBackground(GetColor(0x222034));
BeginMode3D(render_camera);
game_world_view_active_entity_map(DEBUG_draw_ground);
game_world_view_active_entity_map(DEBUG_draw_entities_low);
game_world_view_active_entity_map(DEBUG_draw_entities);
EndMode3D();
}
void renderer_init(void) {
render_camera.up = (Vector3){0.0f,0.0f,-1.0f};
render_camera.fovy = 45.f;
render_camera.projection = CAMERA_PERSPECTIVE;
#if 1
SetCameraMode(render_camera, CAMERA_MODE_STATIONARY);
#else
render_camera.position = (Vector3){10,10,10};
render_camera.target = (Vector3){0};
SetCameraMode(render_camera, CAMERA_ORBITAL);
#endif
// NOTE(zaklaus): Paint the screen before we load the game
// TODO(zaklaus): Render a cool loading screen background maybe? :wink: :wink:
BeginDrawing();
ClearBackground(GetColor(0x222034));
char const *loading_text = "zpl.eco2d (in 3d) is loading...";
int text_w = MeasureText(loading_text, 120);
DrawText(loading_text, GetScreenWidth()-text_w-15, GetScreenHeight()-135, 120, RAYWHITE);
EndDrawing();
blocks_setup();
assets_setup();
}
void renderer_shutdown(void) {
blocks_destroy();
assets_destroy();
}

View File

@ -4,6 +4,8 @@
#include "world/blocks.h"
#include "assets.h"
#include "rlgl.h"
static inline
void DrawTextEco(const char *text, float posX, float posY, int fontSize, Color color, float spacing) {
#if 1
@ -70,4 +72,81 @@ Image GetSpriteImage(uint16_t id) {
static inline
Sound GetSound(uint16_t id) {
return *(Sound*)assets_get_snd(id);
}
}
// Draw cube
// NOTE: Cube position is the center position
static inline
void EcoDrawCube(Vector3 position, float width, float height, float length, float heading, Color color)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlCheckRenderBatchLimit(36);
rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
rlTranslatef(position.x, position.y, position.z);
rlRotatef(heading, 0, 1, 0);
//rlScalef(1.0f, 1.0f, 1.0f); // NOTE: Vertices are directly scaled on definition
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front face
rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left
rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right
rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left
rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Right
rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left
rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right
// Back face
rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Left
rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left
rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right
rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right
rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right
rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left
// Top face
rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left
rlVertex3f(x - width/2, y + height/2, z + length/2); // Bottom Left
rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right
rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right
rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left
rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right
// Bottom face
rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Left
rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right
rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left
rlVertex3f(x + width/2, y - height/2, z - length/2); // Top Right
rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right
rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Left
// Right face
rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right
rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right
rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left
rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left
rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right
rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left
// Left face
rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right
rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left
rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Right
rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left
rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left
rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right
rlEnd();
rlPopMatrix();
}