|
134 | 134 | #define GL_STACK_UNDERFLOW 0x0504
|
135 | 135 | #define GL_OUT_OF_MEMORY 0x0505
|
136 | 136 |
|
| 137 | +#define GL_ALPHA 0x1906 |
| 138 | +#define GL_LUMINANCE 0x1909 |
| 139 | +#define GL_LUMINANCE_ALPHA 0x190A |
| 140 | +#define GL_RGB 0x1907 |
| 141 | +#define GL_RGBA 0x1908 |
| 142 | + |
| 143 | +#define GL_BYTE 0x1400 |
| 144 | +#define GL_UNSIGNED_BYTE 0x1401 |
| 145 | +#define GL_SHORT 0x1402 |
| 146 | +#define GL_UNSIGNED_SHORT 0x1403 |
| 147 | +#define GL_INT 0x1404 |
| 148 | +#define GL_UNSIGNED_INT 0x1405 |
| 149 | +#define GL_FLOAT 0x1406 |
137 | 150 |
|
138 | 151 | /* === RLSW Enums === */
|
139 | 152 |
|
@@ -189,31 +202,21 @@ typedef enum {
|
189 | 202 | } SWfactor;
|
190 | 203 |
|
191 | 204 | typedef enum {
|
192 |
| - SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) |
193 |
| - SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) |
194 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp |
195 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp |
196 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) |
197 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) |
198 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp |
199 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) |
200 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) |
201 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) |
202 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) |
203 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) |
204 |
| - SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) |
205 |
| - SW_PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) |
206 |
| - SW_PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) |
207 |
| - SW_PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp |
208 |
| - SW_PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp |
209 |
| - SW_PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp |
210 |
| - SW_PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp |
211 |
| - SW_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp |
212 |
| - SW_PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp |
213 |
| - SW_PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp |
214 |
| - SW_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp |
215 |
| - SW_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp |
216 |
| -} SWpixelformat; |
| 205 | + SW_LUMINANCE = GL_LUMINANCE, |
| 206 | + SW_LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA, |
| 207 | + SW_RGB = GL_RGB, |
| 208 | + SW_RGBA = GL_RGBA, |
| 209 | +} SWformat; |
| 210 | + |
| 211 | +typedef enum { |
| 212 | + SW_UNSIGNED_BYTE = GL_UNSIGNED_BYTE, |
| 213 | + SW_BYTE = GL_BYTE, |
| 214 | + SW_UNSIGNED_SHORT = GL_UNSIGNED_SHORT, |
| 215 | + SW_SHORT = GL_SHORT, |
| 216 | + SW_UNSIGNED_INT = GL_UNSIGNED_INT, |
| 217 | + SW_INT = GL_INT, |
| 218 | + SW_FLOAT = GL_FLOAT |
| 219 | +} SWtype; |
217 | 220 |
|
218 | 221 | typedef enum {
|
219 | 222 | SW_NEAREST = GL_NEAREST,
|
@@ -312,10 +315,11 @@ void swNormal3fv(const float* v);
|
312 | 315 | void swBindArray(SWarray type, void *buffer);
|
313 | 316 | void swDrawArrays(SWdraw mode, int offset, int count);
|
314 | 317 |
|
315 |
| -uint32_t swLoadTexture(const void *data, int width, int height, int format, int mipmapCount); |
316 |
| -void swUnloadTexture(uint32_t id); |
| 318 | +void swGenTextures(int count, uint32_t* textures); |
| 319 | +void swDeleteTextures(int count, uint32_t* textures); |
317 | 320 |
|
318 |
| -void swTextureParameters(uint32_t id, int param, int value); |
| 321 | +void swTexImage2D(int width, int height, SWformat format, SWtype type, const void* data); |
| 322 | +void swTexParameteri(int param, int value); |
319 | 323 | void swBindTexture(uint32_t id);
|
320 | 324 |
|
321 | 325 | #endif // RLSW_H
|
@@ -348,6 +352,33 @@ void swBindTexture(uint32_t id);
|
348 | 352 |
|
349 | 353 | /* === Internal Structs === */
|
350 | 354 |
|
| 355 | +typedef enum { |
| 356 | + SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) |
| 357 | + SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) |
| 358 | + SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp |
| 359 | + SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp |
| 360 | + SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) |
| 361 | + SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) |
| 362 | + SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp |
| 363 | + SW_PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) |
| 364 | + SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) |
| 365 | + SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) |
| 366 | + SW_PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) |
| 367 | + SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) |
| 368 | + SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) |
| 369 | + SW_PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) |
| 370 | + SW_PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) |
| 371 | + SW_PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp |
| 372 | + SW_PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp |
| 373 | + SW_PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp |
| 374 | + SW_PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp |
| 375 | + SW_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp |
| 376 | + SW_PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp |
| 377 | + SW_PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp |
| 378 | + SW_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp |
| 379 | + SW_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp |
| 380 | +} sw_pixelformat_e; |
| 381 | + |
351 | 382 | typedef float sw_matrix_t[4*4];
|
352 | 383 | typedef uint16_t sw_half_t;
|
353 | 384 |
|
@@ -531,7 +562,54 @@ static inline sw_vertex_t sw_lerp_vertex_PNTCH(const sw_vertex_t* a, const sw_ve
|
531 | 562 | }
|
532 | 563 |
|
533 | 564 |
|
534 |
| -/* === Pixel Format Conversion Part === */ |
| 565 | +/* === Pixel Format Part === */ |
| 566 | + |
| 567 | +int sw_get_pixel_format(SWformat format, SWtype type) |
| 568 | +{ |
| 569 | + int channels = 0; |
| 570 | + int bitsPerChannel = 8; // Default: 8 bits per channel |
| 571 | + |
| 572 | + // Determine the number of channels (format) |
| 573 | + switch (format) { |
| 574 | + case SW_LUMINANCE: channels = 1; break; |
| 575 | + case SW_LUMINANCE_ALPHA: channels = 2; break; |
| 576 | + case SW_RGB: channels = 3; break; |
| 577 | + case SW_RGBA: channels = 4; break; |
| 578 | + default: return -1; // Unknown format |
| 579 | + } |
| 580 | + |
| 581 | + // Determine the depth of each channel (type) |
| 582 | + switch (type) { |
| 583 | + case SW_UNSIGNED_BYTE: bitsPerChannel = 8; break; |
| 584 | + case SW_BYTE: bitsPerChannel = 8; break; |
| 585 | + case SW_UNSIGNED_SHORT: bitsPerChannel = 16; break; |
| 586 | + case SW_SHORT: bitsPerChannel = 16; break; |
| 587 | + case SW_UNSIGNED_INT: bitsPerChannel = 32; break; |
| 588 | + case SW_INT: bitsPerChannel = 32; break; |
| 589 | + case SW_FLOAT: bitsPerChannel = 32; break; |
| 590 | + default: return -1; // Unknown type |
| 591 | + } |
| 592 | + |
| 593 | + // Map the format and type to the correct internal format |
| 594 | + if (bitsPerChannel == 8) { |
| 595 | + if (channels == 1) return SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; |
| 596 | + if (channels == 2) return SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA; |
| 597 | + if (channels == 3) return SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8; |
| 598 | + if (channels == 4) return SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; |
| 599 | + } |
| 600 | + else if (bitsPerChannel == 16) { |
| 601 | + if (channels == 1) return SW_PIXELFORMAT_UNCOMPRESSED_R16; |
| 602 | + if (channels == 3) return SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16; |
| 603 | + if (channels == 4) return SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16; |
| 604 | + } |
| 605 | + else if (bitsPerChannel == 32) { |
| 606 | + if (channels == 1) return SW_PIXELFORMAT_UNCOMPRESSED_R32; |
| 607 | + if (channels == 3) return SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32; |
| 608 | + if (channels == 4) return SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32; |
| 609 | + } |
| 610 | + |
| 611 | + return -1; // Unsupported format |
| 612 | +} |
535 | 613 |
|
536 | 614 | static inline uint32_t sw_cvt_hf_ui(uint16_t h)
|
537 | 615 | {
|
@@ -690,7 +768,7 @@ static inline void sw_get_pixel_rgba_32323232(float* color, const void* pixels,
|
690 | 768 | color[3] = pixel[3];
|
691 | 769 | }
|
692 | 770 |
|
693 |
| -static inline void sw_get_pixel(float* color, const void* pixels, uint32_t offset, SWpixelformat format) |
| 771 | +static inline void sw_get_pixel(float* color, const void* pixels, uint32_t offset, sw_pixelformat_e format) |
694 | 772 | {
|
695 | 773 | switch (format) {
|
696 | 774 |
|
@@ -1773,7 +1851,7 @@ static inline void sw_line_render(sw_vertex_t* v0, sw_vertex_t* v1)
|
1773 | 1851 |
|
1774 | 1852 | /* === Some Validity Check Helper === */
|
1775 | 1853 |
|
1776 |
| -static inline bool sw_is_texture_id_valid(uint32_t id) |
| 1854 | +static inline bool sw_is_texture_valid(uint32_t id) |
1777 | 1855 | {
|
1778 | 1856 | bool valid = true;
|
1779 | 1857 |
|
@@ -2718,53 +2796,76 @@ void swDrawArrays(SWdraw mode, int offset, int count)
|
2718 | 2796 | swEnd();
|
2719 | 2797 | }
|
2720 | 2798 |
|
2721 |
| -uint32_t swLoadTexture(const void *data, int width, int height, int format, int mipmapCount) |
| 2799 | +void swGenTextures(int count, uint32_t* textures) |
2722 | 2800 | {
|
2723 |
| - if (RLSW.loadedTextureCount >= SW_MAX_TEXTURES) { |
2724 |
| - RLSW.errCode = SW_STACK_OVERFLOW; //< Out of memory, not really stack overflow |
2725 |
| - return 0; |
| 2801 | + if (count == 0 || textures == NULL) { |
| 2802 | + return; |
2726 | 2803 | }
|
2727 | 2804 |
|
2728 |
| - sw_texture_t texture = { 0 }; |
2729 |
| - texture.pixels = data; |
2730 |
| - texture.width = width; |
2731 |
| - texture.height = height; |
2732 |
| - texture.format = format; |
2733 |
| - texture.minFilter = SW_NEAREST; |
2734 |
| - texture.magFilter = SW_NEAREST; |
2735 |
| - texture.sWrap = SW_REPEAT; |
2736 |
| - texture.tWrap = SW_REPEAT; |
2737 |
| - texture.tx = 1.0f / width; |
2738 |
| - texture.ty = 1.0f / height; |
2739 |
| - (void)mipmapCount; |
2740 |
| - |
2741 |
| - uint32_t id = 0; |
2742 |
| - if (RLSW.freeTextureIdCount > 0) { |
2743 |
| - id = RLSW.freeTextureIds[--RLSW.freeTextureIdCount]; |
2744 |
| - } |
2745 |
| - else { |
2746 |
| - id = RLSW.loadedTextureCount++; |
| 2805 | + for (int i = 0; i < count; i++) { |
| 2806 | + if (RLSW.loadedTextureCount >= SW_MAX_TEXTURES) { |
| 2807 | + RLSW.errCode = SW_STACK_OVERFLOW; //< Out of memory, not really stack overflow |
| 2808 | + return; |
| 2809 | + } |
| 2810 | + uint32_t id = 0; |
| 2811 | + if (RLSW.freeTextureIdCount > 0) { |
| 2812 | + id = RLSW.freeTextureIds[--RLSW.freeTextureIdCount]; |
| 2813 | + } |
| 2814 | + else { |
| 2815 | + id = RLSW.loadedTextureCount++; |
| 2816 | + } |
| 2817 | + RLSW.loadedTextures[id] = RLSW.loadedTextures[0]; |
| 2818 | + textures[i] = id; |
2747 | 2819 | }
|
| 2820 | +} |
2748 | 2821 |
|
2749 |
| - RLSW.loadedTextures[id] = texture; |
| 2822 | +void swDeleteTextures(int count, uint32_t* textures) |
| 2823 | +{ |
| 2824 | + if (count == 0 || textures == NULL) { |
| 2825 | + return; |
| 2826 | + } |
2750 | 2827 |
|
2751 |
| - return id; |
| 2828 | + for (int i = 0; i < count; i++) { |
| 2829 | + if (!sw_is_texture_valid(textures[i])) { |
| 2830 | + RLSW.errCode = SW_INVALID_VALUE; |
| 2831 | + continue; |
| 2832 | + } |
| 2833 | + RLSW.loadedTextures[textures[i]].pixels = 0; |
| 2834 | + RLSW.freeTextureIds[RLSW.freeTextureIdCount++] = textures[i]; |
| 2835 | + } |
2752 | 2836 | }
|
2753 | 2837 |
|
2754 |
| -void swUnloadTexture(uint32_t id) |
| 2838 | +void swTexImage2D(int width, int height, SWformat format, SWtype type, const void* data) |
2755 | 2839 | {
|
2756 |
| - if (!sw_is_texture_id_valid(id)) { |
| 2840 | + uint32_t id = RLSW.currentTexture; |
| 2841 | + |
| 2842 | + if (!sw_is_texture_valid(id)) { |
2757 | 2843 | RLSW.errCode = SW_INVALID_VALUE;
|
2758 | 2844 | return;
|
2759 | 2845 | }
|
2760 | 2846 |
|
2761 |
| - RLSW.loadedTextures[id].pixels = 0; |
2762 |
| - RLSW.freeTextureIds[RLSW.freeTextureIdCount++] = id; |
| 2847 | + int pixelFormat = sw_get_pixel_format(format, type); |
| 2848 | + |
| 2849 | + if (pixelFormat < 0) { |
| 2850 | + RLSW.errCode = SW_INVALID_ENUM; |
| 2851 | + return; |
| 2852 | + } |
| 2853 | + |
| 2854 | + sw_texture_t* texture = &RLSW.loadedTextures[id]; |
| 2855 | + |
| 2856 | + texture->pixels = data; |
| 2857 | + texture->width = width; |
| 2858 | + texture->height = height; |
| 2859 | + texture->format = pixelFormat; |
| 2860 | + texture->tx = 1.0f / width; |
| 2861 | + texture->ty = 1.0f / height; |
2763 | 2862 | }
|
2764 | 2863 |
|
2765 |
| -void swTextureParameters(uint32_t id, int param, int value) |
| 2864 | +void swTexParameteri(int param, int value) |
2766 | 2865 | {
|
2767 |
| - if (!sw_is_texture_id_valid(id)) { |
| 2866 | + uint32_t id = RLSW.currentTexture; |
| 2867 | + |
| 2868 | + if (!sw_is_texture_valid(id)) { |
2768 | 2869 | RLSW.errCode = SW_INVALID_VALUE;
|
2769 | 2870 | return;
|
2770 | 2871 | }
|
|
0 commit comments