mirror of
https://github.com/quelsolaar/MergeSource
synced 2025-02-08 11:08:41 -05:00
252 lines
6.4 KiB
C
252 lines
6.4 KiB
C
#include "betray_plugin_api.h"
|
|
#include "relinquish.h"
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
uint texture_id = 0;
|
|
uint hald_clut_id = 0;
|
|
uint depth_id = 0;
|
|
uint fbo_id = 0;
|
|
uint screen_size[2] = {0, 0};
|
|
RShader *clut_lookup_shader = NULL;
|
|
void *clut_surface_pool = NULL;
|
|
|
|
char *clut_lookup_vertex =
|
|
"attribute vec4 vertex;"
|
|
"uniform mat4 ModelViewProjectionMatrix;"
|
|
"varying vec2 mapping;"
|
|
"void main()"
|
|
"{"
|
|
" mapping = vertex.ba;"
|
|
" gl_Position = ModelViewProjectionMatrix * vec4(vertex.xy, 0.0, 1.0);"
|
|
"}";
|
|
|
|
char *clut_lookup_fragment =
|
|
"uniform sampler2D image;"
|
|
"uniform sampler3D clut;"
|
|
"varying vec2 mapping;"
|
|
"void main()"
|
|
"{"
|
|
" vec4 sample;"
|
|
" sample = texture2D(image, mapping);"
|
|
" gl_FragColor = texture3D(clut, sample.rgb);"
|
|
"}";
|
|
|
|
|
|
void save_targa(char *file_name, uint8 *data, unsigned int x, unsigned int y)
|
|
{
|
|
FILE *image;
|
|
char *foot = "TRUEVISION-XFILES.";
|
|
unsigned int i, j;
|
|
|
|
if((image = fopen(file_name, "wb")) == NULL)
|
|
{
|
|
printf("Could not create file: %s\n", file_name);
|
|
return;
|
|
}
|
|
fputc(0, image);
|
|
fputc(0, image);
|
|
fputc(2, image); /* uncompressed */
|
|
for(i = 3; i < 12; i++)
|
|
fputc(0, image); /* ignore some stuff */
|
|
fputc(x % 256, image); /* size */
|
|
fputc(x / 256, image);
|
|
fputc(y % 256, image);
|
|
fputc(y / 256, image);
|
|
fputc(24, image); /* 24 bit image */
|
|
for(j = 0; j < y; j++)
|
|
{
|
|
for(i = 0; i < x; i++)
|
|
{
|
|
fputc(data[((y - j - 1) * x + i) * 3 + 0], image);
|
|
fputc(data[((y - j - 1) * x + i) * 3 + 2], image);
|
|
fputc(data[((y - j - 1) * x + i) * 3 + 1], image);
|
|
}
|
|
}
|
|
for(i = 0; i < 9; i++)
|
|
fputc(0, image);
|
|
for(i = 0; foot[i] != 0; i++)
|
|
fputc(foot[i], image);
|
|
fputc(0, image);
|
|
fclose(image);
|
|
}
|
|
|
|
|
|
uint8 *load_targa(char *file_name, unsigned int *x, unsigned int *y)
|
|
{
|
|
FILE *image;
|
|
uint8 *draw = NULL;
|
|
unsigned int i, j, identfeald, type, x_size, y_size, alpha;
|
|
|
|
if((image = fopen(file_name, "rb")) == NULL)
|
|
{
|
|
printf("can not open file: %s\n", file_name);
|
|
return NULL;
|
|
}
|
|
|
|
identfeald = fgetc(image);
|
|
if(0 != fgetc(image))
|
|
{
|
|
printf("Error: File %s a non suported palet image\n", file_name);
|
|
return NULL;
|
|
}
|
|
type = fgetc(image);
|
|
if(2 != type) /* type must be 2 uncompressed RGB */
|
|
{
|
|
printf("Error: File %s is not a uncompressed RGB image\n", file_name);
|
|
return NULL;
|
|
}
|
|
for(i = 3; i < 12; i++)
|
|
fgetc(image); /* ignore some stuff */
|
|
x_size = fgetc(image);
|
|
x_size += 256 * fgetc(image);
|
|
y_size = fgetc(image);
|
|
y_size += 256 * fgetc(image);
|
|
|
|
alpha = fgetc(image);
|
|
|
|
if(alpha != 24 && alpha != 32) /* type must be 24 or 32 bits RGB */
|
|
{
|
|
printf("Error: File %s is not a 24 or 32 bit RGB image\n", file_name);
|
|
return NULL;
|
|
}
|
|
|
|
for(i = 0; i < identfeald; i++)
|
|
fgetc(image); /* ignore some stuff */
|
|
*x = x_size;
|
|
*y = y_size;
|
|
|
|
draw = malloc((sizeof *draw) * x_size * y_size * 3);
|
|
|
|
for(j = 0; j < y_size * x_size * 3; j++)
|
|
draw[j] = 0;
|
|
|
|
if(alpha == 32)
|
|
{
|
|
for(j = 0; j < y_size; j++)
|
|
{
|
|
for(i = 0; i < x_size; i++)
|
|
{
|
|
fgetc(image); /* ignore alpha */
|
|
draw[((y_size - j - 1) * x_size + i) * 3 + 2] = fgetc(image);
|
|
draw[((y_size - j - 1) * x_size + i) * 3 + 1] = fgetc(image);
|
|
draw[((y_size - j - 1) * x_size + i) * 3 + 0] = fgetc(image);
|
|
}
|
|
}
|
|
}else for(j = 0; j < y_size; j++)
|
|
{
|
|
for(i = 0; i < x_size; i++)
|
|
{
|
|
draw[((y_size - j - 1) * x_size + i) * 3 + 0] = fgetc(image);
|
|
draw[((y_size - j - 1) * x_size + i) * 3 + 2] = fgetc(image);
|
|
draw[((y_size - j - 1) * x_size + i) * 3 + 1] = fgetc(image);
|
|
}
|
|
}
|
|
|
|
|
|
fclose(image);
|
|
return draw;
|
|
}
|
|
|
|
|
|
boolean betray_plugin_image_warp(BInputState *input)
|
|
{
|
|
static uint seed = 0;
|
|
RMatrix matrix;
|
|
float f;
|
|
uint x, y, i;
|
|
seed++;
|
|
f = betray_plugin_screen_mode_get(&x, &y, NULL);
|
|
if(screen_size[0] != x || screen_size[1] != y)
|
|
{
|
|
|
|
float surface[6 * 4] = {-1, -1, 0, 0,
|
|
1, -1, 1, 0,
|
|
1, 1, 1, 1,
|
|
-1, -1, 0, 0,
|
|
1, 1, 1, 1,
|
|
-1, 1, 0, 1};
|
|
for(i = 0; i < 6; i++)
|
|
surface[i * 4 + 1] *= f;
|
|
screen_size[0] = x;
|
|
screen_size[1] = y;
|
|
if(texture_id != 0)
|
|
r_texture_free(texture_id);
|
|
if(depth_id != 0)
|
|
r_texture_free(depth_id);
|
|
if(fbo_id != 0)
|
|
r_framebuffer_free(fbo_id);
|
|
texture_id = r_texture_allocate(R_IF_RGB_UINT8, x, y, 1, TRUE, TRUE, NULL);
|
|
depth_id = r_texture_allocate(R_IF_DEPTH32, x, y, 1, TRUE, TRUE, NULL);
|
|
fbo_id = r_framebuffer_allocate(&texture_id, 1, depth_id, RELINQUISH_TARGET_2D_TEXTURE);
|
|
r_array_load_vertex(clut_surface_pool, NULL, surface, 0, 6);
|
|
}
|
|
betray_plugin_application_draw(fbo_id, x, y, NULL, FALSE, NULL);
|
|
|
|
r_viewport(0, 0, x, y);
|
|
r_matrix_set(&matrix);
|
|
r_matrix_identity(&matrix);
|
|
r_matrix_frustum(&matrix, -0.01, 0.01, -0.01 * f, 0.01 * f, 0.01, 100.0);
|
|
glClearColor(0, 0, 1, 1);
|
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
r_matrix_translate(&matrix, 0, 0, -1.0);
|
|
|
|
r_shader_set(clut_lookup_shader);
|
|
r_shader_texture_set(clut_lookup_shader, 0, texture_id);
|
|
r_shader_texture_set(clut_lookup_shader, 1, hald_clut_id);
|
|
r_array_section_draw(clut_surface_pool, NULL, GL_TRIANGLES, 0, 6);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void betray_plugin_init(void)
|
|
{
|
|
char *file_name = "Betray_hald_clut.tga";
|
|
unsigned int i, j, k, size, level = 16, x, y;
|
|
uint8 *data, *p;
|
|
RFormats vertex_format_types = R_FLOAT;
|
|
uint vertex_format_size = 4;
|
|
betray_plugin_callback_set_image_warp(betray_plugin_image_warp, "Hald Clut CC");
|
|
data = load_targa(file_name, &x, &y);
|
|
if(data == NULL)
|
|
{
|
|
level = 8;
|
|
size = level * level;
|
|
data = p = malloc((sizeof *data) * size * size * size * 3);
|
|
for(i = 0; i < size; i++)
|
|
{
|
|
for(j = 0; j < size; j++)
|
|
{
|
|
for(k = 0; k < size; k++)
|
|
{
|
|
*p++ = (uint8)(k * 256 / size);
|
|
*p++ = (uint8)(j * 256 / size);
|
|
*p++ = (uint8)(i * 256 / size);
|
|
}
|
|
}
|
|
}
|
|
save_targa(file_name, data, level * level * level, level * level * level);
|
|
printf("Hald CLUT with level %u created, %u by %u pixels size, file name: %s\n", level, size * level, size * level, file_name);
|
|
return;
|
|
}
|
|
if(x != y)
|
|
{
|
|
printf("Betray Plugin Error: Hald CLUT not sqare\n");
|
|
return;
|
|
}
|
|
|
|
for(i = 0; i * i * i < x * y; i++);
|
|
if(i * i * i != x * y)
|
|
{
|
|
printf("Betray Plugin Error: Hald CLUT size error\n");
|
|
return;
|
|
}
|
|
printf("Hald CLUT Loaded\n");
|
|
r_init(betray_plugin_gl_proc_address_get());
|
|
hald_clut_id = r_texture_allocate(R_IF_RGB_UINT8, i, i, i, TRUE, FALSE, data);
|
|
free(data);
|
|
clut_lookup_shader = r_shader_create_simple(NULL, 0, clut_lookup_vertex, clut_lookup_fragment, "Clut Lookup shader");
|
|
clut_surface_pool = r_array_allocate(6, &vertex_format_types, &vertex_format_size, 1, 0);
|
|
}
|