328 lines
9.8 KiB
C
328 lines
9.8 KiB
C
|
#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);
|
||
|
}
|