forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			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); | ||
|  | } |