Archived
1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
skcblitz/drawlist.h
2025-09-02 14:43:36 +02:00

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]);
}