diff --git a/examples/textures_logo_raylib_tint.c b/examples/textures_logo_raylib_tint.c new file mode 100644 index 0000000..6f75a88 --- /dev/null +++ b/examples/textures_logo_raylib_tint.c @@ -0,0 +1,70 @@ +/******************************************************************************************* +* +* raylib [textures] example - Texture loading and drawing +* +* Example originally created with raylib 1.0, last time updated with raylib 1.0 +* +* 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; +Texture2D texture = {0}; + +void GameFrame() { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, RED); + + DrawText("this IS a texture!", 360, 370, 10, GRAY); + + EndDrawing(); +} + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture loading and drawing"); + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + texture = LoadTexture("resources/raylib_logo.png"); // Texture loading + //--------------------------------------------------------------------------------------- + +#ifdef PLATFORM_WEB + raylib_js_set_entry(GameFrame); +#else + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + GameFrame(); + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- +#endif + return 0; +} diff --git a/index.html b/index.html index 960a2cd..d8d9e2d 100644 --- a/index.html +++ b/index.html @@ -71,7 +71,7 @@ "core": ["core_basic_window", "core_basic_screen_manager", "core_input_keys", "core_input_mouse_wheel",], "shapes": ["shapes_colors_palette"], "text": ["text_writing_anim"], - "textures": ["textures_logo_raylib"], + "textures": ["textures_logo_raylib", "textures_logo_raylib_tint"], } const defaultWasm = Object.values(wasmPaths)[0][0]; diff --git a/nob.c b/nob.c index 15ef36d..31b9491 100644 --- a/nob.c +++ b/nob.c @@ -48,6 +48,16 @@ Example examples[] = { .bin_path = "./build/text_writing_anim", .wasm_path = "./wasm/text_writing_anim.wasm", }, + { + .src_path = "./examples/textures_logo_raylib.c", + .bin_path = "./build/textures_logo_raylib", + .wasm_path = "./wasm/textures_logo_raylib.wasm", + }, + { + .src_path = "./examples/textures_logo_raylib_tint.c", + .bin_path = "./build/textures_logo_raylib_tint", + .wasm_path = "./wasm/textures_logo_raylib_tint.wasm", + }, }; bool build_native(void) diff --git a/raylib.js b/raylib.js index a6a0154..e0b09db 100644 --- a/raylib.js +++ b/raylib.js @@ -61,8 +61,9 @@ class RaylibJs { } const canvas = document.getElementById(canvasId); + this.btx = document.createElement("canvas").getContext("2d"); this.ctx = canvas.getContext("2d"); - if (this.ctx === null) { + if (this.ctx === null || this.btx === null) { throw new Error("Could not create 2d canvas context"); } @@ -109,6 +110,8 @@ class RaylibJs { InitWindow(width, height, title_ptr) { this.ctx.canvas.width = width; this.ctx.canvas.height = height; + this.btx.canvas.width = width; + this.btx.canvas.height = height; const buffer = this.wasm.instance.exports.memory.buffer; document.title = cstr_by_ptr(buffer, title_ptr); } @@ -301,13 +304,28 @@ class RaylibJs { } // RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); - DrawTexture(texture_ptr, posX, posY, color_ptr) { + DrawTexture(texture_ptr, posX, posY, tint_ptr) { + /** @type {ArrayBuffer} */ const buffer = this.wasm.instance.exports.memory.buffer; - const [id, width, height, mipmaps, format] = new Uint32Array(buffer, texture_ptr, 5); - // // TODO: implement tinting for DrawTexture - // const tint = getColorFromMemory(buffer, color_ptr); - - this.ctx.drawImage(this.images[id], posX, posY); + let [id, width, height, mipmaps, format] = new Uint32Array(buffer, texture_ptr); + const tint = getColorFromMemory(buffer, tint_ptr); + const texture = this.images[id]; + if (texture === undefined) { + // TODO: Better error reporting + throw new Error(`textureID ${id} not found.`); + } + // TODO: actually use width / height from the passed struct + width = texture.width; + height = texture.height; + this.btx.clearRect(0, 0, width, height); + this.btx.drawImage(texture, 0, 0); + this.btx.fillStyle = tint; + this.btx.globalCompositeOperation = "multiply"; + this.btx.fillRect(0, 0, width, height); + this.btx.globalCompositeOperation = "destination-in"; + this.btx.drawImage(texture, 0, 0); + this.btx.globalCompositeOperation = "source-over"; + this.ctx.drawImage(this.btx.canvas, 0, 0, width, height, posX, posY, width, height); } // TODO: codepoints are not implemented diff --git a/wasm/textures_logo_raylib_tint.wasm b/wasm/textures_logo_raylib_tint.wasm new file mode 100755 index 0000000..9287e50 Binary files /dev/null and b/wasm/textures_logo_raylib_tint.wasm differ