texture copy support
This commit is contained in:
parent
89d40510c6
commit
be24b06356
97
src/external/rlsw.h
vendored
97
src/external/rlsw.h
vendored
|
|
@ -46,6 +46,10 @@
|
||||||
# define SW_FREE(ptr) free(ptr)
|
# define SW_FREE(ptr) free(ptr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SW_GL_BINDING_COPY_TEXTURE
|
||||||
|
# define SW_GL_BINDING_COPY_TEXTURE true
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SW_COLOR_BUFFER_BITS
|
#ifndef SW_COLOR_BUFFER_BITS
|
||||||
# define SW_COLOR_BUFFER_BITS 24
|
# define SW_COLOR_BUFFER_BITS 24
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -299,7 +303,7 @@ typedef double GLclampd;
|
||||||
#define glDrawArrays(m, o, c) swDrawArrays(m, o, c)
|
#define glDrawArrays(m, o, c) swDrawArrays(m, o, c)
|
||||||
#define glGenTextures(c, v) swGenTextures(c, v)
|
#define glGenTextures(c, v) swGenTextures(c, v)
|
||||||
#define glDeleteTextures(c, v) swDeleteTextures(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 glTexParameteri(tr, pname, param) swTexParameteri(pname, param)
|
||||||
#define glBindTexture(tr, id) swBindTexture(id)
|
#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 swGenTextures(int count, uint32_t* textures);
|
||||||
void swDeleteTextures(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, bool copy, const void* data);
|
||||||
void swTexParameteri(int param, int value);
|
void swTexParameteri(int param, int value);
|
||||||
void swBindTexture(uint32_t id);
|
void swBindTexture(uint32_t id);
|
||||||
|
|
||||||
|
|
@ -590,7 +594,14 @@ typedef struct {
|
||||||
|
|
||||||
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 width;
|
||||||
int height;
|
int height;
|
||||||
int format;
|
int format;
|
||||||
|
|
@ -604,6 +615,8 @@ typedef struct {
|
||||||
float tx;
|
float tx;
|
||||||
float ty;
|
float ty;
|
||||||
|
|
||||||
|
bool copy;
|
||||||
|
|
||||||
} sw_texture_t;
|
} sw_texture_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -1207,6 +1220,43 @@ static inline int sw_get_pixel_format(SWformat format, SWtype type)
|
||||||
return -1; // Unsupported format
|
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)
|
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);
|
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;
|
int x, y;
|
||||||
sw_texture_map(&x, u, tex->width, tex->sWrap);
|
sw_texture_map(&x, u, tex->width, tex->sWrap);
|
||||||
sw_texture_map(&y, v, tex->height, tex->tWrap);
|
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)
|
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 fy = v * (tex->height - 1) - y0;
|
||||||
|
|
||||||
float c00[4], c10[4], c01[4], c11[4];
|
float c00[4], c10[4], c01[4], c11[4];
|
||||||
sw_get_pixel(c00, tex->pixels, y0 * tex->width + x0, tex->format);
|
sw_get_pixel(c00, tex->pixels.cptr, y0 * tex->width + x0, tex->format);
|
||||||
sw_get_pixel(c10, tex->pixels, y0 * tex->width + x1, tex->format);
|
sw_get_pixel(c10, tex->pixels.cptr, y0 * tex->width + x1, tex->format);
|
||||||
sw_get_pixel(c01, tex->pixels, y1 * tex->width + x0, tex->format);
|
sw_get_pixel(c01, tex->pixels.cptr, y1 * tex->width + x0, tex->format);
|
||||||
sw_get_pixel(c11, tex->pixels, y1 * tex->width + x1, tex->format);
|
sw_get_pixel(c11, tex->pixels.cptr, y1 * tex->width + x1, tex->format);
|
||||||
|
|
||||||
float c0[4], c1[4];
|
float c0[4], c1[4];
|
||||||
for (int i = 0; i < 4; i++) {
|
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;
|
if (id == 0) valid = false;
|
||||||
else if (id >= SW_MAX_TEXTURES) 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -3099,7 +3149,7 @@ bool swInit(int w, int h)
|
||||||
1.0f, 1.0f, 1.0f,
|
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].width = 2;
|
||||||
RLSW.loadedTextures[0].height = 2;
|
RLSW.loadedTextures[0].height = 2;
|
||||||
RLSW.loadedTextures[0].format = SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32;
|
RLSW.loadedTextures[0].format = SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32;
|
||||||
|
|
@ -3990,12 +4040,15 @@ void swDeleteTextures(int count, uint32_t* textures)
|
||||||
RLSW.errCode = SW_INVALID_VALUE;
|
RLSW.errCode = SW_INVALID_VALUE;
|
||||||
continue;
|
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];
|
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, bool copy, const void* data)
|
||||||
{
|
{
|
||||||
uint32_t id = RLSW.currentTexture;
|
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];
|
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->width = width;
|
||||||
texture->height = height;
|
texture->height = height;
|
||||||
texture->format = pixelFormat;
|
texture->format = pixelFormat;
|
||||||
texture->tx = 1.0f / width;
|
texture->tx = 1.0f / width;
|
||||||
texture->ty = 1.0f / height;
|
texture->ty = 1.0f / height;
|
||||||
|
texture->copy = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swTexParameteri(int param, int value)
|
void swTexParameteri(int param, int value)
|
||||||
|
|
@ -4080,7 +4149,7 @@ void swBindTexture(uint32_t id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id > 0 && RLSW.loadedTextures[id].pixels == 0) {
|
if (id > 0 && RLSW.loadedTextures[id].pixels.cptr == NULL) {
|
||||||
RLSW.errCode = SW_INVALID_OPERATION;
|
RLSW.errCode = SW_INVALID_OPERATION;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user