328 lines
9.8 KiB
C
Raw Normal View History

2025-01-22 16:18:30 +01:00
#include <kinc/graphics4/graphics.h>
#include <kinc/image.h>
#include <kinc/video.h>
#include <hl.h>
#include <assert.h>
typedef struct tex_and_data {
kinc_g4_texture_t texture;
int width, height;
void *data;
} tex_and_data_t;
static kinc_image_format_t convertImageFormat(int format) {
switch (format) {
default:
case 0:
return KINC_IMAGE_FORMAT_RGBA32;
case 1:
return KINC_IMAGE_FORMAT_GREY8;
case 2:
return KINC_IMAGE_FORMAT_RGBA128;
case 4:
return KINC_IMAGE_FORMAT_RGBA64;
case 5:
return KINC_IMAGE_FORMAT_A32;
case 6:
return KINC_IMAGE_FORMAT_A16;
}
}
static int sizeOf(kinc_image_format_t format) {
switch (format) {
case KINC_IMAGE_FORMAT_RGBA128:
return 16;
case KINC_IMAGE_FORMAT_RGBA32:
case KINC_IMAGE_FORMAT_BGRA32:
return 4;
case KINC_IMAGE_FORMAT_RGBA64:
return 8;
case KINC_IMAGE_FORMAT_A32:
return 4;
case KINC_IMAGE_FORMAT_A16:
return 2;
case KINC_IMAGE_FORMAT_GREY8:
return 1;
case KINC_IMAGE_FORMAT_RGB24:
return 3;
}
assert(false);
return 0;
}
vbyte *hl_kinc_texture_create(int width, int height, int format, bool readable) {
tex_and_data_t *texture = (tex_and_data_t *)malloc(sizeof(tex_and_data_t));
kinc_image_format_t f = convertImageFormat(format);
kinc_g4_texture_init(&texture->texture, width, height, f);
texture->width = width;
texture->height = height;
if (readable) {
texture->data = malloc(width * height * sizeOf(f));
}
else {
texture->data = NULL;
}
return (vbyte *)texture;
}
vbyte *hl_kinc_texture_create_from_file(vbyte *filename, bool readable) {
size_t size = kinc_image_size_from_file((char *)filename);
if (size > 0) {
tex_and_data_t *texture = (tex_and_data_t *)malloc(sizeof(tex_and_data_t));
texture->data = malloc(size);
kinc_image_t image;
if (kinc_image_init_from_file(&image, texture->data, (char *)filename) != 0) {
kinc_g4_texture_init_from_image(&texture->texture, &image);
texture->width = image.width;
texture->height = image.height;
if (!readable) {
free(texture->data);
texture->data = NULL;
}
kinc_image_destroy(&image);
return (vbyte *)texture;
}
kinc_image_destroy(&image);
free(texture->data);
texture->data = NULL;
free(texture);
}
return NULL;
}
vbyte *hl_kinc_texture_create3d(int width, int height, int depth, int format, bool readable) {
tex_and_data_t *texture = (tex_and_data_t *)malloc(sizeof(tex_and_data_t));
kinc_image_format_t f = convertImageFormat(format);
kinc_g4_texture_init(&texture->texture, width, height, f);
texture->width = width;
texture->height = height;
if (readable) {
texture->data = malloc(width * height * depth * sizeOf(f));
}
else {
texture->data = NULL;
}
return (vbyte *)texture;
}
vbyte *hl_kinc_video_get_current_image(vbyte *video) {
kinc_video_t *v = (kinc_video_t *)video;
return (vbyte *)kinc_video_current_image(v);
}
vbyte *hl_kinc_texture_from_bytes(vbyte *bytes, int width, int height, int format, bool readable) {
kinc_image_format_t f = convertImageFormat(format);
kinc_image_t image;
kinc_image_init(&image, bytes, width, height, f);
tex_and_data_t *texture = (tex_and_data_t *)malloc(sizeof(tex_and_data_t));
kinc_g4_texture_init_from_image(&texture->texture, &image);
texture->width = width;
texture->height = height;
kinc_image_destroy(&image);
if (readable) {
size_t size = width * height * sizeOf(f);
texture->data = malloc(size);
memcpy(texture->data, bytes, size);
}
else {
texture->data = NULL;
}
return (vbyte *)texture;
}
vbyte *hl_kinc_texture_from_bytes3d(vbyte *bytes, int width, int height, int depth, int format, bool readable) {
kinc_image_format_t f = convertImageFormat(format);
kinc_image_t image;
kinc_image_init3d(&image, bytes, width, height, depth, f);
tex_and_data_t *texture = (tex_and_data_t *)malloc(sizeof(tex_and_data_t));
kinc_g4_texture_init_from_image3d(&texture->texture, &image);
texture->width = width;
texture->height = height;
kinc_image_destroy(&image);
if (readable) {
size_t size = width * height * depth * sizeOf(f);
texture->data = malloc(size);
memcpy(texture->data, bytes, size);
}
else {
texture->data = NULL;
}
return (vbyte *)texture;
}
vbyte *hl_kinc_texture_from_encoded_bytes(vbyte *bytes, int length, vbyte *format, bool readable) {
tex_and_data_t *texture = (tex_and_data_t *)malloc(sizeof(tex_and_data_t));
size_t size = kinc_image_size_from_encoded_bytes(bytes, length, (char *)format);
texture->data = malloc(size);
kinc_image_t image;
kinc_image_init_from_encoded_bytes(&image, texture->data, bytes, length, (char *)format);
kinc_g4_texture_init_from_image(&texture->texture, &image);
texture->width = image.width;
texture->height = image.height;
kinc_image_destroy(&image);
if (!readable) {
free(texture->data);
texture->data = NULL;
}
return (vbyte *)texture;
}
bool hl_kinc_non_pow2_textures_supported(void) {
return kinc_g4_supports_non_pow2_textures();
}
int hl_kinc_texture_get_width(vbyte *texture) {
tex_and_data_t *tex = (tex_and_data_t *)texture;
return tex->width;
}
int hl_kinc_texture_get_height(vbyte *texture) {
tex_and_data_t *tex = (tex_and_data_t *)texture;
return tex->height;
}
int hl_kinc_texture_get_real_width(vbyte *texture) {
kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
return tex->tex_width;
}
int hl_kinc_texture_get_real_height(vbyte *texture) {
kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
return tex->tex_height;
}
int hl_kinc_texture_get_stride(vbyte *texture) {
kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
return kinc_g4_texture_stride(tex);
}
int hl_kinc_texture_at(vbyte *texture, int x, int y) {
tex_and_data_t *tex = (tex_and_data_t *)texture;
assert(tex->data != NULL);
return *(int *)&((uint8_t *)tex->data)[tex->width * sizeOf(tex->texture.format) * y + x * sizeOf(tex->texture.format)];
}
void hl_kinc_texture_unload(vbyte *texture) {
tex_and_data_t *tex = (tex_and_data_t *)texture;
if (tex->data != NULL) {
free(tex->data);
tex->data = NULL;
}
kinc_g4_texture_destroy(&tex->texture);
free(tex);
}
void hl_kinc_render_target_unload(vbyte *renderTarget) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
kinc_g4_render_target_destroy(rt);
free(rt);
}
vbyte *hl_kinc_render_target_create(int width, int height, int depthBufferBits, int format, int stencilBufferBits) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)malloc(sizeof(kinc_g4_render_target_t));
kinc_g4_render_target_init(rt, width, height, (kinc_g4_render_target_format_t)format, depthBufferBits, stencilBufferBits);
return (vbyte *)rt;
}
int hl_kinc_render_target_get_width(vbyte *renderTarget) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
return rt->width;
}
int hl_kinc_render_target_get_height(vbyte *renderTarget) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
return rt->height;
}
int hl_kinc_render_target_get_real_width(vbyte *renderTarget) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
return rt->texWidth;
}
int hl_kinc_render_target_get_real_height(vbyte *renderTarget) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
return rt->texHeight;
}
void hl_kinc_texture_unlock(vbyte *texture, vbyte *bytes) {
kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
uint8_t *b = (uint8_t *)bytes;
uint8_t *btex = kinc_g4_texture_lock(tex);
int size = sizeOf(tex->format);
int stride = kinc_g4_texture_stride(tex);
for (int y = 0; y < tex->tex_height; ++y) {
for (int x = 0; x < tex->tex_width; ++x) {
#ifdef KORE_DIRECT3D
if (tex->format == KINC_IMAGE_FORMAT_RGBA32) {
// RBGA->BGRA
btex[y * stride + x * size + 0] = b[(y * tex->tex_width + x) * size + 2];
btex[y * stride + x * size + 1] = b[(y * tex->tex_width + x) * size + 1];
btex[y * stride + x * size + 2] = b[(y * tex->tex_width + x) * size + 0];
btex[y * stride + x * size + 3] = b[(y * tex->tex_width + x) * size + 3];
}
else
#endif
{
for (int i = 0; i < size; ++i) {
btex[y * stride + x * size + i] = b[(y * tex->tex_width + x) * size + i];
}
}
}
}
kinc_g4_texture_unlock(tex);
}
void hl_kinc_render_target_get_pixels(vbyte *renderTarget, vbyte *pixels) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
kinc_g4_render_target_get_pixels(rt, pixels);
}
void hl_kinc_generate_mipmaps_texture(vbyte *texture, int levels) {
kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
kinc_g4_texture_generate_mipmaps(tex, levels);
}
void hl_kinc_generate_mipmaps_target(vbyte *renderTarget, int levels) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
kinc_g4_render_target_generate_mipmaps(rt, levels);
}
void hl_kinc_set_mipmap_texture(vbyte *texture, vbyte *mipmap, int level) {
kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
tex_and_data_t *miptex = (tex_and_data_t *)mipmap;
assert(miptex->data != NULL);
kinc_image_t mipimage;
kinc_image_init(&mipimage, miptex->data, miptex->width, miptex->height, miptex->texture.format);
kinc_g4_texture_set_mipmap(tex, &mipimage, level);
kinc_image_destroy(&mipimage);
}
void hl_kinc_render_target_set_depth_stencil_from(vbyte *renderTarget, vbyte *from) {
kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
kinc_g4_render_target_t *rt2 = (kinc_g4_render_target_t *)from;
kinc_g4_render_target_set_depth_stencil_from(rt, rt2);
}
void hl_kinc_texture_clear(vbyte *texture, int x, int y, int z, int width, int height, int depth, int color) {
kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
kinc_g4_texture_clear(tex, x, y, z, width, height, depth, color);
}