142 lines
3.9 KiB
C
142 lines
3.9 KiB
C
|
|
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]);
|
|
}
|