From 25c6c12150d6f0aeea83d55d1a0f16e12a3effd3 Mon Sep 17 00:00:00 2001 From: Jussi Viitala Date: Sat, 18 Nov 2023 21:02:33 +0200 Subject: Added glsl 100 and 120 shaders to lightmap example. (#3543) * Added glsl 100 and 120 shaders to lightmap example. * Fixed lightmap example resource loading on web. --- examples/Makefile.Web | 8 +++--- .../shaders/resources/shaders/glsl100/lightmap.fs | 22 +++++++++++++++ .../shaders/resources/shaders/glsl100/lightmap.vs | 31 ++++++++++++++++++++++ .../shaders/resources/shaders/glsl120/lightmap.fs | 20 ++++++++++++++ .../shaders/resources/shaders/glsl120/lightmap.vs | 31 ++++++++++++++++++++++ examples/shaders/shaders_lightmap.c | 1 - 6 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 examples/shaders/resources/shaders/glsl100/lightmap.fs create mode 100644 examples/shaders/resources/shaders/glsl100/lightmap.vs create mode 100644 examples/shaders/resources/shaders/glsl120/lightmap.fs create mode 100644 examples/shaders/resources/shaders/glsl120/lightmap.vs (limited to 'examples') diff --git a/examples/Makefile.Web b/examples/Makefile.Web index e8a72661..aa42d722 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -968,10 +968,10 @@ shaders/shaders_julia_set: shaders/shaders_julia_set.c shaders/shaders_lightmap: shaders/shaders_lightmap.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s FORCE_FILESYSTEM=1 \ - --preload-file shaders/resources/shaders/glsl330/lightmap.vs \ - --preload-file shaders/resources/shaders/glsl330/lightmap.fs \ - --preload-file shaders/resources/cubicmap_atlas.png \ - --preload-file shaders/resources/spark_flame.png + --preload-file shaders/resources/shaders/glsl100/lightmap.vs@resources/shaders/glsl100/lightmap.vs \ + --preload-file shaders/resources/shaders/glsl100/lightmap.fs@resources/shaders/glsl100/lightmap.fs \ + --preload-file shaders/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png \ + --preload-file shaders/resources/spark_flame.png@resources/spark_flame.png shaders/shaders_mesh_instancing: shaders/shaders_mesh_instancing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ diff --git a/examples/shaders/resources/shaders/glsl100/lightmap.fs b/examples/shaders/resources/shaders/glsl100/lightmap.fs new file mode 100644 index 00000000..9f0bcd27 --- /dev/null +++ b/examples/shaders/resources/shaders/glsl100/lightmap.fs @@ -0,0 +1,22 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec2 fragTexCoord2; +varying vec3 fragPosition; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D texture1; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec4 texelColor2 = texture2D(texture1, fragTexCoord2); + + gl_FragColor = texelColor * texelColor2; +} diff --git a/examples/shaders/resources/shaders/glsl100/lightmap.vs b/examples/shaders/resources/shaders/glsl100/lightmap.vs new file mode 100644 index 00000000..f5d87b3e --- /dev/null +++ b/examples/shaders/resources/shaders/glsl100/lightmap.vs @@ -0,0 +1,31 @@ +#version 100 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec2 vertexTexCoord2; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; + +// Output vertex attributes (to fragment shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec2 fragTexCoord2; +varying vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragTexCoord2 = vertexTexCoord2; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} diff --git a/examples/shaders/resources/shaders/glsl120/lightmap.fs b/examples/shaders/resources/shaders/glsl120/lightmap.fs new file mode 100644 index 00000000..93a0609e --- /dev/null +++ b/examples/shaders/resources/shaders/glsl120/lightmap.fs @@ -0,0 +1,20 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec2 fragTexCoord2; +varying vec3 fragPosition; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D texture1; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec4 texelColor2 = texture2D(texture1, fragTexCoord2); + + gl_FragColor = texelColor * texelColor2; +} diff --git a/examples/shaders/resources/shaders/glsl120/lightmap.vs b/examples/shaders/resources/shaders/glsl120/lightmap.vs new file mode 100644 index 00000000..9847b253 --- /dev/null +++ b/examples/shaders/resources/shaders/glsl120/lightmap.vs @@ -0,0 +1,31 @@ +#version 120 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec2 vertexTexCoord2; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; + +// Output vertex attributes (to fragment shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec2 fragTexCoord2; +varying vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragTexCoord2 = vertexTexCoord2; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} diff --git a/examples/shaders/shaders_lightmap.c b/examples/shaders/shaders_lightmap.c index c5ed6094..445d81d2 100644 --- a/examples/shaders/shaders_lightmap.c +++ b/examples/shaders/shaders_lightmap.c @@ -170,4 +170,3 @@ int main(void) return 0; } - -- cgit v1.2.3 From 21469e92b0a886de8b384b7ffadc5c1c73cff913 Mon Sep 17 00:00:00 2001 From: Karim <35817819+Kimo-s@users.noreply.github.com> Date: Sat, 18 Nov 2023 14:05:45 -0500 Subject: Image convolution function ImageKernelConvolution (#3528) * Added image convultion ImageKernelConvolution * comment changes * spelling changes and change to kernel size * removed kernel normalization inside function * fix to formating --- examples/Makefile | 1 + examples/textures/textures_image_kernel.c | 127 ++++++++++++++++++ .../Notepad++/raylib_npp_parser/raylib_to_parse.h | 1 + src/raylib.h | 1 + src/rtextures.c | 142 +++++++++++++++++++++ 5 files changed, 272 insertions(+) create mode 100644 examples/textures/textures_image_kernel.c (limited to 'examples') diff --git a/examples/Makefile b/examples/Makefile index 5cd8e6bb..11669e3a 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -490,6 +490,7 @@ TEXTURES = \ textures/textures_gif_player \ textures/textures_image_drawing \ textures/textures_image_generation \ + textures/textures_image_kernel \ textures/textures_image_loading \ textures/textures_image_processing \ textures/textures_image_rotate \ diff --git a/examples/textures/textures_image_kernel.c b/examples/textures/textures_image_kernel.c new file mode 100644 index 00000000..cbc75e18 --- /dev/null +++ b/examples/textures/textures_image_kernel.c @@ -0,0 +1,127 @@ +/******************************************************************************************* +* +* raylib [textures] example - Image loading and texture creation +* +* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) +* +* Example originally created with raylib 1.3, last time updated with raylib 1.3 +* +* 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) 2015-2023 Karim Salem (@kimo-s) +* +********************************************************************************************/ + +#include "raylib.h" + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +void normalizeKernel(float *kernel, int size){ + float sum = 0.0f; + for(int i = 0; i < size; i++) + { + sum += kernel[i]; + } + + if(sum != 0.0f) + { + for(int i = 0; i < size; i++) + { + kernel[i] /= sum; + } + } +} + +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + + Image image = LoadImage("resources/cat.png"); // Loaded in CPU memory (RAM) + + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - image convolution"); + + float gaussiankernel[] = {1.0, 2.0, 1.0, + 2.0, 4.0, 2.0, + 1.0, 2.0, 1.0}; + + float sobelkernel[] = {1.0, 0.0, -1.0, + 2.0, 0.0, -2.0, + 1.0, 0.0, -1.0}; + + float sharpenkernel[] = {0.0, -1.0, 0.0, + -1.0, 5.0, -1.0, + 0.0, -1.0, 0.0}; + + normalizeKernel(gaussiankernel, 9); + normalizeKernel(sharpenkernel, 9); + normalizeKernel(sobelkernel, 9); + + Image catSharpend = ImageCopy(image); + ImageKernelConvolution(&catSharpend, sharpenkernel, 9); + + Image catSobel = ImageCopy(image); + ImageKernelConvolution(&catSobel, sobelkernel, 9); + + Image catGaussian = ImageCopy(image); + for(int i = 0; i < 6; i++) + { + ImageKernelConvolution(&catGaussian, gaussiankernel, 9); + } + + ImageCrop(&image, (Rectangle){ 0, 0, (float)200, (float)450 }); + ImageCrop(&catGaussian, (Rectangle){ 0, 0, (float)200, (float)450 }); + ImageCrop(&catSobel, (Rectangle){ 0, 0, (float)200, (float)450 }); + ImageCrop(&catSharpend, (Rectangle){ 0, 0, (float)200, (float)450 }); + Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM) + Texture2D catSharpendTexture = LoadTextureFromImage(catSharpend); + Texture2D catSobelTexture = LoadTextureFromImage(catSobel); + Texture2D catGaussianTexture = LoadTextureFromImage(catGaussian); + UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM + UnloadImage(catGaussian); + UnloadImage(catSobel); + UnloadImage(catSharpend); + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawTexture(catSharpendTexture, 0, 0, WHITE); + DrawTexture(catSobelTexture, 200, 0, WHITE); + DrawTexture(catGaussianTexture, 400, 0, WHITE); + DrawTexture(texture, 600, 0, WHITE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(texture); // Texture unloading + UnloadTexture(catGaussianTexture); + UnloadTexture(catSobelTexture); + UnloadTexture(catSharpendTexture); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h index 2c033c91..8776d434 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +++ b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h @@ -375,6 +375,7 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation +RLAPI void ImageKernelConvolution(Image *image, float* kernel, int kernelSize); // Apply Custom Square image convolution kernel RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color diff --git a/src/raylib.h b/src/raylib.h index 6ea00300..28f052c7 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1329,6 +1329,7 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation +RLAPI void ImageKernelConvolution(Image *image, float* kernel, int kernelSize); // Apply Custom Square image convolution kernel RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color diff --git a/src/rtextures.c b/src/rtextures.c index 98586db7..8742b0c9 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -2082,6 +2082,148 @@ void ImageBlurGaussian(Image *image, int blurSize) { ImageFormat(image, format); } +// The kernel matrix is assumed to be square. Only supply the width of the kernel. +void ImageKernelConvolution(Image *image, float* kernel, int kernelSize){ + + if ((image->data == NULL) || (image->width == 0) || (image->height == 0) || kernel == NULL) return; + + int kernelWidth = (int)sqrtf((float)kernelSize); + if (kernelWidth*kernelWidth != kernelSize) + { + TRACELOG(LOG_WARNING, "IMAGE: Convolution kernel must be square to be applied"); + return; + } + + Color *pixels = LoadImageColors(*image); + + Vector4 *imageCopy2 = RL_MALLOC((image->height)*(image->width)*sizeof(Vector4)); + Vector4 *temp = RL_MALLOC(kernelSize*sizeof(Vector4)); + + + for(int i = 0; i < kernelSize; i++){ + temp[i].x = 0.0f; + temp[i].y = 0.0f; + temp[i].z = 0.0f; + temp[i].w = 0.0f; + } + + float rRes = 0.0f; + float gRes = 0.0f; + float bRes = 0.0f; + float aRes = 0.0f; + + + int startRange, endRange; + if(kernelWidth % 2 == 0) + { + startRange = -kernelWidth/2; + endRange = kernelWidth/2; + } else + { + startRange = -kernelWidth/2; + endRange = kernelWidth/2+1; + } + for(int x = 0; x < image->height; x++) + { + for(int y = 0; y < image->width; y++) + { + + for(int xk = startRange; xk < endRange; xk++) + { + for(int yk = startRange; yk < endRange; yk++) + { + int xkabs = xk + kernelWidth/2; + int ykabs = yk + kernelWidth/2; + size_t imgindex = image->width * (x+xk) + (y+yk); + if(imgindex < 0 || imgindex >= image->width * image->height){ + temp[kernelWidth * xkabs + ykabs].x = 0.0f; + temp[kernelWidth * xkabs + ykabs].y = 0.0f; + temp[kernelWidth * xkabs + ykabs].z = 0.0f; + temp[kernelWidth * xkabs + ykabs].w = 0.0f; + } else { + temp[kernelWidth * xkabs + ykabs].x = ((float)pixels[imgindex].r)/255.0f * kernel[kernelWidth * xkabs + ykabs]; + temp[kernelWidth * xkabs + ykabs].y = ((float)pixels[imgindex].g)/255.0f * kernel[kernelWidth * xkabs + ykabs]; + temp[kernelWidth * xkabs + ykabs].z = ((float)pixels[imgindex].b)/255.0f * kernel[kernelWidth * xkabs + ykabs]; + temp[kernelWidth * xkabs + ykabs].w = ((float)pixels[imgindex].a)/255.0f * kernel[kernelWidth * xkabs + ykabs]; + } + } + } + + for(int i = 0; i < kernelSize; i++) + { + rRes += temp[i].x; + gRes += temp[i].y; + bRes += temp[i].z; + aRes += temp[i].w; + } + + if(rRes < 0.0f) + { + rRes = 0.0f; + } + if(gRes < 0.0f) + { + gRes = 0.0f; + } + if(bRes < 0.0f) + { + bRes = 0.0f; + } + + if(rRes > 1.0f) + { + rRes = 1.0f; + } + if(gRes > 1.0f) + { + gRes = 1.0f; + } + if(bRes > 1.0f) + { + bRes = 1.0f; + } + + imageCopy2[image->width * (x) + (y)].x = rRes; + imageCopy2[image->width * (x) + (y)].y = gRes; + imageCopy2[image->width * (x) + (y)].z = bRes; + imageCopy2[image->width * (x) + (y)].w = aRes; + + rRes = 0.0f; + gRes = 0.0f; + bRes = 0.0f; + aRes = 0.0f; + + for(int i = 0; i < kernelSize; i++) + { + temp[i].x = 0.0f; + temp[i].y = 0.0f; + temp[i].z = 0.0f; + temp[i].w = 0.0f; + } + } + } + + for (int i = 0; i < (image->width) * (image->height); i++) + { + float alpha = (float)imageCopy2[i].w; + pixels[i].r = (unsigned char)((imageCopy2[i].x)*255.0f); + pixels[i].g = (unsigned char)((imageCopy2[i].y)*255.0f); + pixels[i].b = (unsigned char)((imageCopy2[i].z)*255.0f); + pixels[i].a = (unsigned char)((alpha)*255.0f); + // printf("pixels[%d] = %d", i, pixels[i].r); + } + + + int format = image->format; + RL_FREE(image->data); + RL_FREE(imageCopy2); + RL_FREE(temp); + + image->data = pixels; + image->format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + ImageFormat(image, format); +} + // Generate all mipmap levels for a provided image // NOTE 1: Supports POT and NPOT images // NOTE 2: image.data is scaled to include mipmap levels -- cgit v1.2.3 From ce26e26177eb886c4fec16a51581f4611b8a069f Mon Sep 17 00:00:00 2001 From: Sergey Zapunidi Date: Mon, 20 Nov 2023 22:49:58 +0300 Subject: Added missing textures_image_kernel example in web makefile (#3555) * Added missing textures_image_kernel example in web makefile * Added missing --preload-file for textures_image_kernel --------- Co-authored-by: zap --- examples/Makefile.Web | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'examples') diff --git a/examples/Makefile.Web b/examples/Makefile.Web index aa42d722..a3c2bb72 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -396,6 +396,7 @@ TEXTURES = \ textures/textures_gif_player \ textures/textures_image_drawing \ textures/textures_image_generation \ + textures/textures_image_kernel \ textures/textures_image_loading \ textures/textures_image_processing \ textures/textures_image_rotate \ @@ -702,6 +703,10 @@ textures/textures_image_drawing: textures/textures_image_drawing.c textures/textures_image_generation: textures/textures_image_generation.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864 + +textures/textures_image_kernel: textures/textures_image_kernel.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file textures/resources/cat.png@resources/cat.png textures/textures_image_loading: textures/textures_image_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ -- cgit v1.2.3