vertbuffer_t gs_rendersave(void) { graphics_t graphics = thread_graphics; size_t num_tex, i; if (graphics->using_immediate) return NULL; if (!graphics->vbd->num) { vbdata_destroy(graphics->vbd); return NULL; } for (num_tex = 0; num_tex < 16; num_tex++) { if (!graphics->texverts[num_tex].num) break; } graphics->vbd->points = graphics->verts.array; graphics->vbd->normals = graphics->norms.array; graphics->vbd->colors = graphics->colors.array; graphics->vbd->num = graphics->verts.num; graphics->vbd->num_tex = num_tex; graphics->vbd->tvarray = bmalloc(sizeof(struct tvertarray) * num_tex); for (i = 0; i < num_tex; i++) { graphics->vbd->tvarray[i].width = 2; graphics->vbd->tvarray[i].array = graphics->texverts[i].array; } reset_immediate_arrays(graphics); return gs_create_vertexbuffer(graphics->vbd, 0); }
void vertexbuffer_destroy(vertbuffer_t vb) { if (vb) { if (vb->vertex_buffer) gl_delete_buffers(1, &vb->vertex_buffer); if (vb->normal_buffer) gl_delete_buffers(1, &vb->normal_buffer); if (vb->tangent_buffer) gl_delete_buffers(1, &vb->tangent_buffer); if (vb->color_buffer) gl_delete_buffers(1, &vb->color_buffer); if (vb->uv_buffers.num) gl_delete_buffers((GLsizei)vb->uv_buffers.num, vb->uv_buffers.array); if (vb->vao) gl_delete_vertex_arrays(1, &vb->vao); da_free(vb->uv_sizes); da_free(vb->uv_buffers); vbdata_destroy(vb->data); bfree(vb); } }
void gs_renderstop(enum gs_draw_mode mode) { graphics_t graphics = thread_graphics; size_t i, num = graphics->verts.num; if (!num) { if (!graphics->using_immediate) { da_free(graphics->verts); da_free(graphics->norms); da_free(graphics->colors); for (i = 0; i < 16; i++) da_free(graphics->texverts[i]); vbdata_destroy(graphics->vbd); } return; } if (graphics->norms.num && (graphics->norms.num != graphics->verts.num)) { blog(LOG_WARNING, "gs_renderstop: normal count does " "not match vertex count"); num = min_size(num, graphics->norms.num); } if (graphics->colors.num && (graphics->colors.num != graphics->verts.num)) { blog(LOG_WARNING, "gs_renderstop: color count does " "not match vertex count"); num = min_size(num, graphics->colors.num); } if (graphics->texverts[0].num && (graphics->texverts[0].num != graphics->verts.num)) { blog(LOG_WARNING, "gs_renderstop: texture vertex count does " "not match vertex count"); num = min_size(num, graphics->texverts[0].num); } if (graphics->using_immediate) { vertexbuffer_flush(graphics->immediate_vertbuffer, false); gs_load_vertexbuffer(graphics->immediate_vertbuffer); gs_load_indexbuffer(NULL); gs_draw(mode, 0, (uint32_t)num); reset_immediate_arrays(graphics); } else { vertbuffer_t vb = gs_rendersave(); gs_load_vertexbuffer(vb); gs_load_indexbuffer(NULL); gs_draw(mode, 0, 0); vertexbuffer_destroy(vb); } graphics->vbd = NULL; }
static bool create_buffers(struct gs_vertex_buffer *vb) { GLenum usage = vb->dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; size_t i; if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->vertex_buffer, vb->data->num * sizeof(struct vec3), vb->data->points, usage)) return false; if (vb->data->normals) { if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->normal_buffer, vb->data->num * sizeof(struct vec3), vb->data->normals, usage)) return false; } if (vb->data->tangents) { if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->tangent_buffer, vb->data->num * sizeof(struct vec3), vb->data->tangents, usage)) return false; } if (vb->data->colors) { if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->color_buffer, vb->data->num * sizeof(uint32_t), vb->data->colors, usage)) return false; } da_reserve(vb->uv_buffers, vb->data->num_tex); da_reserve(vb->uv_sizes, vb->data->num_tex); for (i = 0; i < vb->data->num_tex; i++) { GLuint tex_buffer; struct tvertarray *tv = vb->data->tvarray+i; size_t size = vb->data->num * sizeof(float) * tv->width; if (!gl_create_buffer(GL_ARRAY_BUFFER, &tex_buffer, size, tv->array, usage)) return false; da_push_back(vb->uv_buffers, &tex_buffer); da_push_back(vb->uv_sizes, &tv->width); } if (!vb->dynamic) { vbdata_destroy(vb->data); vb->data = NULL; } if (!gl_gen_vertex_arrays(1, &vb->vao)) return false; return true; }