From efa64ffca98ab08d4b82c0f66fff81aebdcd4762 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Mon, 26 Feb 2024 19:08:25 -0500 Subject: [PATCH 1/3] Add shape drawing with shapes_basic_shapes example --- examples/shapes_basic_shapes.c | 105 +++++++++++++++++++++++++++++ index.html | 2 +- nob.c | 5 ++ raylib.js | 119 +++++++++++++++++++++++++++++++-- 4 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 examples/shapes_basic_shapes.c diff --git a/examples/shapes_basic_shapes.c b/examples/shapes_basic_shapes.c new file mode 100644 index 0000000..a34438a --- /dev/null +++ b/examples/shapes_basic_shapes.c @@ -0,0 +1,105 @@ +/******************************************************************************************* +* +* raylib [shapes] example - Draw basic shapes 2d (rectangle, circle, line...) +* +* Example originally created with raylib 1.0, last time updated with raylib 4.2 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +void raylib_js_set_entry(void (*entry)(void)); + +const int screenWidth = 800; +const int screenHeight = 450; +float rotation = 0.0f; + +void GameFrame(void) +{ + // Update + //---------------------------------------------------------------------------------- + rotation += 0.02f; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("some basic shapes available on raylib", 20, 20, 20, DARKGRAY); + + // Circle shapes and lines + DrawCircle(screenWidth/5, 120, 35, DARKBLUE); + //DrawCircleGradient(screenWidth/5, 220, 60, GREEN, SKYBLUE); + DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE); + + // Rectangle shapes and lines + DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED); + //DrawRectangleGradientH(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD); + DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); // NOTE: Uses QUADS internally, not lines + + // Triangle shapes and lines + DrawTriangle((Vector2){ screenWidth/4.0f *3.0f, 80.0f }, + (Vector2){ screenWidth/4.0f *3.0f - 60.0f, 150.0f }, + (Vector2){ screenWidth/4.0f *3.0f + 60.0f, 150.0f }, VIOLET); + + DrawTriangleLines((Vector2){ screenWidth/4.0f*3.0f, 160.0f }, + (Vector2){ screenWidth/4.0f*3.0f - 20.0f, 230.0f }, + (Vector2){ screenWidth/4.0f*3.0f + 20.0f, 230.0f }, DARKBLUE); + + // Polygon shapes and lines + DrawPoly((Vector2){ screenWidth/4.0f*3, 330 }, 6, 80, rotation, BROWN); + DrawPolyLines((Vector2){ screenWidth/4.0f*3, 330 }, 6, 90, rotation, BROWN); + DrawPolyLinesEx((Vector2){ screenWidth/4.0f*3, 330 }, 6, 85, rotation, 6, BEIGE); + + // NOTE: We draw all LINES based shapes together to optimize internal drawing, + // this way, all LINES are rendered in a single draw pass + DrawLine(18, 42, screenWidth - 18, 42, BLACK); + EndDrawing(); + //---------------------------------------------------------------------------------- +} + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - basic shapes drawing"); + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + +#ifdef PLATFORM_WEB + raylib_js_set_entry(GameFrame); +#else + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + GameFrame(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- +#endif + + return 0; +} diff --git a/index.html b/index.html index 960a2cd..a164558 100644 --- a/index.html +++ b/index.html @@ -69,7 +69,7 @@ const wasmPaths = { "tsoding": ["tsoding_ball", "tsoding_snake",], "core": ["core_basic_window", "core_basic_screen_manager", "core_input_keys", "core_input_mouse_wheel",], - "shapes": ["shapes_colors_palette"], + "shapes": ["shapes_basic_shapes", "shapes_colors_palette"], "text": ["text_writing_anim"], "textures": ["textures_logo_raylib"], } diff --git a/nob.c b/nob.c index 15ef36d..4396f4a 100644 --- a/nob.c +++ b/nob.c @@ -23,6 +23,11 @@ Example examples[] = { .bin_path = "./build/core_input_keys", .wasm_path = "./wasm/core_input_keys.wasm", }, + { + .src_path = "./examples/shapes_basic_shapes.c", + .bin_path = "./build/shapes_basic_shapes", + .wasm_path = "./wasm/shapes_basic_shapes.wasm", + }, { .src_path = "./examples/shapes_colors_palette.c", .bin_path = "./build/shapes_colors_palette", diff --git a/raylib.js b/raylib.js index a6a0154..42aab2e 100644 --- a/raylib.js +++ b/raylib.js @@ -144,17 +144,90 @@ class RaylibJs { this.currentMouseWheelMoveState = 0.0; } - DrawCircleV(center_ptr, radius, color_ptr) { + // RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line + DrawLine(startPosX, startPosY, endPosX, endPosY, color_ptr) { const buffer = this.wasm.instance.exports.memory.buffer; - const [x, y] = new Float32Array(buffer, center_ptr, 2); - const [r, g, b, a] = new Uint8Array(buffer, color_ptr, 4); - const color = color_hex_unpacked(r, g, b, a); + const color = getColorFromMemory(buffer, color_ptr); this.ctx.beginPath(); - this.ctx.arc(x, y, radius, 0, 2*Math.PI, false); + this.ctx.moveTo(startPosX, startPosY) + this.ctx.lineTo(endPosX, endPosY); + this.ctx.strokeStyle = color; + this.ctx.lineWidth = 1; + this.ctx.stroke(); + } + + // RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines) + DrawLineV(startPos_ptr, endPos_ptr, color_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [startPosX, startPosY] = new Float32Array(buffer, startPos_ptr, 2); + const [endPosX, endPosY] = new Float32Array(buffer, endPos_ptr, 2); + this.DrawLine(startPosX, startPosY, endPosX, endPosY, color_ptr); + } + + // RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle + DrawCircle(centerX, centerY, radius, color_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const color = getColorFromMemory(buffer, color_ptr); + this.ctx.beginPath(); + this.ctx.arc(centerX, centerY, radius, 0, 2*Math.PI, false); this.ctx.fillStyle = color; this.ctx.fill(); } + // RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) + DrawCircleV(center_ptr, radius, color_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [x, y] = new Float32Array(buffer, center_ptr, 2); + this.DrawCircle(x, y, radius, color_ptr); + } + + // RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline + DrawCircleLines(centerX, centerY, radius, color_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const color = getColorFromMemory(buffer, color_ptr); + this.ctx.beginPath(); + this.ctx.arc(centerX, centerY, radius, 0, 2*Math.PI, false); + this.ctx.strokeStyle = color; + this.ctx.stroke(); + } + + // RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) + DrawPoly(center_ptr, sides, radius, rotation, color_ptr, lineThick = 0) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [centerX, centerY] = new Float32Array(buffer, center_ptr, 2); + const color = getColorFromMemory(buffer, color_ptr); + let angle = (Math.PI * 2)/sides; + this.ctx.save(); + this.ctx.beginPath(); + this.ctx.translate(centerX, centerY); + this.ctx.rotate(rotation); + this.ctx.moveTo(radius, 0); + for (let i = 1; i < sides; i++) { + this.ctx.lineTo(radius * Math.cos(angle * i), radius * Math.sin(angle * i)); + } + this.ctx.closePath(); + this.ctx.restore(); + if (lineThick > 0) { + this.ctx.strokeStyle = color; + this.ctx.lineWidth = lineThick; + this.ctx.stroke(); + } + else { + this.ctx.fillStyle = color; + this.ctx.fill(); + } + } + + // RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides + DrawPolyLines(center_ptr, sides, radius, rotation, color_ptr) { + this.DrawPoly(center_ptr, sides, radius, rotation, color_ptr, 1); + } + + // RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters + DrawPolyLinesEx(center_ptr, sides, radius, rotation, lineThick, color_ptr) { + this.DrawPoly(center_ptr, sides, radius, rotation, color_ptr, lineThick); + } + ClearBackground(color_ptr) { this.ctx.fillStyle = getColorFromMemory(this.wasm.instance.exports.memory.buffer, color_ptr); this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); @@ -184,6 +257,34 @@ class RaylibJs { this.ctx.fillRect(posX, posY, width, height); } + // RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) + DrawTriangle(v1_ptr, v2_ptr, v3_ptr, color_ptr, lines = false) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [v1_x, v1_y] = new Float32Array(buffer, v1_ptr, 2); + const [v2_x, v2_y] = new Float32Array(buffer, v2_ptr, 2); + const [v3_x, v3_y] = new Float32Array(buffer, v3_ptr, 2); + const color = getColorFromMemory(buffer, color_ptr); + this.ctx.beginPath(); + this.ctx.moveTo(v1_x, v1_y); + this.ctx.lineTo(v2_x, v2_y); + this.ctx.lineTo(v3_x, v3_y); + this.ctx.closePath(); + if (lines) { + this.ctx.strokeStyle = color; + this.ctx.stroke(); + } + else { + this.ctx.fillStyle = color; + this.ctx.lineWidth = 1; + this.ctx.fill(); + } + } + + // RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) + DrawTriangleLines(v1_ptr, v2_ptr, v3_ptr, color_ptr) { + this.DrawTriangle(v1_ptr, v2_ptr, v3_ptr, color_ptr, true); + } + IsKeyPressed(key) { return !this.prevPressedKeyState.has(key) && this.currentPressedKeyState.has(key); } @@ -249,6 +350,14 @@ class RaylibJs { this.ctx.fillRect(x, y, w, h); } + DrawRectangleLines(posX, posY, width, height, color_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const color = getColorFromMemory(buffer, color_ptr); + this.ctx.strokeStyle = color; + this.ctx.lineWidth = 1; + this.ctx.strokeRect(posX, posY, width, height); + } + DrawRectangleLinesEx(rec_ptr, lineThick, color_ptr) { const buffer = this.wasm.instance.exports.memory.buffer; const [x, y, w, h] = new Float32Array(buffer, rec_ptr, 4); From ede1f1365f602b510e0e162f61d62b87546833a9 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Mon, 26 Feb 2024 19:09:30 -0500 Subject: [PATCH 2/3] Add compiled shapes_basic_shapes example --- wasm/shapes_basic_shapes.wasm | Bin 0 -> 3277 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 wasm/shapes_basic_shapes.wasm diff --git a/wasm/shapes_basic_shapes.wasm b/wasm/shapes_basic_shapes.wasm new file mode 100755 index 0000000000000000000000000000000000000000..e2fdf4cda3b8b8a7c24d4092cf82cbeca130b07c GIT binary patch literal 3277 zcmaKvU2s%Y630)UJDFrM1G)JSA)ua?AW1ZlD9()6D4ZmKC@S(HD&S<2T*3^KnK(0n zL=6)lK=}St`BDRj2G*)Y-3RugwpiB(9=1wWty&)Tfd^}gvi8CKs^Y;axBE;;h)eCH zW^Vtw``+$8x%bR}L^RU{LI{{w+$uyXoZiokFmyq&eY6(@oL#4V~#!PqIS*dy6<{h1;7IlChYv zIhJluxWY1LjXRdal5QsNoy6W{ZhJPG?4(R{YS{!|KG_5U99WT#<#RoJ)zaHt`BdXK z-7HNd`a}VznKF#|6yq!5Q^$M@dWDxW&54{fI>v%z2j`6qU%WUO%dUzgJ5rlOA)gRf z?q*j+)17X1;nL;#r6^BF`x3FXNIVnCxY>xC%%=M&;;}@L&r<;1AZ39CLVAlJ2m1Pu z$6r`ydAr=MRJuMM$=IHI~w-K*|VXm1;>d_M*5cf_!%JdPgk8w7rAN(=ttI!6u3}h2@aUuUa!ptD0}{9{^tN&WK%w=(0uB&kcnJePBQdi+iWWE%~Rq92xT&+~A?49FF@G`|-4$B)n zhHA!F2ww@yzcZG$;H!kMhUIm}b2W%&74_P!|jdcyM zgRmoH(dt&qtAH+{8^L12E7gNDC1GWGiIW<8Q&&6OGb?~0{9Ml z-l2)88ybmr%6HlGE{!zEEnJ?D$M|@m36Jw^CqNGYp5&a9G|VZ`gMjZbzDM{zs8gU$ zfI1H95U69I-UoXRk4Mdaz*!$q@nby7Fw-y*T~^>}rqe`pecBSvFrFbi3A(IO*H-HN z-uylb$gQih)ZbAcFMbHR7SB-{egyg`;Kv;Pn0grj^%1CZpguI8BVh04M(lm29oihv zbLM%_w0M!omVQV6=jlMS}9$`%Q&LRtok3 zW1BB@(g;QNLBj%l^et?ZL7X&!KVMw=O8g}NIr}gtu_7t)``3^T8YuFw%nL5HIR3=op4p1YKvxK?JDnA9ivJvlj?FOMxq;|u>^}Nl}f7o)r9y`dXmvD7f#6v z`ue_22gA=LupCpr)@{PqVDE%;B3golY5FKDi9}NA82ucGCL%0S%Z*emECWH2OqPBS zM7mS4WY$glia`|Cr&Ar#Y*d7O-DLH&yXg!B$ZU5r8MmXZtq%e#+j^4O9@U;8NnhG9 Rw|-9joVtb{<7}vJ_%C9sD;@v< literal 0 HcmV?d00001 From 876f440aa09e1a5d928d1ad32a309c919ad4900d Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Mon, 26 Feb 2024 19:34:41 -0500 Subject: [PATCH 3/3] DrawPoly: Fix radius when drawing with line thickness --- raylib.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/raylib.js b/raylib.js index 42aab2e..80a0cca 100644 --- a/raylib.js +++ b/raylib.js @@ -196,12 +196,13 @@ class RaylibJs { const buffer = this.wasm.instance.exports.memory.buffer; const [centerX, centerY] = new Float32Array(buffer, center_ptr, 2); const color = getColorFromMemory(buffer, color_ptr); - let angle = (Math.PI * 2)/sides; this.ctx.save(); this.ctx.beginPath(); this.ctx.translate(centerX, centerY); this.ctx.rotate(rotation); + radius -= lineThick; this.ctx.moveTo(radius, 0); + let angle = (Math.PI * 2) / sides; for (let i = 1; i < sides; i++) { this.ctx.lineTo(radius * Math.cos(angle * i), radius * Math.sin(angle * i)); }