/* * @brief Generates vertex primitives for the world model by iterating leafs. */ static void R_LoadBspVertexArrays(r_model_t *mod) { uint16_t i, j; R_AllocVertexArrays(mod); GLuint count = 0; const r_bsp_leaf_t *leaf = mod->bsp->leafs; for (i = 0; i < mod->bsp->num_leafs; i++, leaf++) { r_bsp_surface_t **s = leaf->first_leaf_surface; for (j = 0; j < leaf->num_leaf_surfaces; j++, s++) { R_LoadBspVertexArrays_Surface(mod, *s, &count); } } }
/* * R_LoadBspVertexArrays */ static void R_LoadBspVertexArrays(void) { int i, j; int vert_index, texcoord_index, tangent_index, color_index; float soff, toff, s, t; float *point, *normal, *sdir, *tdir; vec4_t tangent; vec3_t bitangent; r_bsp_surface_t *surf; r_bsp_edge_t *edge; r_bsp_vertex_t *vert; R_AllocVertexArrays(r_load_model); // allocate the arrays vert_index = texcoord_index = tangent_index = 0; surf = r_load_model->surfaces; for (i = 0; i < r_load_model->num_surfaces; i++, surf++) { surf->index = vert_index / 3; for (j = 0; j < surf->num_edges; j++) { const int index = r_load_model->surface_edges[surf->first_edge + j]; // vertex if (index > 0) { // negative indices to differentiate which end of the edge edge = &r_load_model->edges[index]; vert = &r_load_model->vertexes[edge->v[0]]; } else { edge = &r_load_model->edges[-index]; vert = &r_load_model->vertexes[edge->v[1]]; } point = vert->position; memcpy(&r_load_model->verts[vert_index], point, sizeof(vec3_t)); // texture directional vectors and offsets sdir = surf->texinfo->vecs[0]; soff = surf->texinfo->vecs[0][3]; tdir = surf->texinfo->vecs[1]; toff = surf->texinfo->vecs[1][3]; // texture coordinates s = DotProduct(point, sdir) + soff; s /= surf->texinfo->image->width; t = DotProduct(point, tdir) + toff; t /= surf->texinfo->image->height; r_load_model->texcoords[texcoord_index + 0] = s; r_load_model->texcoords[texcoord_index + 1] = t; if (surf->flags & R_SURF_LIGHTMAP) { // lightmap coordinates s = DotProduct(point, sdir) + soff; s -= surf->st_mins[0]; s += surf->light_s * r_load_model->lightmap_scale; s += r_load_model->lightmap_scale / 2.0; s /= r_lightmaps.size * r_load_model->lightmap_scale; t = DotProduct(point, tdir) + toff; t -= surf->st_mins[1]; t += surf->light_t * r_load_model->lightmap_scale; t += r_load_model->lightmap_scale / 2.0; t /= r_lightmaps.size * r_load_model->lightmap_scale; } r_load_model->lmtexcoords[texcoord_index + 0] = s; r_load_model->lmtexcoords[texcoord_index + 1] = t; // normal vector if ((surf->texinfo->flags & SURF_PHONG) && !VectorCompare( vert->normal, vec3_origin)) // phong shaded normal = vert->normal; else // per-plane normal = surf->normal; memcpy(&r_load_model->normals[vert_index], normal, sizeof(vec3_t)); // tangent vector TangentVectors(normal, sdir, tdir, tangent, bitangent); memcpy(&r_load_model->tangents[tangent_index], tangent, sizeof(vec4_t)); // accumulate colors R_AddBspVertexColor(vert, surf); vert_index += 3; texcoord_index += 2; tangent_index += 4; } } color_index = 0; surf = r_load_model->surfaces; // now iterate over the verts again, assembling the accumulated colors for (i = 0; i < r_load_model->num_surfaces; i++, surf++) { for (j = 0; j < surf->num_edges; j++) { const int index = r_load_model->surface_edges[surf->first_edge + j]; // vertex if (index > 0) { // negative indices to differentiate which end of the edge edge = &r_load_model->edges[index]; vert = &r_load_model->vertexes[edge->v[0]]; } else { edge = &r_load_model->edges[-index]; vert = &r_load_model->vertexes[edge->v[1]]; } memcpy(&r_load_model->colors[color_index], vert->color, sizeof(vec4_t)); color_index += 4; } } }