/* 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; }