improve boid rendering

This commit is contained in:
Rokas Puzonas 2023-08-05 21:12:21 +03:00
parent f108649ef0
commit a98f423873
5 changed files with 153 additions and 31 deletions

View File

@ -19,6 +19,7 @@ DEBUG_MODE := no
COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -O3 -flto -msse4.2 -mavx
COMPILER_FLAGS += -DRPROF_IMPLEMENTATION
COMPILER_FLAGS += -DRAYGUI_IMPLEMENTATION
COMPILER_FLAGS += -Idepends/raylib/src/external
LINKER_FLAGS := -lraylib
# SOURCES := $(wildcard src/*.cpp)
@ -82,6 +83,7 @@ ifeq ($(PLATFORM), web)
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
COMPILER_FLAGS += -I$(EMSCRIPTEN_PATH)/cache/sysroot/include
COMPILER_FLAGS += -D_DEFAULT_SOURCE
COMPILER_FLAGS += -DGRAPHICS_API_OPENGL_ES2
COMPILER_FLAGS += -msimd128
LINKER_FLAGS += -s USE_GLFW=3
LINKER_FLAGS += -s FORCE_FILESYSTEM=1

View File

@ -1,8 +1,10 @@
-Idepends/raylib-cpp/include/
-Idepends/raylib/src/
-Idepends/raygui/src/
-Idepends/raylib/src/external
-DRLGL_IMPLEMENTATION
-DRPROF_IMPLEMENTATION
-DRAYGUI_IMPLEMENTATION
-DPLATFORM_DESKTOP
-DDEBUG
-DSIMD256

View File

@ -2,8 +2,7 @@
#include <vector>
#include <assert.h>
#include <raylib-cpp.hpp>
#include "rlgl.h"
#include "raylib.h"
#include "memory-arena.hpp"
@ -66,6 +65,16 @@ struct Visuals {
Camera2D camera;
struct {
uint32_t id;
int32_t vertex_position_loc;
int32_t frag_color_loc;
int32_t mvp_loc;
uint32_t vao;
uint32_t vbo;
} boid_shader;
bool show_control_panel = true;
bool draw_boid_direction = false;

View File

@ -1,5 +1,3 @@
#include "raylib.h"
#include "raymath.h"
#include <cmath>
#include <optional>
@ -10,12 +8,10 @@
// #define RPROF_ONLY_TOTAL_TIME
#include "rprof.h"
#include "boid-playground.hpp"
#include "world.cpp"
#include "raycast.cpp"
#include "memory-arena.cpp"
#include "boid-list.cpp"
#include "world.cpp"
#include "ui.cpp"
#define FRAMERATE 60
@ -42,8 +38,8 @@ int main() {
int screen_width = 1280;
int screen_height = 720;
raylib::Window window(screen_width, screen_height, "Boid Playground");
window.SetState(FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
InitWindow(screen_width, screen_height, "Boid Playground");
SetWindowState(FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
GuiLoadStyleDefault();
@ -64,13 +60,14 @@ int main() {
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(FRAMERATE);
while (!window.ShouldClose()) {
while (!WindowShouldClose()) {
UpdateDrawFrame();
}
#endif
window.Close();
world_free(&g_world);
visuals_cleanup(&g_visuals);
CloseWindow();
rprof_end();

View File

@ -1,10 +1,80 @@
#include "boid-playground.hpp"
#if defined(PLATFORM_DESKTOP)
#if defined(GRAPHICS_API_OPENGL_ES2)
#include "glad_gles2.h" // Required for: OpenGL functionality
#define glGenVertexArrays glGenVertexArraysOES
#define glBindVertexArray glBindVertexArrayOES
#define glDeleteVertexArrays glDeleteVertexArraysOES
#define GLSL_VERSION 100
#else
#if defined(__APPLE__)
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#include <OpenGL/gl3ext.h> // OpenGL 3 extensions library for OSX
#else
#include "glad.h" // Required for: OpenGL functionality
#endif
#define GLSL_VERSION 330
#endif
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
#define GL_GLEXT_PROTOTYPES
//#include <EGL/egl.h> // EGL library -> not required, platform layer
#include <GLES2/gl2.h> // OpenGL ES 2.0 library
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
#endif
#include "rlgl.h"
#if defined(GRAPHICS_API_OPENGL_21)
#define GLSL_SHADER_HEADER "#version 120\n"
#define GLSL_VERT_SHADER_HEADER GLSL_SHADER_HEADER
#define GLSL_FRAG_SHADER_HEADER GLSL_SHADER_HEADER "varying vec4 outputColor;\n"
#define GLSL_FRAG_OUTPUT_COLOR "outputColor"
#define GLSL_IN "attribute "
#define GLSL_OUT "varying "
#elif defined(GRAPHICS_API_OPENGL_33)
#define GLSL_SHADER_HEADER "#version 330\n"
#define GLSL_VERT_SHADER_HEADER GLSL_SHADER_HEADER
#define GLSL_FRAG_SHADER_HEADER GLSL_SHADER_HEADER "out vec4 outputColor;\n"
#define GLSL_FRAG_OUTPUT_COLOR "outputColor"
#define GLSL_IN "in "
#define GLSL_OUT "out "
#elif defined(GRAPHICS_API_OPENGL_ES2)
#define GLSL_SHADER_HEADER "#version 100\n"
#define GLSL_VERT_SHADER_HEADER GLSL_SHADER_HEADER
#define GLSL_FRAG_SHADER_HEADER GLSL_SHADER_HEADER "precision mediump float;"
#define GLSL_FRAG_OUTPUT_COLOR "gl_FragColor"
#define GLSL_IN "attribute "
#define GLSL_OUT "varying "
#endif
#include "raymath.h"
#include "raycast.hpp"
#include "rprof.h"
#include "boid-list.hpp"
#include "simd.cpp"
#define BOID_VERT_SHADER \
GLSL_VERT_SHADER_HEADER \
GLSL_IN "vec2 vertexPosition;\n" \
"uniform mat4 mvp;\n" \
"void main()\n" \
"{\n" \
" gl_Position = mvp*vec4(vertexPosition.x, vertexPosition.y, 0.0, 1.0);\n" \
"}\0"
#define BOID_FRAG_SHADER \
GLSL_FRAG_SHADER_HEADER \
"uniform vec4 fragColor;\n" \
"void main()\n" \
"{\n" \
" " GLSL_FRAG_OUTPUT_COLOR " = fragColor;\n" \
"}\0"
static float vector2_atan2(Vector2 a) {
return std::atan2(a.y, a.x);
}
@ -117,15 +187,41 @@ static void world_init(World *world, float width, float height) {
world->size = { width, height };
}
static void visuals_init(World *world, Visuals *visuals) {
visuals->camera = { 0 };
visuals->camera.zoom = 1;
}
static void world_free(World *world) {
arena_free(&world->frame_arena);
}
static int visuals_init(World *world, Visuals *visuals) {
visuals->camera = { 0 };
visuals->camera.zoom = 1;
int vert_shader_id = rlCompileShader(BOID_VERT_SHADER, GL_VERTEX_SHADER);
int frag_shader_id = rlCompileShader(BOID_FRAG_SHADER, GL_FRAGMENT_SHADER);
int shader_id = rlLoadShaderProgram(vert_shader_id, frag_shader_id);
if (shader_id <= 0) return -1;
visuals->boid_shader.id = shader_id;
visuals->boid_shader.vertex_position_loc = glGetAttribLocation(shader_id, "vertexPosition");
visuals->boid_shader.frag_color_loc = glGetUniformLocation(shader_id, "fragColor");
visuals->boid_shader.mvp_loc = glGetUniformLocation(shader_id, "mvp");
visuals->boid_shader.vao = rlLoadVertexArray();
unsigned int vertex_position_buffer = 0;
rlEnableVertexArray(visuals->boid_shader.vao);
glGenBuffers(1, &visuals->boid_shader.vbo);
rlDisableVertexArray();
return 0;
}
static void visuals_cleanup(Visuals *visuals) {
glDeleteBuffers(1, &visuals->boid_shader.vbo);
rlUnloadVertexArray(visuals->boid_shader.vao);
rlUnloadShaderProgram(visuals->boid_shader.id);
}
// --------------------- Utils -----------------------
void world_adjust_boid_count(World *world, int new_boid_count) {
@ -609,15 +705,15 @@ static void draw_circle_sector(Vector2 center, float radius, float start_angle,
}
static void draw_boids(World *world, Visuals *visuals) {
int boid_count = world->boids.size();
float boid_length = visuals->boid_edge_size * std::sqrt(3)/2;
float boid_width = visuals->boid_edge_size * 0.6;
Color color = visuals->boid_color;
int boid_count = world->boids.size();
int vertex_count = boid_count*3;
Vector2 *vertices = (Vector2*)arena_malloc(&world->frame_arena, vertex_count);
rlBegin(RL_TRIANGLES);
for (int i = 0; i < boid_count; i++) {
Boid *boid = &world->boids[i];
Vector2 *boid_vertices = &vertices[3*i];
Vector2 triangle[] = {
{ boid_length*2/3.0f, 0 },
@ -627,20 +723,36 @@ static void draw_boids(World *world, Visuals *visuals) {
float facing = std::atan2(boid->dir.y, boid->dir.x);
float facing_cos = cos(facing);
float facing_sin = sin(facing);
for (int i = 0; i < 3; i++) {
Vector2 new_pos = boid->pos;
new_pos.x += triangle[i].x * facing_cos - triangle[i].y * facing_sin;
new_pos.y += triangle[i].x * facing_sin + triangle[i].y * facing_cos;
triangle[i] = new_pos;
for (int j = 0; j < 3; j++) {
boid_vertices[j].x = boid->pos.x + (triangle[j].x * facing_cos - triangle[j].y * facing_sin);
boid_vertices[j].y = boid->pos.y + (triangle[j].x * facing_sin + triangle[j].y * facing_cos);
}
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(triangle[0].x, triangle[0].y);
rlVertex2f(triangle[1].x, triangle[1].y);
rlVertex2f(triangle[2].x, triangle[2].y);
}
rlEnd();
rlDrawRenderBatchActive();
int32_t vertex_position_loc = visuals->boid_shader.vertex_position_loc;
int32_t frag_color_loc = visuals->boid_shader.frag_color_loc;
int32_t mvp_loc = visuals->boid_shader.mvp_loc;
uint32_t vao = visuals->boid_shader.vao;
uint32_t vbo = visuals->boid_shader.vbo;
Color color = visuals->boid_color;
glUseProgram(visuals->boid_shader.id);
Matrix modelViewProjection = MatrixMultiply(rlGetMatrixModelview(), rlGetMatrixProjection());
glUniformMatrix4fv(mvp_loc, 1, false, MatrixToFloat(modelViewProjection));
glUniform4f(frag_color_loc, (float)color.r/255, (float)color.g/255, (float)color.b/255, (float)color.a/255);
rlEnableVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertex_count*sizeof(Vector2), vertices, GL_DYNAMIC_DRAW);
glVertexAttribPointer(vertex_position_loc, 2, GL_FLOAT, 0, 0, NULL);
rlEnableVertexAttribute(vertex_position_loc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, vertex_count);
rlDisableVertexArray();
glUseProgram(0);
}
static void visuals_update(World *world, Visuals *visuals) {