mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-04 12:47:56 +03:00
937 lines
32 KiB
C++
937 lines
32 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
*/
|
|
|
|
#include "render_context.hpp"
|
|
#include "shader_ft.hpp"
|
|
#include "sound.hpp"
|
|
#include "sprite.hpp"
|
|
#include "task.hpp"
|
|
|
|
float_t delta_frame_history = 0;
|
|
int32_t delta_frame_history_int = 0;
|
|
|
|
extern float_t rob_frame;
|
|
extern render_context* rctx_ptr;
|
|
|
|
//extern void dw_gui_ctrl_disp();
|
|
|
|
static void render_context_light_param_data_ibl_set_diffuse(light_param_ibl_diffuse* diffuse, int32_t level);
|
|
static void render_context_light_param_data_ibl_set_specular(light_param_ibl_specular* specular);
|
|
|
|
static const GLuint POSITION_INDEX = 0;
|
|
static const GLuint BONE_WEIGHT_INDEX = 1;
|
|
static const GLuint NORMAL_INDEX = 2;
|
|
static const GLuint COLOR0_INDEX = 3;
|
|
static const GLuint COLOR1_INDEX = 4;
|
|
static const GLuint MORPH_COLOR_INDEX = 5;
|
|
static const GLuint TANGENT_INDEX = 6;
|
|
static const GLuint UNKNOWN_INDEX = 7;
|
|
static const GLuint TEXCOORD0_INDEX = 8;
|
|
static const GLuint TEXCOORD1_INDEX = 9;
|
|
static const GLuint MORPH_POSITION_INDEX = 10;
|
|
static const GLuint MORPH_NORMAL_INDEX = 11;
|
|
static const GLuint MORPH_TANGENT_INDEX = 12;
|
|
static const GLuint MORPH_TEXCOORD0_INDEX = 13;
|
|
static const GLuint MORPH_TEXCOORD1_INDEX = 14;
|
|
static const GLuint BONE_INDEX_INDEX = 15;
|
|
|
|
draw_state_stats::draw_state_stats() : object_draw_count(), object_translucent_draw_count(),
|
|
object_reflect_draw_count(), field_C(), field_10(), draw_count(), draw_triangle_count(), field_1C() {
|
|
|
|
}
|
|
|
|
void draw_state_stats::reset() {
|
|
object_draw_count = 0;
|
|
object_translucent_draw_count = 0;
|
|
object_reflect_draw_count = 0;
|
|
field_C = 0;
|
|
field_10 = 0;
|
|
draw_count = 0;
|
|
draw_triangle_count = 0;
|
|
field_1C = 0;
|
|
}
|
|
|
|
draw_state::draw_state() : wireframe(), wireframe_overlay(), light(), self_shadow(),
|
|
shader_debug_flag(), use_global_material(), fog_height(), ex_data_mat(), field_68() {
|
|
shader = true;
|
|
shader_index = -1;
|
|
show = -1;
|
|
bump_depth = 1.0f;
|
|
intensity = 1.0f;
|
|
reflectivity = 1.0f;
|
|
reflect_uv_scale = 0.1f;
|
|
refract_uv_scale = 0.1f;
|
|
fresnel = 7.0f;
|
|
}
|
|
|
|
void draw_state::set_fog_height(bool value) {
|
|
fog_height = value;
|
|
}
|
|
|
|
sss_data::sss_data() : init_data(), enable(), npr_contour(), param() {
|
|
init_data = true;
|
|
enable = true;
|
|
npr_contour = true;
|
|
param = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
}
|
|
|
|
sss_data::~sss_data() {
|
|
|
|
}
|
|
|
|
void sss_data::free() {
|
|
|
|
}
|
|
|
|
void sss_data::init() {
|
|
textures[0].Init(640, 360, 0, GL_RGBA16F, GL_ZERO /*GL_DEPTH_COMPONENT32F*/);
|
|
textures[1].Init(320, 180, 0, GL_RGBA16F, GL_ZERO);
|
|
textures[2].Init(320, 180, 0, GL_RGBA16F, GL_ZERO);
|
|
textures[3].Init(320, 180, 0, GL_RGBA16F, GL_ZERO);
|
|
}
|
|
|
|
light_proj::light_proj(int32_t width, int32_t height) : enable(), texture_id() {
|
|
shadow_texture[0].Init(2048, 512, 0, GL_R32F, GL_DEPTH_COMPONENT32F);
|
|
shadow_texture[1].Init(2048, 512, 0, GL_R32F, GL_ZERO);
|
|
draw_texture.Init(width, height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F);
|
|
}
|
|
|
|
light_proj::~light_proj() {
|
|
|
|
}
|
|
|
|
void light_proj::resize(int32_t width, int32_t height) {
|
|
if (!this)
|
|
return;
|
|
|
|
draw_texture.Init(width, height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F);
|
|
}
|
|
|
|
bool light_proj::set() {
|
|
if (!this)
|
|
return false;
|
|
|
|
static const vec4 color_clear = 1.0f;
|
|
static const GLfloat depth_clear = 1.0f;
|
|
|
|
shadow_texture[0].Bind();
|
|
glViewport(0, 0, 2048, 512);
|
|
gl_state_enable_depth_test();
|
|
gl_state_set_depth_mask(GL_TRUE);
|
|
glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear);
|
|
glClearBufferfv(GL_DEPTH, 0, &depth_clear);
|
|
|
|
if (set_mat(false)) {
|
|
rctx_ptr->draw_state->shader_index = SHADER_FT_SIL;
|
|
uniform_value[U0A] = 1;
|
|
return true;
|
|
}
|
|
else {
|
|
draw_texture.Bind();
|
|
draw_texture.SetViewport();
|
|
gl_state_enable_depth_test();
|
|
gl_state_set_depth_mask(GL_TRUE);
|
|
glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear);
|
|
glClearBufferfv(GL_DEPTH, 0, &depth_clear);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool light_proj::set_mat(bool set_mat) {
|
|
render_context* rctx = rctx_ptr;
|
|
light_set* set = &rctx->light_set[LIGHT_SET_MAIN];
|
|
light_data* data = &set->lights[LIGHT_PROJECTION];
|
|
if (data->get_type() != LIGHT_SPOT)
|
|
return false;
|
|
|
|
vec3 position;
|
|
vec3 spot_direction;
|
|
data->get_position(position);
|
|
data->get_spot_direction(spot_direction);
|
|
|
|
if (vec3::length_squared(spot_direction) <= 0.000001f)
|
|
return false;
|
|
|
|
float_t spot_cutoff = data->get_spot_cutoff();
|
|
float_t fov = atanf(tanf(spot_cutoff * DEG_TO_RAD_FLOAT) * 0.25f) * 2.0f;
|
|
|
|
vec3 interest = position + spot_direction;
|
|
if (set_mat) {
|
|
mat4 temp;
|
|
mat4_translate(0.5f, 0.5f, 0.5f, &temp);
|
|
mat4_scale_rot(&temp, 0.5f, 0.5f, 0.5f, &temp);
|
|
|
|
mat4 proj;
|
|
mat4_persp(fov, 4.0f, 0.1f, 10.0f, &proj);
|
|
mat4_mul(&proj, &temp, &proj);
|
|
|
|
mat4 view;
|
|
vec3 up = { 0.0f, 1.0f, 0.0f };
|
|
mat4_look_at(&position, &interest, &up, &view);
|
|
|
|
mat4 mat;
|
|
mat4_mul(&view, &proj, &mat);
|
|
rctx->obj_scene.set_g_light_projection(mat);
|
|
}
|
|
else {
|
|
mat4_persp(fov, 4.0f, 0.1f, 10.0f, &rctx->proj_mat);
|
|
|
|
vec3 up = { 0.0f, 1.0f, 0.0f };
|
|
mat4_look_at(&position, &interest, &up, &rctx->view_mat);
|
|
rctx->obj_scene.set_projection_view(rctx->view_mat, rctx->proj_mat);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void obj_scene_shader_data::set_g_irradiance_r_transforms(const mat4& mat) {
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_irradiance_r_transforms[0] = temp.row0;
|
|
g_irradiance_r_transforms[1] = temp.row1;
|
|
g_irradiance_r_transforms[2] = temp.row2;
|
|
g_irradiance_r_transforms[3] = temp.row3;
|
|
}
|
|
|
|
void obj_scene_shader_data::set_g_irradiance_g_transforms(const mat4& mat) {
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_irradiance_g_transforms[0] = temp.row0;
|
|
g_irradiance_g_transforms[1] = temp.row1;
|
|
g_irradiance_g_transforms[2] = temp.row2;
|
|
g_irradiance_g_transforms[3] = temp.row3;
|
|
}
|
|
|
|
void obj_scene_shader_data::set_g_irradiance_b_transforms(const mat4& mat) {
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_irradiance_b_transforms[0] = temp.row0;
|
|
g_irradiance_b_transforms[1] = temp.row1;
|
|
g_irradiance_b_transforms[2] = temp.row2;
|
|
g_irradiance_b_transforms[3] = temp.row3;
|
|
}
|
|
|
|
void obj_scene_shader_data::set_g_normal_tangent_transforms(const mat4& mat) {
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_normal_tangent_transforms[0] = temp.row0;
|
|
g_normal_tangent_transforms[1] = temp.row1;
|
|
g_normal_tangent_transforms[2] = temp.row2;
|
|
}
|
|
|
|
void obj_scene_shader_data::set_g_self_shadow_receivers(int32_t index, const mat4& mat) {
|
|
size_t _index = index * 3LL;
|
|
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_self_shadow_receivers[_index + 0] = temp.row0;
|
|
g_self_shadow_receivers[_index + 1] = temp.row1;
|
|
g_self_shadow_receivers[_index + 2] = temp.row2;
|
|
}
|
|
|
|
void obj_scene_shader_data::set_g_light_projection(const mat4& mat) {
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_light_projection[0] = temp.row0;
|
|
g_light_projection[1] = temp.row1;
|
|
g_light_projection[2] = temp.row2;
|
|
g_light_projection[3] = temp.row3;
|
|
}
|
|
|
|
void obj_scene_shader_data::set_projection_view(const mat4& view, const mat4& proj) {
|
|
mat4 temp;
|
|
mat4_transpose(&view, &temp);
|
|
g_view[0] = temp.row0;
|
|
g_view[1] = temp.row1;
|
|
g_view[2] = temp.row2;
|
|
|
|
mat4_invert(&view, &temp);
|
|
mat4_transpose(&temp, &temp);
|
|
g_view_inverse[0] = temp.row0;
|
|
g_view_inverse[1] = temp.row1;
|
|
g_view_inverse[2] = temp.row2;
|
|
|
|
mat4_mul(&view, &proj, &temp);
|
|
mat4_transpose(&temp, &temp);
|
|
g_projection_view[0] = temp.row0;
|
|
g_projection_view[1] = temp.row1;
|
|
g_projection_view[2] = temp.row2;
|
|
g_projection_view[3] = temp.row3;
|
|
}
|
|
|
|
void obj_batch_shader_data::set_g_joint(const mat4& mat) {
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_joint[0] = temp.row0;
|
|
g_joint[1] = temp.row1;
|
|
g_joint[2] = temp.row2;
|
|
|
|
mat4_invert(&mat, &temp);
|
|
mat4_transpose(&temp, &temp);
|
|
g_joint_inverse[0] = temp.row0;
|
|
g_joint_inverse[1] = temp.row1;
|
|
g_joint_inverse[2] = temp.row2;
|
|
}
|
|
|
|
void obj_batch_shader_data::set_g_texcoord_transforms(int32_t index, const mat4& mat) {
|
|
size_t _index = index * 2LL;
|
|
|
|
mat4 temp;
|
|
mat4_transpose(&mat, &temp);
|
|
g_texcoord_transforms[_index + 0] = temp.row0;
|
|
g_texcoord_transforms[_index + 1] = temp.row1;
|
|
}
|
|
|
|
void obj_batch_shader_data::set_transforms(const mat4& model, const mat4& view, const mat4& proj) {
|
|
mat4 temp;
|
|
mat4_transpose(&model, &temp);
|
|
g_worlds[0] = temp.row0;
|
|
g_worlds[1] = temp.row1;
|
|
g_worlds[2] = temp.row2;
|
|
|
|
mat4_invert(&model, &temp);
|
|
g_worlds_invtrans[0] = temp.row0;
|
|
g_worlds_invtrans[1] = temp.row1;
|
|
g_worlds_invtrans[2] = temp.row2;
|
|
|
|
mat4 mv;
|
|
mat4_mul(&model, &view, &mv);
|
|
|
|
mat4_transpose(&mv, &temp);
|
|
g_worldview[0] = temp.row0;
|
|
g_worldview[1] = temp.row1;
|
|
g_worldview[2] = temp.row2;
|
|
|
|
mat4_invert(&mv, &temp);
|
|
mat4_transpose(&temp, &temp);
|
|
g_worldview_inverse[0] = temp.row0;
|
|
g_worldview_inverse[1] = temp.row1;
|
|
g_worldview_inverse[2] = temp.row2;
|
|
|
|
mat4_mul(&mv, &proj, &temp);
|
|
mat4_transpose(&temp, &temp);
|
|
g_transforms[0] = temp.row0;
|
|
g_transforms[1] = temp.row1;
|
|
g_transforms[2] = temp.row2;
|
|
g_transforms[3] = temp.row3;
|
|
}
|
|
|
|
render_context::render_context() : litproj(), chara_reflect(), chara_refract(), box_vao(), lens_ghost_vao(),
|
|
common_vao(), empty_texture_2d(), empty_texture_cube_map(), samplers(), render_samplers(), sprite_samplers(),
|
|
sprite_width(), sprite_height(), screen_x_offset(), screen_y_offset(), screen_width(), screen_height() {
|
|
camera = new ::camera;
|
|
draw_state = new ::draw_state;
|
|
disp_manager = new mdl::DispManager;
|
|
render_manager = new rndr::RenderManager;
|
|
sss_data = new ::sss_data;
|
|
|
|
static const float_t box_texcoords[] = {
|
|
1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
-0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
-0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
-0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
-0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f,
|
|
3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f,
|
|
3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f,
|
|
3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f,
|
|
3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f,
|
|
3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f,
|
|
3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f,
|
|
3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f,
|
|
};
|
|
|
|
glGenVertexArrays(1, &box_vao);
|
|
gl_state_bind_vertex_array(box_vao);
|
|
|
|
box_vbo.Create(sizeof(box_texcoords), box_texcoords);
|
|
box_vbo.Bind();
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)0);
|
|
glEnableVertexAttribArray(1);
|
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 4));
|
|
glEnableVertexAttribArray(2);
|
|
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 8));
|
|
glEnableVertexAttribArray(3);
|
|
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 12));
|
|
|
|
glGenVertexArrays(1, &lens_ghost_vao);
|
|
gl_state_bind_vertex_array(lens_ghost_vao);
|
|
|
|
lens_ghost_vbo.Create(sizeof(float_t) * 5 * (6 * 16));
|
|
lens_ghost_vbo.Bind();
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float_t) * 5, (void*)0);
|
|
glEnableVertexAttribArray(1);
|
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float_t) * 5, (void*)(sizeof(float_t) * 2));
|
|
gl_state_bind_array_buffer(0);
|
|
gl_state_bind_vertex_array(0);
|
|
|
|
glGenVertexArrays(1, &common_vao);
|
|
|
|
contour_coef_ubo.Create(sizeof(contour_coef_shader_data));
|
|
contour_params_ubo.Create(sizeof(contour_params_shader_data));
|
|
filter_scene_ubo.Create(sizeof(filter_scene_shader_data));
|
|
esm_filter_batch_ubo.Create(sizeof(esm_filter_batch_shader_data));
|
|
imgfilter_batch_ubo.Create(sizeof(imgfilter_batch_shader_data));
|
|
exposure_measure_ubo.Create(sizeof(exposure_measure_shader_data));
|
|
gaussian_coef_ubo.Create(sizeof(gaussian_coef_shader_data));
|
|
glass_eye_batch_ubo.Create(sizeof(glass_eye_batch_shader_data));
|
|
glitter_batch_ubo.Create(sizeof(glitter_batch_shader_data));
|
|
quad_ubo.Create(sizeof(quad_shader_data));
|
|
sprite_scene_ubo.Create(sizeof(sprite_scene_shader_data));
|
|
sss_filter_gaussian_coef_ubo.Create(sizeof(sss_filter_gaussian_coef_shader_data));
|
|
sun_quad_ubo.Create(sizeof(sun_quad_shader_data));
|
|
tone_map_ubo.Create(sizeof(tone_map_shader_data));
|
|
transparency_batch_ubo.Create(sizeof(transparency_batch_shader_data));
|
|
|
|
obj_scene = {};
|
|
obj_batch = {};
|
|
obj_skinning = {};
|
|
obj_scene_ubo.Create(sizeof(obj_scene_shader_data));
|
|
obj_batch_ubo.Create(sizeof(obj_batch_shader_data));
|
|
obj_skinning_ubo.Create(sizeof(obj_skinning_shader_data));
|
|
|
|
static const uint8_t empty_texture_data[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
static const GLenum target_cube_map_array[] = {
|
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
|
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
|
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
|
};
|
|
|
|
glGenTextures(1, &empty_texture_2d);
|
|
gl_state_bind_texture_2d(empty_texture_2d);
|
|
texture_set_params(GL_TEXTURE_2D, 0, false);
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0,
|
|
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 0, 8, empty_texture_data);
|
|
gl_state_bind_texture_2d(0);
|
|
|
|
glGenTextures(1, &empty_texture_cube_map);
|
|
gl_state_bind_texture_cube_map(empty_texture_cube_map);
|
|
texture_set_params(GL_TEXTURE_CUBE_MAP, 0, false);
|
|
for (int32_t side = 0; side < 6; side++)
|
|
glCompressedTexImage2D(target_cube_map_array[side], 0,
|
|
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 0, 8, empty_texture_data);
|
|
gl_state_bind_texture_cube_map(0);
|
|
|
|
static const vec4 border_color = 0.0f;
|
|
|
|
glGenSamplers(18, samplers);
|
|
for (int32_t i = 0; i < 18; i++) {
|
|
GLuint sampler = samplers[i];
|
|
|
|
glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER,
|
|
i % 2 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
|
|
|
|
GLuint wrap_s;
|
|
switch (i / 2 % 3) {
|
|
case 0:
|
|
wrap_s = GL_CLAMP_TO_EDGE;
|
|
break;
|
|
case 1:
|
|
wrap_s = GL_REPEAT;
|
|
break;
|
|
case 2:
|
|
wrap_s = GL_MIRRORED_REPEAT;
|
|
break;
|
|
}
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, wrap_s);
|
|
|
|
GLenum wrap_t;
|
|
switch (i / 6 % 3) {
|
|
case 0:
|
|
wrap_t = GL_CLAMP_TO_EDGE;
|
|
break;
|
|
case 1:
|
|
wrap_t = GL_REPEAT;
|
|
break;
|
|
case 2:
|
|
wrap_t = GL_MIRRORED_REPEAT;
|
|
break;
|
|
}
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, wrap_t);
|
|
}
|
|
|
|
GLuint sampler;
|
|
glGenSamplers(4, render_samplers);
|
|
sampler = render_samplers[0];
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
sampler = render_samplers[1];
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
sampler = render_samplers[2];
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color);
|
|
|
|
sampler = render_samplers[3];
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color);
|
|
|
|
glGenSamplers(3, sprite_samplers);
|
|
sampler = sprite_samplers[0];
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
|
|
|
|
sampler = sprite_samplers[1];
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
|
|
|
|
sampler = sprite_samplers[2];
|
|
glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
|
|
}
|
|
|
|
render_context::~render_context() {
|
|
glDeleteSamplers(3, sprite_samplers);
|
|
glDeleteSamplers(4, render_samplers);
|
|
glDeleteSamplers(18, samplers);
|
|
|
|
glDeleteTextures(1, &empty_texture_cube_map);
|
|
glDeleteTextures(1, &empty_texture_2d);
|
|
|
|
obj_skinning_ubo.Destroy();
|
|
obj_batch_ubo.Destroy();
|
|
obj_scene_ubo.Destroy();
|
|
|
|
tone_map_ubo.Destroy();
|
|
transparency_batch_ubo.Destroy();
|
|
sun_quad_ubo.Destroy();
|
|
sss_filter_gaussian_coef_ubo.Destroy();
|
|
sprite_scene_ubo.Destroy();
|
|
quad_ubo.Destroy();
|
|
glitter_batch_ubo.Destroy();
|
|
glass_eye_batch_ubo.Destroy();
|
|
gaussian_coef_ubo.Destroy();
|
|
exposure_measure_ubo.Destroy();
|
|
imgfilter_batch_ubo.Destroy();
|
|
esm_filter_batch_ubo.Destroy();
|
|
filter_scene_ubo.Destroy();
|
|
contour_params_ubo.Destroy();
|
|
contour_coef_ubo.Destroy();
|
|
|
|
if (common_vao) {
|
|
glDeleteVertexArrays(1, &common_vao);
|
|
common_vao = 0;
|
|
}
|
|
|
|
if (lens_ghost_vao) {
|
|
glDeleteVertexArrays(1, &lens_ghost_vao);
|
|
lens_ghost_vao = 0;
|
|
}
|
|
|
|
lens_ghost_vbo.Destroy();
|
|
|
|
if (box_vao) {
|
|
glDeleteVertexArrays(1, &box_vao);
|
|
box_vao = 0;
|
|
}
|
|
|
|
box_vbo.Destroy();
|
|
|
|
if (sss_data) {
|
|
delete sss_data;
|
|
sss_data = 0;
|
|
}
|
|
|
|
if (render_manager) {
|
|
delete render_manager;
|
|
render_manager = 0;
|
|
}
|
|
|
|
if (disp_manager) {
|
|
delete disp_manager;
|
|
disp_manager = 0;
|
|
}
|
|
|
|
if (draw_state) {
|
|
delete draw_state;
|
|
draw_state = 0;
|
|
}
|
|
|
|
if (camera) {
|
|
delete camera;
|
|
camera = 0;
|
|
}
|
|
}
|
|
|
|
void render_context::ctrl() {
|
|
delta_frame_history += get_delta_frame();
|
|
float_t v1;
|
|
delta_frame_history = modff(delta_frame_history, &v1);
|
|
delta_frame_history_int = (int32_t)v1;
|
|
if (delta_frame_history < 0.001f)
|
|
delta_frame_history = 0.0f;
|
|
else if (1.0f - delta_frame_history < 0.001f)
|
|
delta_frame_history_int++;
|
|
|
|
rctx_ptr = this;
|
|
app::TaskWork::ctrl();
|
|
sound_ctrl();
|
|
file_handler_storage_ctrl();
|
|
}
|
|
|
|
void render_context::disp() {
|
|
rctx_ptr = this;
|
|
disp_manager->refresh();
|
|
sprite_manager_reset_req_list();
|
|
draw_state->stats_prev = draw_state->stats;
|
|
draw_state->stats.reset();
|
|
app::TaskWork::disp();
|
|
shadow_ptr_get()->Ctrl();
|
|
int32_t sprite_index = sprite_manager_get_index();
|
|
//sprite_manager_set_index(3);
|
|
sprite_manager_set_index(0);
|
|
extern void dw_gui_ctrl_disp();
|
|
dw_gui_ctrl_disp();
|
|
sprite_manager_set_index(sprite_index);
|
|
render.ctrl(camera);
|
|
render_manager->render_all();
|
|
render.lens_flare_texture = 0;
|
|
render.aet_back = 0;
|
|
render_manager->field_31C = false;
|
|
app::TaskWork::basic();
|
|
}
|
|
|
|
void render_context::free() {
|
|
shadow_buffer.Free();
|
|
screen_buffer.Free();
|
|
render_buffer.Free();
|
|
reflect_buffer.Free();
|
|
}
|
|
|
|
void render_context::init() {
|
|
auto init_copy_buffer = [&](RenderTexture& src, RenderTexture& dst) {
|
|
dst.Init(src.GetWidth(),
|
|
src.GetHeight(), 0, src.color_texture->internal_format,
|
|
src.depth_texture ? src.depth_texture->internal_format : GL_ZERO);
|
|
};
|
|
|
|
RenderTexture& render_buffer = render.rend_texture[0];
|
|
RenderTexture& reflect_buffer = render_manager->get_render_texture(1);
|
|
RenderTexture& shadow_buffer = shadow_ptr_get()->render_textures[1];
|
|
init_copy_buffer(reflect_buffer, this->reflect_buffer);
|
|
init_copy_buffer(render_buffer, this->render_buffer);
|
|
init_copy_buffer(shadow_buffer, this->shadow_buffer);
|
|
|
|
screen_buffer.Init(sprite_width, sprite_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F
|
|
}
|
|
|
|
void render_context::light_param_data_light_set(light_param_light * light) {
|
|
for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) {
|
|
light_param_light_group* group = &light->group[i];
|
|
::light_set* set = &light_set[i];
|
|
|
|
for (int32_t j = LIGHT_CHARA; j < LIGHT_MAX; j++) {
|
|
light_param_light_data* data = &group->data[j];
|
|
light_data* light = &set->lights[j];
|
|
|
|
if (data->has_type)
|
|
light->set_type(data->type);
|
|
|
|
if (data->has_ambient)
|
|
light->set_ambient(data->ambient);
|
|
|
|
if (data->has_diffuse)
|
|
light->set_diffuse(data->diffuse);
|
|
|
|
if (data->has_specular)
|
|
light->set_specular(data->specular);
|
|
|
|
if (data->has_position)
|
|
light->set_position(data->position);
|
|
|
|
if (data->has_spot_direction)
|
|
light->set_spot_direction(data->spot_direction);
|
|
|
|
if (data->has_spot_exponent)
|
|
light->set_spot_exponent(data->spot_exponent);
|
|
|
|
if (data->has_spot_cutoff)
|
|
light->set_spot_cutoff(data->spot_cutoff);
|
|
|
|
if (data->has_attenuation)
|
|
light->set_attenuation(data->attenuation);
|
|
|
|
light->set_clip_plane(data->clip_plane);
|
|
|
|
if (data->has_tone_curve)
|
|
light->set_tone_curve(data->tone_curve);
|
|
}
|
|
}
|
|
}
|
|
|
|
void render_context::light_param_data_fog_set(light_param_fog* f) {
|
|
for (int32_t i = FOG_DEPTH; i < FOG_MAX; i++) {
|
|
light_param_fog_group* group = &f->group[i];
|
|
::fog* fog = &this->fog[i];
|
|
|
|
if (group->has_type)
|
|
fog->set_type(group->type);
|
|
|
|
if (group->has_density)
|
|
fog->set_density(group->density);
|
|
|
|
if (group->has_linear) {
|
|
fog->set_start(group->linear_start);
|
|
fog->set_end(group->linear_end);
|
|
}
|
|
|
|
if (group->has_color)
|
|
fog->set_color(group->color);
|
|
}
|
|
}
|
|
|
|
void render_context::light_param_data_glow_set(light_param_glow* glow) {
|
|
render.set_auto_exposure(true);
|
|
render.set_tone_map(TONE_MAP_YCC_EXPONENT);
|
|
render.reset_saturate_coeff(0, false);
|
|
render.reset_scene_fade(0);
|
|
render.reset_tone_trans(0);
|
|
|
|
if (glow->has_exposure)
|
|
render.set_exposure(glow->exposure);
|
|
|
|
if (glow->has_gamma)
|
|
render.set_gamma(glow->gamma);
|
|
|
|
if (glow->has_saturate_power)
|
|
render.set_saturate_power(glow->saturate_power);
|
|
|
|
if (glow->has_saturate_coef)
|
|
render.set_saturate_coeff(glow->saturate_coef, 0, false);
|
|
|
|
if (glow->has_flare)
|
|
render.set_lens(glow->flare);
|
|
|
|
if (glow->has_sigma)
|
|
render.set_radius(glow->sigma);
|
|
|
|
if (glow->has_intensity)
|
|
render.set_intensity(glow->intensity);
|
|
|
|
if (glow->has_auto_exposure)
|
|
render.set_auto_exposure(glow->auto_exposure);
|
|
|
|
if (glow->has_tone_map_method)
|
|
render.set_tone_map(glow->tone_map_method);
|
|
|
|
if (glow->has_fade_color) {
|
|
vec4 fade_color = glow->fade_color;
|
|
render.set_scene_fade(fade_color, 0);
|
|
render.set_scene_fade_blend_func(glow->fade_color_blend_func, 0);
|
|
}
|
|
|
|
if (glow->has_tone_transform)
|
|
render.set_tone_trans(glow->tone_transform_start, glow->tone_transform_end, 0);
|
|
}
|
|
|
|
void render_context::light_param_data_ibl_set(
|
|
light_param_ibl* ibl, light_param_data_storage* storage) {
|
|
if (!ibl->ready)
|
|
return;
|
|
|
|
for (int32_t i = 0, j = -1; i < 5; i++, j++) {
|
|
gl_state_bind_texture_cube_map(storage->textures[i]);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
if (!i) {
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
|
render_context_light_param_data_ibl_set_diffuse(&ibl->diffuse[0], 0);
|
|
render_context_light_param_data_ibl_set_diffuse(&ibl->diffuse[1], 1);
|
|
}
|
|
else {
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, ibl->specular[j].max_level);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS, 0.0f);
|
|
render_context_light_param_data_ibl_set_specular(&ibl->specular[j]);
|
|
}
|
|
}
|
|
gl_state_bind_texture_cube_map(0);
|
|
|
|
::light_set* set = &light_set[LIGHT_SET_MAIN];
|
|
set->set_irradiance(ibl->diff_coef[1][0], ibl->diff_coef[1][1], ibl->diff_coef[1][2]);
|
|
|
|
float_t len;
|
|
vec3 pos;
|
|
|
|
light_data* l = &set->lights[LIGHT_CHARA];
|
|
l->get_position(pos);
|
|
len = vec3::length(pos);
|
|
if (fabsf(len - 1.0f) < 0.02f)
|
|
l->set_position(ibl->lit_dir[0]);
|
|
|
|
l->set_ibl_color0(ibl->lit_col[0]);
|
|
l->set_ibl_color1(ibl->lit_col[2]);
|
|
l->set_ibl_direction(ibl->lit_dir[0]);
|
|
|
|
l = &set->lights[LIGHT_STAGE];
|
|
l->get_position(pos);
|
|
len = vec3::length(pos);
|
|
if (fabsf(len - 1.0f) < 0.02f)
|
|
l->set_position(ibl->lit_dir[1]);
|
|
|
|
l->set_ibl_color0(ibl->lit_col[1]);
|
|
l->set_ibl_direction(ibl->lit_dir[1]);
|
|
}
|
|
|
|
void render_context::light_param_data_wind_set(light_param_wind* w) {
|
|
wind* wind = task_wind->ptr;
|
|
if (w->has_scale)
|
|
wind->scale = w->scale;
|
|
|
|
if (w->has_cycle)
|
|
wind->cycle = w->cycle;
|
|
|
|
if (w->has_rot) {
|
|
wind->rot_y = w->rot_y;
|
|
wind->rot_z = w->rot_z;
|
|
}
|
|
|
|
if (w->has_bias)
|
|
wind->bias = w->bias;
|
|
|
|
for (int32_t i = 0; i < 16; i++)
|
|
if (w->has_spc[i]) {
|
|
wind->spc[i].cos = w->spc[i].cos;
|
|
wind->spc[i].sin = w->spc[i].sin;
|
|
}
|
|
}
|
|
|
|
void render_context::light_param_data_face_set(light_param_face* face) {
|
|
this->face.set_offset(face->offset);
|
|
this->face.set_scale(face->scale);
|
|
this->face.set_position(face->position);
|
|
this->face.set_direction(face->direction);
|
|
}
|
|
|
|
void render_context::resize(int32_t render_width, int32_t render_height,
|
|
int32_t sprite_width, int32_t sprite_height,
|
|
int32_t screen_width, int32_t screen_height) {
|
|
bool render_res_change = render.inner_width != render_width || render.inner_height != render_height;
|
|
bool sprite_res_change = this->sprite_width != sprite_width || this->sprite_height != sprite_height;
|
|
bool screen_res_change = this->screen_width != screen_width || this->screen_height != screen_height;
|
|
if (!render_res_change && !sprite_res_change && !screen_res_change)
|
|
return;
|
|
|
|
this->sprite_width = sprite_width;
|
|
this->sprite_height = sprite_height;
|
|
|
|
screen_x_offset = (screen_width - sprite_width) / 2 + (screen_width - sprite_width) % 2;
|
|
screen_y_offset = (screen_height - sprite_height) / 2 + (screen_height - sprite_height) % 2;
|
|
|
|
this->screen_width = screen_width;
|
|
this->screen_height = screen_height;
|
|
|
|
if (render_res_change)
|
|
render.resize(render_width, render_height);
|
|
|
|
if (sprite_res_change)
|
|
render_manager->resize(sprite_width, sprite_height);
|
|
|
|
if (render_res_change)
|
|
litproj->resize(render_width, render_height);
|
|
|
|
sprite_manager_set_res((double_t)sprite_width / (double_t)sprite_height,
|
|
sprite_width, sprite_height);
|
|
|
|
if (render_res_change) {
|
|
free();
|
|
init();
|
|
}
|
|
}
|
|
|
|
static void render_context_light_param_data_ibl_set_diffuse(light_param_ibl_diffuse* diffuse, int32_t level) {
|
|
int32_t size = diffuse->size;
|
|
size_t data_size = size;
|
|
data_size = 4 * data_size * data_size;
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &diffuse->data[data_size * 0]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &diffuse->data[data_size * 1]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &diffuse->data[data_size * 2]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &diffuse->data[data_size * 3]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &diffuse->data[data_size * 4]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &diffuse->data[data_size * 5]);
|
|
}
|
|
|
|
static void render_context_light_param_data_ibl_set_specular(light_param_ibl_specular* specular) {
|
|
int32_t size = specular->size;
|
|
int32_t max_level = specular->max_level;
|
|
for (int32_t i = 0; i <= max_level; i++, size /= 2) {
|
|
std::vector<half_t>& data = specular->data[i];
|
|
size_t data_size = size;
|
|
data_size = 4 * data_size * data_size;
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, i, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &data[data_size * 0]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, i, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &data[data_size * 1]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, i, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &data[data_size * 2]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, i, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &data[data_size * 3]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, i, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &data[data_size * 4]);
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, i, GL_RGBA16F,
|
|
size, size, 0, GL_RGBA, GL_HALF_FLOAT, &data[data_size * 5]);
|
|
}
|
|
}
|