Browse Source

texture copy support

pull/4832/head
Bigfoot71 1 week ago
parent
commit
be24b06356
1 changed files with 83 additions and 14 deletions
  1. +83
    -14
      src/external/rlsw.h

+ 83
- 14
src/external/rlsw.h View File

@ -46,6 +46,10 @@
# define SW_FREE(ptr) free(ptr)
#endif
#ifndef SW_GL_BINDING_COPY_TEXTURE
# define SW_GL_BINDING_COPY_TEXTURE true
#endif
#ifndef SW_COLOR_BUFFER_BITS
# define SW_COLOR_BUFFER_BITS 24
#endif
@ -299,7 +303,7 @@ typedef double GLclampd;
#define glDrawArrays(m, o, c) swDrawArrays(m, o, c)
#define glGenTextures(c, v) swGenTextures(c, v)
#define glDeleteTextures(c, v) swDeleteTextures(c, v)
#define glTexImage2D(tr, l, if, w, h, b, f, t, p) swTexImage2D(w, h, f, t, p)
#define glTexImage2D(tr, l, if, w, h, b, f, t, p) swTexImage2D(w, h, f, t, SW_GL_BINDING_COPY_TEXTURE, p)
#define glTexParameteri(tr, pname, param) swTexParameteri(pname, param)
#define glBindTexture(tr, id) swBindTexture(id)
@ -514,7 +518,7 @@ void swDrawArrays(SWdraw mode, int offset, int count);
void swGenTextures(int count, uint32_t* textures);
void swDeleteTextures(int count, uint32_t* textures);
void swTexImage2D(int width, int height, SWformat format, SWtype type, const void* data);
void swTexImage2D(int width, int height, SWformat format, SWtype type, t">bool copy, const void* data);
void swTexParameteri(int param, int value);
void swBindTexture(uint32_t id);
@ -590,7 +594,14 @@ typedef struct {
typedef struct {
const void* pixels;
// Dirty hack for copied data
// TODO: Rework copied image handling
union {
const void* cptr; //< NOTE: Is used for all data reads
void* ptr; //< WARNING: Should only be used to allocate and free data
} pixels;
int width;
int height;
int format;
@ -604,6 +615,8 @@ typedef struct {
float tx;
float ty;
bool copy;
} sw_texture_t;
typedef struct {
@ -1207,6 +1220,43 @@ static inline int sw_get_pixel_format(SWformat format, SWtype type)
return -1; // Unsupported format
}
int sw_get_pixel_bpp(sw_pixelformat_e format)
{
int bpp = 0;
switch (format)
{
case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
case SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
case SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5:
case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R16: bpp = 16; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: bpp = 16*3; break;
case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: bpp = 16*4; break;
case SW_PIXELFORMAT_COMPRESSED_DXT1_RGB:
case SW_PIXELFORMAT_COMPRESSED_DXT1_RGBA:
case SW_PIXELFORMAT_COMPRESSED_ETC1_RGB:
case SW_PIXELFORMAT_COMPRESSED_ETC2_RGB:
case SW_PIXELFORMAT_COMPRESSED_PVRT_RGB:
case SW_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
case SW_PIXELFORMAT_COMPRESSED_DXT3_RGBA:
case SW_PIXELFORMAT_COMPRESSED_DXT5_RGBA:
case SW_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
case SW_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
case SW_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
default: break;
}
return bpp;
}
static inline void sw_get_pixel_grayscale(float* color, const void* pixels, uint32_t offset)
{
float gray = (float)((uint8_t*)pixels)[offset] * (1.0f / 255);
@ -1640,7 +1690,7 @@ static inline void sw_texture_sample_nearest(float* color, const sw_texture_t* t
int x, y;
sw_texture_map(&x, u, tex->width, tex->sWrap);
sw_texture_map(&y, v, tex->height, tex->tWrap);
sw_get_pixel(color, tex->pixels, y * tex->width + x, tex->format);
sw_get_pixel(color, tex->pixels.cptr, y * tex->width + x, tex->format);
}
static inline void sw_texture_sample_linear(float* color, const sw_texture_t* tex, float u, float v)
@ -1655,10 +1705,10 @@ static inline void sw_texture_sample_linear(float* color, const sw_texture_t* te
float fy = v * (tex->height - 1) - y0;
float c00[4], c10[4], c01[4], c11[4];
sw_get_pixel(c00, tex->pixels, y0 * tex->width + x0, tex->format);
sw_get_pixel(c10, tex->pixels, y0 * tex->width + x1, tex->format);
sw_get_pixel(c01, tex->pixels, y1 * tex->width + x0, tex->format);
sw_get_pixel(c11, tex->pixels, y1 * tex->width + x1, tex->format);
sw_get_pixel(c00, tex->pixels.cptr, y0 * tex->width + x0, tex->format);
sw_get_pixel(c10, tex->pixels.cptr, y0 * tex->width + x1, tex->format);
sw_get_pixel(c01, tex->pixels.cptr, y1 * tex->width + x0, tex->format);
sw_get_pixel(c11, tex->pixels.cptr, y1 * tex->width + x1, tex->format);
float c0[4], c1[4];
for (int i = 0; i < 4; i++) {
@ -2937,7 +2987,7 @@ static inline bool sw_is_texture_valid(uint32_t id)
if (id == 0) valid = false;
else if (id >= SW_MAX_TEXTURES) valid = false;
else if (RLSW.loadedTextures[id].pixels == 0) valid = false;
else if (RLSW.loadedTextures[id].pixels.cptr == 0) valid = false;
return true;
}
@ -3099,7 +3149,7 @@ bool swInit(int w, int h)
1.0f, 1.0f, 1.0f,
};
RLSW.loadedTextures[0].pixels = defTex;
RLSW.loadedTextures[0].pixels.cptr = defTex;
RLSW.loadedTextures[0].width = 2;
RLSW.loadedTextures[0].height = 2;
RLSW.loadedTextures[0].format = SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32;
@ -3990,12 +4040,15 @@ void swDeleteTextures(int count, uint32_t* textures)
RLSW.errCode = SW_INVALID_VALUE;
continue;
}
RLSW.loadedTextures[textures[i]].pixels = 0;
if (RLSW.loadedTextures[textures[i]].copy) {
SW_FREE(RLSW.loadedTextures[textures[i]].pixels.ptr);
}
RLSW.loadedTextures[textures[i]].pixels.cptr = NULL;
RLSW.freeTextureIds[RLSW.freeTextureIdCount++] = textures[i];
}
}
void swTexImage2D(int width, int height, SWformat format, SWtype type, const void* data)
void swTexImage2D(int width, int height, SWformat format, SWtype type, t">bool copy, const void* data)
{
uint32_t id = RLSW.currentTexture;
@ -4013,12 +4066,28 @@ void swTexImage2D(int width, int height, SWformat format, SWtype type, const voi
sw_texture_t* texture = &RLSW.loadedTextures[id];
texture->pixels = data;
if (copy) {
int bpp = sw_get_pixel_bpp(pixelFormat);
int size = bpp * width * height;
texture->pixels.ptr = SW_MALLOC(size);
if (texture->pixels.ptr == NULL) {
RLSW.errCode = SW_STACK_OVERFLOW; //< Out of memory...
return;
}
for (int i = 0; i < size; i++) {
((uint8_t*)texture->pixels.ptr)[i] = ((uint8_t*)data)[i];
}
}
else {
texture->pixels.cptr = data;
}
texture->width = width;
texture->height = height;
texture->format = pixelFormat;
texture->tx = 1.0f / width;
texture->ty = 1.0f / height;
texture->copy = copy;
}
void swTexParameteri(int param, int value)
@ -4080,7 +4149,7 @@ void swBindTexture(uint32_t id)
return;
}
if (id > 0 && RLSW.loadedTextures[id].pixels == mi">0) {
if (id > 0 && RLSW.loadedTextures[id].pixels.cptr == nb">NULL) {
RLSW.errCode = SW_INVALID_OPERATION;
return;
}

Loading…
Cancel
Save