void draw_set_material(world_t *world, material_t *mat) { shd_sel(mat->shader ? mat->shader : gdr.shd_world, world); shd_scolor("specular", mat->spec_color); shd_float("shine", mat->shine); shd_float("density", mat->density); if(mat->texture) glBindTexture(GL_TEXTURE_2D, mat->texture); } int draw_dispatch(world_t *world, drawlist_t *list) { int drawn = 0; draw_t *draw; mat4 mat; glm_mat4_identity(mat); glm_translate(mat, list->position); glBindVertexArray(list->vao); for(int z = 0; z < list->size; z++) { draw = &list->draws[z]; draw_set_material(world, draw->material); shd_mat4("model", mat); glDrawArrays(GL_TRIANGLES, draw->offset, draw->size); drawn += draw->size; } return drawn; } void draw_world(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.ldist_chunk_xz; int y2 = y1 + gdr.ldist_chunk_y; int z2 = z1 + gdr.ldist_chunk_xz; int lists = 0; int drawn = 0; chunk_t *chunk; // = &world->global; x1 -= gdr.ldist_chunk_xz; y1 -= gdr.ldist_chunk_y; z1 -= gdr.ldist_chunk_xz; // 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); // if(chunk->drawlist) { // drawn += draw_dispatch(chunk->drawlist); // lists++; // } 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; if(chunk->drawlist) { drawn += draw_dispatch(world, chunk->drawlist); lists++; } } } } gdr.lists_drawn += lists; gdr.tris_drawn += drawn / 3; } /* void draw_floor(world_t *world) { if(!(world->flat_tex)) return; mat4 mat; glm_mat4_identity(mat); glm_scale(mat, world->flat_scale); glm_translate(mat, world->flat_offset); shd_mat4("model", mat); glBindVertexArray(gdr.vao_box); glBindTexture(GL_TEXTURE_2D, world->flat_tex); draw_set_material(world->flat_mat); glDrawArrays(GL_TRIANGLES, 30, 6); } */ void draw_destroy(drawlist_t *list) { if(list->bind) buf_destroy(list->bind); if(list->draws) mem_free(list->draws); list->size = 0; list->draws = NULL; list->bind = NULL; } void draw_build(chunk_t *chunk, drawlist_t *list) { int pos; int done; int verts; uint id; material_t *material; polygon_t *poly; float *vert; draw_t *draw; float *vertices = mem_alloc(chunk->poly_list.stored * 3 * sizeof(vertex_t), MEM_POLY); list->size = 0; list->draws = NULL; for(done = 0; done < chunk->poly_list.stored; list->size += 1) { list->draws = mem_realloc(list->draws, sizeof(draw_t) * (list->size + 1), MEM_POLY); draw = &list->draws[list->size]; verts = 0; material = NULL; pos = 0; draw->offset = done * 3; while((id = lst_iter(&chunk->poly_list, &pos)) != 0xffffffff) { poly = &chunk->poly_pool[id]; if(!material) { material = poly->material; for(int z = 0; z < list->size; z++) { if(material == list->draws[z].material) { material = NULL; break; } } if(!material) continue; } else if(material != poly->material) { // logd("nnt", "C %d %d %d %d %.3f %.3f", texture, poly->texture, material, poly->material, density, poly->density); continue; } sys_assert(done < chunk->poly_list.stored) memcpy(&vertices[24 * done], poly->vertices, 3 * sizeof(vertex_t)); done++; verts++; } draw->size = verts * 3; draw->material = material; // logd("nnt", "L %d %d %d %.3f", draw->size, draw->texture, draw->material, draw->density); } list->bind = buf_init(0, &list->vbo, &list->vao, vertices, done * 3 * sizeof(vertex_t), 8, 3, 3, 2); mem_free(vertices); VEC3_SET(list->position, chunk->box.x1, chunk->box.y1, chunk->box.z1); // logd("nnt", "= %d @ %.3f %.3f %.3f", list->size, list->position[0], list->position[1], list->position[2]); }