215 lines
6.5 KiB
C
215 lines
6.5 KiB
C
|
|
/*
|
|
void light_set_shader(light_t *light, uint id) {
|
|
int pos;
|
|
char str[32];
|
|
pos = sprintf(str, "lights[%d].", id);
|
|
sprintf(str+pos, "position");
|
|
shd_vec3(str, light->pos);
|
|
sprintf(str+pos, "ambient");
|
|
shd_vec3(str, light->ambient);
|
|
sprintf(str+pos, "diffuse");
|
|
shd_vec3(str, light->diffuse);
|
|
sprintf(str+pos, "specular");
|
|
shd_vec3(str, light->specular);
|
|
sprintf(str+pos, "range");
|
|
shd_vec3(str, light->range);
|
|
sprintf(str+pos, "constant");
|
|
shd_float(str, light->constant);
|
|
sprintf(str+pos, "linear");
|
|
shd_float(str, light->linear);
|
|
sprintf(str+pos, "quadratic");
|
|
shd_float(str, light->quadratic);
|
|
sprintf(str+pos, "enabled");
|
|
shd_bool(str, 1);
|
|
}
|
|
|
|
void light_unset_shader(uint id) {
|
|
char str[32];
|
|
sprintf(str, "lights[%d].enabled", id);
|
|
shd_bool(str, 0);
|
|
}
|
|
*/
|
|
|
|
void light_calc(world_t *world) {
|
|
int x1 = ((int)world->camera.pos_x) / CHUNK_SIZE;
|
|
int y1 = ((int)world->camera.pos_y) / CHUNK_SIZE;
|
|
int z1 = ((int)world->camera.pos_z) / CHUNK_SIZE;
|
|
int x2 = x1 + gdr.light_dist_chunk;
|
|
int y2 = y1 + gdr.light_dist_chunk;
|
|
int z2 = z1 + gdr.light_dist_chunk;
|
|
ulong pos;
|
|
chunk_t *chunk;
|
|
light_t *light;
|
|
x1 -= gdr.light_dist_chunk;
|
|
y1 -= gdr.light_dist_chunk;
|
|
z1 -= gdr.light_dist_chunk;
|
|
// x1 = CHUNK_CLAMP(world, x1, x);
|
|
// y1 = CHUNK_CLAMP(world, y1, y);
|
|
// z1 = CHUNK_CLAMP(world, z1, z);
|
|
// x2 = CHUNK_CLAMP(world, x2, x);
|
|
// y2 = CHUNK_CLAMP(world, y2, y);
|
|
// z2 = CHUNK_CLAMP(world, z2, z);
|
|
// glBufferData(GL_UNIFORM_BUFFER, sizeof(float) * 18 * gdr.light_max, NULL, GL_DYNAMIC_DRAW);
|
|
// memset(world->lights, 0, sizeof(light_t) * gdr.light_max);
|
|
world->s_lights = 0;
|
|
if(!gdr.light_max)
|
|
return;
|
|
glBindBuffer(GL_UNIFORM_BUFFER, world->light_buf);
|
|
for(int cx = x1; cx <= x2; cx++) {
|
|
for(int cz = z1; cz <= z2; cz++) {
|
|
for(int cy = y1; cy <= y2; cy++) {
|
|
if(!(chunk = chunk_get(world, cx, cy, cz, 0)))
|
|
continue;
|
|
pos = 0;
|
|
while(light = tbl_iter(&chunk->light_table, &pos)) {
|
|
// if(nndist) {
|
|
// if(light_add(world, light) == 0xffffffff)
|
|
// return;
|
|
glBufferSubData(GL_UNIFORM_BUFFER, LIGHT_SSIZE * world->s_lights, LIGHT_SSIZE, light);
|
|
// memcpy(&world->lights[world->s_lights], light, sizeof(shdlight_t));
|
|
if((world->s_lights += 1) >= gdr.light_max) {
|
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
return;
|
|
}
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
}
|
|
|
|
/*
|
|
uint light_add(float x, float y, float z, uint color) {
|
|
light_t *light;
|
|
uint id;
|
|
if(!(world->lights))
|
|
return 0xffffffff;
|
|
if((id = lst_push(&world->light_list)) == 0xffffffff)
|
|
return 0xffffffff;
|
|
light = &world->lights[id];
|
|
light_init_def(light, x, y, z, color);
|
|
shd_sel(gdr.shd_world, 0);
|
|
light_set_shader(light, id);
|
|
world->s_lights += 1;
|
|
shd_int("n_lights", world->s_lights);
|
|
logd("TST", "l %d @ %.3f %.3f %.3f: %06x, %.1f %.1f %.1f", id, x, y, z, color, light->diffuse[0], light->diffuse[1], light->diffuse[2]);
|
|
return id;
|
|
}
|
|
*/
|
|
|
|
// void light_remove(world_t *world, uint id) {
|
|
// lst_pop(&world->light_list, id);
|
|
// shd_sel(gdr.shd_world, world);
|
|
// glBindBuffer(GL_UNIFORM_BUFFER, world->light_buf);
|
|
// light_unset_shader(id);
|
|
// world->s_lights -= 1;
|
|
// shd_int("n_lights", world->s_lights);
|
|
// }
|
|
|
|
// void light_refresh() {
|
|
// if(world->world)
|
|
// light_calc(world->world);
|
|
// /*
|
|
// for(int z = 0; z < gdr.light_max; z++) {
|
|
// light_add(((float)(rand() % 20000)) / 100.0f - 100.0f, 1.0f, ((float)(rand() % 20000)) / 100.0f - 100.0f, (rand() % 0xffffff) | 0x404040);
|
|
// }
|
|
// */
|
|
// }
|
|
|
|
// void light_end(world_t *world) {
|
|
// if(world->lights) {
|
|
// mem_free(world->lights);
|
|
// world->lights = NULL;
|
|
// }
|
|
// }
|
|
|
|
// void light_init(world_t *world) {
|
|
// light_end(world);
|
|
// if(gdr.light_max)
|
|
// world->lights = mem_alloc(sizeof(light_t) * gdr.light_max, MEM_LIGHTS);
|
|
// light_calc(world);
|
|
// }
|
|
|
|
void light_setup(int max) {
|
|
window_t *win;
|
|
gdr.light_max = max;
|
|
shd_refresh();
|
|
for(win = wcf.window_list; win; win = win->next) {
|
|
if(win->world) {
|
|
glNamedBufferData(win->world->light_buf, LIGHT_SSIZE * gdr.light_max, NULL, GL_DYNAMIC_DRAW);
|
|
light_calc(win->world);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
void light_map_fill(const float *polys, int n_polys, uint color, float fog) {
|
|
buf_data(gdr.buf_lightmap, polys, n_polys * 3);
|
|
glBindVertexArray(gdr.vao_lightmap);
|
|
shd_sel(gdr.shd_lightmap, 1);
|
|
shd_vec2v("size", (float)(TEMP_LM_SIZE * CHUNK_SIZE), (float)(TEMP_LM_SIZE * CHUNK_SIZE));
|
|
shd_scolor("color", color);
|
|
shd_float("fog", fog);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, gdr.fb_lightmap);
|
|
glViewport(0, 0, TEMP_LM_SIZE * CHUNK_SIZE, TEMP_LM_SIZE * CHUNK_SIZE);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_BLEND);
|
|
glDrawArrays(GL_TRIANGLES, 0, n_polys * 3);
|
|
glEnable(GL_BLEND);
|
|
glViewport(0, 0, wcf.current->fb_x, wcf.current->fb_y);
|
|
buf_data(gdr.buf_lightmap, NULL, 0);
|
|
}
|
|
|
|
void light_map_rect(int x1, int z1, int x2, int z2, uint color, float fog) {
|
|
x2 -= x1;
|
|
z2 -= z1;
|
|
x1 += (CHUNK_SIZE * (TEMP_LM_SIZE / 2));
|
|
z1 += (CHUNK_SIZE * (TEMP_LM_SIZE / 2));
|
|
glBindFramebuffer(GL_FRAMEBUFFER, gdr.fb_lightmap);
|
|
glClearColor(
|
|
(float)((uint)((color >> 16) & 0xff)) / 255.0f,
|
|
(float)((uint)((color >> 8) & 0xff)) / 255.0f,
|
|
(float)((uint)(color & 0xff)) / 255.0f,
|
|
fog);
|
|
glViewport(0, 0, TEMP_LM_SIZE * CHUNK_SIZE, TEMP_LM_SIZE * CHUNK_SIZE);
|
|
glScissor(x1, z1, x2, z2);
|
|
// logd(LOG_SYS, "n %d %d %d %d", x1, z1, x2, z2);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
glDisable(GL_SCISSOR_TEST);
|
|
glViewport(0, 0, wcf.current->fb_x, wcf.current->fb_y);
|
|
}
|
|
|
|
void light_map_clear() {
|
|
fb_size(gdr.fbt_lightmap, TEMP_LM_SIZE * CHUNK_SIZE, TEMP_LM_SIZE * CHUNK_SIZE);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, gdr.fb_lightmap);
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
*/
|
|
|
|
void light_init_base(light_t *light, light_b *lamp) {
|
|
float r = (float)((uint)((lamp->color >> 16) & 0xff)) / 255.0f;
|
|
float g = (float)((uint)((lamp->color >> 8) & 0xff)) / 255.0f;
|
|
float b = (float)((uint)(lamp->color & 0xff)) / 255.0f;
|
|
VEC3_SET(light->ambient, r * lamp->amb_fact, g * lamp->amb_fact, b * lamp->amb_fact);
|
|
VEC3_SET(light->diffuse, r * lamp->dif_fact, g * lamp->dif_fact, b * lamp->dif_fact);
|
|
VEC3_SET(light->specular, r, g, b);
|
|
VEC3_SET(light->range, lamp->range_xz, lamp->range_y, lamp->range_xz);
|
|
light->constant = lamp->constant;
|
|
light->linear = lamp->linear;
|
|
light->quadratic = lamp->quadratic;
|
|
}
|
|
|
|
void light_init_def(light_b *light, uint color, float brightness) {
|
|
light->color = color;
|
|
light->amb_fact = brightness;
|
|
light->dif_fact = MIN_VALUE(brightness * 16.0f, 1.0f);
|
|
light->range_xz = 1.0f;
|
|
light->range_y = 1.0f;
|
|
light->constant = 1.0f;
|
|
light->linear = 0.09f;
|
|
light->quadratic = 0.032f;
|
|
}
|