/* * R_DrawSurfacesLines_default */ static void R_DrawSurfacesLines_default(const r_bsp_surfaces_t *surfs) { unsigned int i; R_EnableTexture(&texunit_diffuse, false); R_EnableColorArray(true); R_SetArrayState(r_world_model); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); for (i = 0; i < surfs->count; i++) { if (surfs->surfaces[i]->frame != r_locals.frame) continue; R_DrawSurface_default(surfs->surfaces[i]); } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); R_EnableColorArray(false); R_EnableTexture(&texunit_diffuse, true); }
/** * @brief Manages state for stages supporting static, dynamic, and per-pixel lighting. */ static void R_StageLighting (const mBspSurface_t *surf, const materialStage_t *stage) { /* if the surface has a lightmap, and the stage specifies lighting.. */ if ((surf->flags & MSURF_LIGHTMAP) && (stage->flags & (STAGE_LIGHTMAP | STAGE_LIGHTING))) { R_EnableTexture(&texunit_lightmap, true); R_BindLightmapTexture(surf->lightmap_texnum); /* hardware lighting */ /** @todo fix it and enable it back for r_materials 1 */ if (r_materials->integer > 1) { if ((stage->flags & STAGE_LIGHTING)) { R_EnableLighting(r_state.world_program, true); R_SetSurfaceBumpMappingParameters(surf, stage->image->normalmap, stage->image->specularmap); } else { R_SetSurfaceBumpMappingParameters(surf, nullptr, nullptr); R_EnableLighting(nullptr, false); } } } else { if (!r_state.lighting_enabled) return; R_EnableLighting(nullptr, false); R_EnableTexture(&texunit_lightmap, false); } }
/* * @brief */ static void R_DrawLines(void) { if (!r_draw.line_arrays.vert_index) return; R_EnableTexture(&texunit_diffuse, false); R_EnableColorArray(true); // alter the array pointers R_BindArray(GL_VERTEX_ARRAY, GL_SHORT, r_draw.line_arrays.verts); R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_draw.line_arrays.colors); glDrawArrays(GL_LINES, 0, r_draw.line_arrays.vert_index / 2); // and restore them R_BindDefaultArray(GL_VERTEX_ARRAY); R_BindDefaultArray(GL_COLOR_ARRAY); R_EnableColorArray(false); R_EnableTexture(&texunit_diffuse, true); r_draw.line_arrays.vert_index = r_draw.line_arrays.color_index = 0; }
void R_DrawFills (void) { if (!r_fill_arrays.vert_index) return; R_EnableTexture(&texunit_diffuse, false); R_EnableColorArray(true); /* alter the array pointers */ R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_fill_arrays.colors); glVertexPointer(2, GL_SHORT, 0, r_fill_arrays.verts); glDrawArrays(GL_QUADS, 0, r_fill_arrays.vert_index / 2); refdef.batchCount++; /* and restore them */ R_BindDefaultArray(GL_VERTEX_ARRAY); R_BindDefaultArray(GL_COLOR_ARRAY); R_EnableColorArray(false); R_EnableTexture(&texunit_diffuse, true); r_fill_arrays.vert_index = r_fill_arrays.color_index = 0; R_Color(NULL); }
/** * @brief Developer tool for viewing BSP vertex normals. Only Phong interpolated * surfaces show their normals when r_shownormals > 1. */ void R_DrawBspNormals (int tile) { int i, j, k; const mBspSurface_t* surf; const mBspModel_t* bsp; const vec4_t color = {1.0, 0.0, 0.0, 1.0}; if (!r_shownormals->integer) return; R_EnableTexture(&texunit_diffuse, false); R_ResetArrayState(); /* default arrays */ R_Color(color); k = 0; bsp = &r_mapTiles[tile]->bsp; surf = bsp->surfaces; for (i = 0; i < bsp->numsurfaces; i++, surf++) { if (surf->frame != r_locals.frame) continue; /* not visible */ if (surf->texinfo->flags & SURF_WARP) continue; /* don't care */ if (r_shownormals->integer > 1 && !(surf->texinfo->flags & SURF_PHONG)) continue; /* don't care */ /* avoid overflows, draw in batches */ if (k > r_state.array_size - 512) { glDrawArrays(GL_LINES, 0, k / 3); k = 0; refdef.batchCount++; } for (j = 0; j < surf->numedges; j++) { vec3_t end; const GLfloat* vertex = &bsp->verts[(surf->index + j) * 3]; const GLfloat* normal = &bsp->normals[(surf->index + j) * 3]; VectorMA(vertex, 12.0, normal, end); memcpy(&r_state.vertex_array_3d[k], vertex, sizeof(vec3_t)); memcpy(&r_state.vertex_array_3d[k + 3], end, sizeof(vec3_t)); k += sizeof(vec3_t) / sizeof(vec_t) * 2; R_ReallocateStateArrays(k); } } glDrawArrays(GL_LINES, 0, k / 3); refdef.batchCount++; R_EnableTexture(&texunit_diffuse, true); R_Color(nullptr); }
/* * @brief */ void R_DrawCoronas(void) { if (!r_coronas->value) return; if (!r_view.num_coronas) return; R_EnableTexture(&texunit_diffuse, false); R_EnableColorArray(true); R_ResetArrayState(); R_BlendFunc(GL_SRC_ALPHA, GL_ONE); for (uint16_t i = 0; i < r_view.num_coronas; i++) { const r_corona_t *c = &r_view.coronas[i]; const vec_t f = c->radius * c->flicker * sin(0.09 * r_view.time); // use at least 12 verts, more for larger coronas const uint16_t num_verts = Clamp(c->radius / 8.0, 12, 64); memcpy(&r_state.color_array[0], c->color, sizeof(vec3_t)); r_state.color_array[3] = r_coronas->value; // set origin color // and the corner colors memset(&r_state.color_array[4], 0, num_verts * 2 * sizeof(vec4_t)); memcpy(&r_state.vertex_array_3d[0], c->origin, sizeof(vec3_t)); uint32_t vert_index = 3; // and the origin for (uint16_t j = 0; j <= num_verts; j++) { // now draw the corners const vec_t a = j / (vec_t) num_verts * M_PI * 2; vec3_t v; VectorCopy(c->origin, v); VectorMA(v, cos(a) * (c->radius + f), r_view.right, v); VectorMA(v, sin(a) * (c->radius + f), r_view.up, v); memcpy(&r_state.vertex_array_3d[vert_index], v, sizeof(vec3_t)); vert_index += 3; } glDrawArrays(GL_TRIANGLE_FAN, 0, vert_index / 3); } R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_EnableColorArray(false); R_EnableTexture(&texunit_diffuse, true); R_Color(NULL); }
/** * @brief Draw all translucent bsp surfaces with multitexture enabled and blend enabled */ void R_RenderBlendBspRRefs (void) { assert(r_state.blend_enabled); R_EnableTexture(&texunit_lightmap, true); R_RenderBspRRefs(R_DrawSurfaces, S_BLEND); R_EnableTexture(&texunit_lightmap, false); }
/** * @brief Draws a circle out of lines * @param[in] p The particle definition with origin, radius and color * @sa Draw_Circle */ static void R_DrawPtlCircle (const ptl_t* p) { const float radius = p->size[0]; const float thickness = p->size[1]; R_EnableTexture(&texunit_diffuse, qfalse); R_DrawCircle(radius, p->color, thickness, p->s); R_EnableTexture(&texunit_diffuse, qtrue); }
/** * @brief Draw all simple opaque bsp surfaces with multitexture enabled and light enabled */ void R_RenderOpaqueBspRRefs (void) { R_EnableTexture(&texunit_lightmap, true); R_EnableLighting(r_state.world_program, true); R_EnableWorldLights(); R_RenderBspRRefs(R_DrawSurfaces, S_OPAQUE); R_EnableLighting(nullptr, false); R_EnableGlowMap(nullptr); R_EnableTexture(&texunit_lightmap, false); }
/** * @brief Re-draws the mesh using the stencil test. Meshes with stale lighting * information, or with a lighting point above our view, are not drawn. */ static void R_DrawMeshShadow (entity_t *e, const mAliasMesh_t *mesh) { vec4_t color; const bool oldBlend = r_state.blend_enabled; const bool lighting = r_state.lighting_enabled; r_program_t *program = r_state.active_program; if (!r_stencilshadows->integer) return; if (!r_shadows->value) return; if (r_wire->integer) return; if (e->flags & RF_NO_SHADOW) return; if (e->flags & RF_TRANSLUCENT) return; if (!R_UpdateShadowOrigin(e)) return; if (e->lighting->shadowOrigin[2] > refdef.viewOrigin[2]) return; Vector4Set(color, 0.0, 0.0, 0.0, r_shadows->value * MESH_SHADOW_ALPHA); R_Color(color); R_EnableTexture(&texunit_diffuse, false); R_EnableBlend(true); R_RotateForMeshShadow(e); R_EnableStencilTest(true); if (lighting) R_EnableLighting(NULL, false); glDrawArrays(GL_TRIANGLES, 0, mesh->num_tris * 3); refdef.batchCount++; if (lighting) R_EnableLighting(program, true); R_EnableStencilTest(false); R_RotateForMeshShadow(NULL); R_EnableBlend(oldBlend); R_EnableTexture(&texunit_diffuse, true); R_Color(NULL); }
/* * R_SetDEfaultState * * Sets OpenGL state parameters to appropiate defaults. */ void R_SetDefaultState(void) { int i; r_texunit_t *tex; // setup vertex array pointers glEnableClientState(GL_VERTEX_ARRAY); R_BindDefaultArray(GL_VERTEX_ARRAY); R_EnableColorArray(true); R_BindDefaultArray(GL_COLOR_ARRAY); R_EnableColorArray(false); glEnableClientState(GL_NORMAL_ARRAY); R_BindDefaultArray(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); // setup texture units for (i = 0; i < r_config.max_texunits && i < MAX_GL_TEXUNITS; i++) { tex = &r_state.texunits[i]; tex->texture = GL_TEXTURE0_ARB + i; R_EnableTexture(tex, true); R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY); if (i > 0) // turn them off for now R_EnableTexture(tex, false); } R_SelectTexture(&texunit_diffuse); // alpha test parameters glAlphaFunc(GL_GREATER, 0.25); // stencil test parameters glStencilFunc(GL_GEQUAL, 1, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // fog parameters glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_DENSITY, 0.0); glFogf(GL_FOG_START, FOG_START); glFogf(GL_FOG_END, FOG_END); // alpha blend parameters R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
/* * R_DrawBlendSurfaces_default */ void R_DrawBlendSurfaces_default(const r_bsp_surfaces_t *surfs) { if (!surfs->count) return; if (r_draw_wireframe->value) { // surface outlines R_DrawSurfacesLines_default(surfs); return; } // blend is already enabled when this is called R_EnableTexture(&texunit_lightmap, true); R_DrawSurfaces_default(surfs); R_EnableTexture(&texunit_lightmap, false); }
/* * R_DrawOpaqueSurfaces_default */ void R_DrawOpaqueSurfaces_default(const r_bsp_surfaces_t *surfs) { if (!surfs->count) return; if (r_draw_wireframe->value) { // surface outlines R_DrawSurfacesLines_default(surfs); return; } R_EnableTexture(&texunit_lightmap, true); R_EnableLighting(r_state.world_program, true); R_DrawSurfaces_default(surfs); R_EnableLighting(NULL, false); R_EnableTexture(&texunit_lightmap, false); }
/** * @brief Draw replacement model (e.g. when model wasn't found) * @sa R_DrawNullEntities */ static void R_DrawNullModel (const entity_t* e) { int i; vec3_t points[6]; R_EnableTexture(&texunit_diffuse, false); glPushMatrix(); glMultMatrixf(e->transform.matrix); R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points); VectorSet(points[0], 0, 0, -16); for (i = 0; i <= 4; i++) { points[i + 1][0] = 16 * cos(i * (M_PI / 2)); points[i + 1][1] = 16 * sin(i * (M_PI / 2)); points[i + 1][2] = 0; } glDrawArrays(GL_TRIANGLE_FAN, 0, 6); refdef.batchCount++; VectorSet(points[0], 0, 0, 16); for (i = 4; i >= 0; i--) { points[i + 1][0] = 16 * cos(i * (M_PI / 2)); points[i + 1][1] = 16 * sin(i * (M_PI / 2)); points[i + 1][2] = 0; } glDrawArrays(GL_TRIANGLE_FAN, 0, 6); refdef.batchCount++; R_BindDefaultArray(GL_VERTEX_ARRAY); glPopMatrix(); R_EnableTexture(&texunit_diffuse, true); }
/** * @sa R_DrawParticles */ static void R_DrawPtlLine (const ptl_t * p) { const vec3_t points[] = { { p->s[0], p->s[1], p->s[2] }, { p->v[0], p->v[1], p->v[2] } }; R_EnableTexture(&texunit_diffuse, qfalse); glEnable(GL_LINE_SMOOTH); R_Color(p->color); /* draw line from s to v */ R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points); glDrawArrays(GL_LINE_STRIP, 0, 2); R_BindDefaultArray(GL_VERTEX_ARRAY); refdef.batchCount++; R_Color(NULL); glDisable(GL_LINE_SMOOTH); R_EnableTexture(&texunit_diffuse, qtrue); }
static void R_DrawAliasTags (const mAliasModel_t *mod) { int i; const uint32_t color[] = {0xFF0000FF, 0xFF00FF00, 0xFFFF0000}; glEnable(GL_LINE_SMOOTH); R_EnableTexture(&texunit_diffuse, false); R_EnableColorArray(true); for (i = 0; i < mod->num_tags; i++) { int j; const mAliasTag_t *tag = &mod->tags[i]; for (j = 0; j < 3; j++) { vec3_t out; const mAliasTagOrientation_t *o = &tag->orient[mod->curFrame]; VectorMA(o->origin, 5, o->axis[j], out); const vec3_t points[] = { { o->origin[0], o->origin[1], o->origin[2] }, { out[0], out[1], out[2] } }; GLbyte colorArray[8]; memcpy(&colorArray[0], &color[j], 4); memcpy(&colorArray[4], &color[j], 4); R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, colorArray); R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points); glDrawArrays(GL_LINE_STRIP, 0, 2); refdef.batchCount++; } } /* restore default array bindings */ R_BindDefaultArray(GL_COLOR_ARRAY); R_BindDefaultArray(GL_VERTEX_ARRAY); R_EnableColorArray(false); R_EnableTexture(&texunit_diffuse, true); glDisable(GL_LINE_SMOOTH); }
/** * @brief Gives handle to (and uploads if needed) weather particle texture; also binds it to the active texture unit * @return OpenGL handle of texture object * @note alas, image_t does not support anything but RGB(A) textures, so we've got to reinvent the wheel */ static GLuint wpTexture (void) { static GLuint wpTextureHandle = 0; if (wpTextureHandle) return wpTextureHandle; R_EnableTexture(&texunit_diffuse, true); glGenTextures(1, &wpTextureHandle); glBindTexture(GL_TEXTURE_2D, wpTextureHandle); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 8, 8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, wpImage); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); return wpTextureHandle; }
/** * @brief Draw the day and night images of a flat geoscape * multitexture feature is used to blend the images * @sa R_Draw3DGlobe * @param[in] p The horizontal shift of the night map * @param[in] cx The x texture coordinate * @param[in] cy The y texture coordinate * @param[in] iz The zoomlevel of the geoscape - see ccs.zoom * @param[in] map The geoscape map to draw (can be changed in the campaign definition) * @param[in] overlayNation,overlayXVI,overlayRadar Whether these overlays should be drawn or not */ void R_DrawFlatGeoscape (const vec2_t nodePos, const vec2_t nodeSize, float p, float cx, float cy, float iz, const char *map, bool overlayNation, bool overlayXVI, bool overlayRadar, image_t *r_dayandnightTexture, image_t *r_xviTexture, image_t *r_radarTexture) { image_t *gl; float geoscape_texcoords[4 * 2]; short geoscape_verts[4 * 2]; /* normalize */ const float nx = nodePos[0] * viddef.rx; const float ny = nodePos[1] * viddef.ry; const float nw = nodeSize[0] * viddef.rx; const float nh = nodeSize[1] * viddef.ry; /* load day image */ gl = R_FindImage(va("pics/geoscape/%s_day", map), it_wrappic); if (gl == r_noTexture) Com_Error(ERR_FATAL, "Could not load geoscape day image"); /* alter the array pointers */ glVertexPointer(2, GL_SHORT, 0, geoscape_verts); R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_texcoords); geoscape_texcoords[0] = cx - iz; geoscape_texcoords[1] = cy - iz; geoscape_texcoords[2] = cx + iz; geoscape_texcoords[3] = cy - iz; geoscape_texcoords[4] = cx + iz; geoscape_texcoords[5] = cy + iz; geoscape_texcoords[6] = cx - iz; geoscape_texcoords[7] = cy + iz; geoscape_verts[0] = nx; geoscape_verts[1] = ny; geoscape_verts[2] = nx + nw; geoscape_verts[3] = ny; geoscape_verts[4] = nx + nw; geoscape_verts[5] = ny + nh; geoscape_verts[6] = nx; geoscape_verts[7] = ny + nh; /* draw day image */ R_BindTexture(gl->texnum); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); refdef.batchCount++; /* draw night map */ gl = R_FindImage(va("pics/geoscape/%s_night", map), it_wrappic); /* maybe the campaign map doesn't have a night image */ if (gl != r_noTexture) { float geoscape_nighttexcoords[4 * 2]; R_BindTexture(gl->texnum); R_EnableTexture(&texunit_lightmap, true); R_SelectTexture(&texunit_lightmap); geoscape_nighttexcoords[0] = geoscape_texcoords[0] + p; geoscape_nighttexcoords[1] = geoscape_texcoords[1]; geoscape_nighttexcoords[2] = geoscape_texcoords[2] + p; geoscape_nighttexcoords[3] = geoscape_texcoords[3]; geoscape_nighttexcoords[4] = geoscape_texcoords[4] + p; geoscape_nighttexcoords[5] = geoscape_texcoords[5]; geoscape_nighttexcoords[6] = geoscape_texcoords[6] + p; geoscape_nighttexcoords[7] = geoscape_texcoords[7]; R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_nighttexcoords); R_BindTexture(r_dayandnightTexture->texnum); R_SelectTexture(&texunit_diffuse); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); refdef.batchCount++; R_SelectTexture(&texunit_lightmap); R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_texcoords); R_EnableTexture(&texunit_lightmap, false); } /* draw nation overlay */ if (overlayNation) { gl = R_FindImage(va("pics/geoscape/%s_nations_overlay", map), it_wrappic); if (gl == r_noTexture) Com_Error(ERR_FATAL, "Could not load geoscape nation overlay image"); /* draw day image */ R_BindTexture(gl->texnum); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); refdef.batchCount++; } /* draw XVI image */ if (overlayXVI) { gl = R_FindImage(va("pics/geoscape/%s_xvi_overlay", map), it_wrappic); if (gl == r_noTexture) Com_Error(ERR_FATAL, "Could not load xvi overlay image"); R_BindTexture(gl->texnum); R_EnableTexture(&texunit_lightmap, true); R_BindLightmapTexture(r_xviTexture->texnum); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); refdef.batchCount++; R_EnableTexture(&texunit_lightmap, false); } /* draw radar image */ if (overlayRadar) { R_BindTexture(r_radarTexture->texnum); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); refdef.batchCount++; } /* and restore them */ R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY); R_BindDefaultArray(GL_VERTEX_ARRAY); }
void R_DrawCoronas (void) { int i, j, k; vec3_t v; if (!r_coronas->integer) return; if (!refdef.numCoronas) return; R_EnableTexture(&texunit_diffuse, false); R_EnableColorArray(true); R_ResetArrayState(); R_BlendFunc(GL_ONE, GL_ONE); for (k = 0; k < refdef.numCoronas; k++) { const corona_t *c = &refdef.coronas[k]; int verts, vertind; if (!c->radius) continue; /* use at least 12 verts, more for larger coronas */ verts = 12 + c->radius / 8; memcpy(&r_state.color_array[0], c->color, sizeof(vec3_t)); r_state.color_array[3] = 1.0f; /* set origin color */ /* and the corner colors */ memset(&r_state.color_array[4], 0, verts * 2 * sizeof(vec4_t)); memcpy(&r_state.vertex_array_3d[0], c->org, sizeof(vec3_t)); vertind = 3; /* and the origin */ for (i = verts; i >= 0; i--) { /* now draw the corners */ const float a = (M_PI * 2 / verts) * i; for (j = 0; j < 3; j++) v[j] = c->org[j] + r_locals.right[j] * (float) cos(a) * c->radius + r_locals.up[j] * (float) sin(a) * c->radius; memcpy(&r_state.vertex_array_3d[vertind], v, sizeof(vec3_t)); vertind += 3; } glDrawArrays(GL_TRIANGLE_FAN, 0, vertind / 3); refdef.batchCount++; } R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_EnableColorArray(false); R_EnableTexture(&texunit_diffuse, true); R_Color(nullptr); }
/** * @brief Iterates the specified surfaces list, updating materials as they are * encountered, and rendering all visible stages. State is lazily managed * throughout the iteration, so there is a concerted effort to restore the * state after all surface stages have been rendered. */ void R_DrawMaterialSurfaces (const mBspSurfaces_t *surfs, GLushort *indexPtr) { int i; if (!r_materials->integer || r_wire->integer) return; if (!surfs->count) return; assert(r_state.blend_enabled); /** @todo - integrate BSP lighting with model lighting */ R_EnableModelLights(nullptr, 0, false, false); R_EnableColorArray(true); R_ResetArrayState(); R_EnableColorArray(false); R_EnableLighting(nullptr, false); R_EnableTexture(&texunit_lightmap, false); #ifndef GL_VERSION_ES_CM_1_0 glEnable(GL_POLYGON_OFFSET_FILL); #endif glPolygonOffset(-1.f, -1.f); glMatrixMode(GL_TEXTURE); /* some stages will manipulate texcoords */ for (i = 0; i < surfs->count; i++) { materialStage_t *s; mBspSurface_t *surf = surfs->surfaces[i]; material_t *m = &surf->texinfo->image->material; int j = -1; if (surf->frame != r_locals.frame) continue; R_UpdateMaterial(m); for (s = m->stages; s; s = s->next, j--) { if (!(s->flags & STAGE_RENDER)) continue; R_SetSurfaceStageState(surf, s); R_DrawSurfaceStage(surf, s); } } R_Color(nullptr); /* polygon offset parameters */ glPolygonOffset(0.0, 0.0); #ifndef GL_VERSION_ES_CM_1_0 glDisable(GL_POLYGON_OFFSET_FILL); #endif glLoadIdentity(); glMatrixMode(GL_MODELVIEW); R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_EnableFog(true); R_EnableColorArray(false); R_EnableTexture(&texunit_lightmap, false); R_EnableBumpmap(nullptr); R_EnableLighting(nullptr, false); R_EnableGlowMap(nullptr); R_Color(nullptr); }