/* * R_DrawSurfaces_default */ static void R_DrawSurfaces_default(const r_bsp_surfaces_t *surfs) { unsigned int i; R_SetArrayState(r_world_model); // draw the surfaces for (i = 0; i < surfs->count; i++) { if (surfs->surfaces[i]->frame != r_locals.frame) continue; R_SetSurfaceState_default(surfs->surfaces[i]); R_DrawSurface_default(surfs->surfaces[i]); } // reset state if (r_state.lighting_enabled) { if (r_state.bumpmap_enabled) R_EnableBumpmap(NULL, false); R_EnableLights(0); } glColor4ubv(color_white); }
/* * R_SetSurfaceState_default */ static void R_SetSurfaceState_default(const r_bsp_surface_t *surf) { r_image_t *image; float a; if (r_state.blend_enabled) { // alpha blend switch (surf->texinfo->flags & (SURF_BLEND_33 | SURF_BLEND_66)) { case SURF_BLEND_33: a = 0.33; break; case SURF_BLEND_66: a = 0.66; break; default: // both flags mean use the texture's alpha channel a = 1.0; break; } glColor4f(1.0, 1.0, 1.0, a); } image = surf->texinfo->image; if (texunit_diffuse.enabled) // diffuse texture R_BindTexture(image->texnum); if (texunit_lightmap.enabled) // lightmap texture R_BindLightmapTexture(surf->lightmap_texnum); if (r_state.lighting_enabled) { // hardware lighting if (r_bumpmap->value) { // bump mapping if (image->normalmap) { R_BindDeluxemapTexture(surf->deluxemap_texnum); R_BindNormalmapTexture(image->normalmap->texnum); R_EnableBumpmap(&image->material, true); } else R_EnableBumpmap(NULL, false); } if (surf->light_frame == r_locals.light_frame) // dynamic light sources R_EnableLights(surf->lights); else R_EnableLights(0); } }
void R_SetSurfaceBumpMappingParameters (const mBspSurface_t *surf, const image_t *normalMap, const image_t *specularMap) { if (!r_state.lighting_enabled) return; if (!r_bumpmap->value) return; assert(surf); if (normalMap && (surf->flags & MSURF_LIGHTMAP)) { const image_t *image = surf->texinfo->image; R_BindDeluxemapTexture(surf->deluxemap_texnum); R_EnableBumpmap(normalMap); R_EnableSpecularMap(specularMap, true); R_UseMaterial(&image->material); } else { R_EnableBumpmap(NULL); R_EnableSpecularMap(NULL, false); R_UseMaterial(NULL); } }
/** * @brief General surface drawing function, that draw the surface chains * @note The needed states for the surfaces must be set before you call this * @sa R_DrawSurface * @sa R_SetSurfaceState */ void R_DrawSurfaces (const mBspSurfaces_t *surfs) { int numSurfaces = surfs->count; mBspSurface_t **surfPtrList = surfs->surfaces; const int frame = r_locals.frame; int lastLightMap = 0, lastDeluxeMap = 0; image_t *lastTexture = NULL; uint32_t lastFlags = ~0; while (numSurfaces--) { const mBspSurface_t *surf = *surfPtrList++; mBspTexInfo_t *texInfo; int texFlags; if (surf->frame != frame) continue; /** @todo integrate it better with R_SetSurfaceState - maybe cache somewhere in the mBspSurface_t ? */ texInfo = surf->texinfo; texFlags = texInfo->flags & (SURF_BLEND33 | SURF_BLEND66 | MSURF_LIGHTMAP); /* should match flags that affect R_SetSurfaceState behavior */ if (texInfo->image != lastTexture || surf->lightmap_texnum != lastLightMap || surf->deluxemap_texnum != lastDeluxeMap || texFlags != lastFlags) { lastTexture = texInfo->image; lastLightMap = surf->lightmap_texnum; lastDeluxeMap = surf->deluxemap_texnum; lastFlags = texFlags; R_SetSurfaceState(surf); } R_DrawSurface(surf); } /* reset state */ if (r_state.active_normalmap) R_EnableBumpmap(NULL); R_EnableGlowMap(NULL); R_Color(NULL); }
/** * @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); }
/** * @brief Draw a model from the battlescape entity list * @sa R_GetEntityLists */ void R_DrawAliasModel (entity_t *e) { mAliasModel_t *mod = &e->model->alias; /* the values are sane here already - see R_GetEntityLists */ const image_t *skin = mod->meshes[e->as.mesh].skins[e->skinnum].skin; int i; float g; vec4_t color = {0.8, 0.8, 0.8, 1.0}; mAliasMesh_t *mesh; /* IR goggles override color for entities that are affected */ if ((refdef.rendererFlags & RDF_IRGOGGLES) && (e->flags & RF_IRGOGGLES)) Vector4Set(e->shell, 1.0, 0.3, 0.3, 1.0); if (e->flags & RF_PULSE) { /* and then adding in a pulse */ const float f = 1.0 + sin((refdef.time + (e->model->alias.meshes[0].num_tris)) * 6.0) * 0.33; VectorScale(color, 1.0 + f, color); } g = 0.0; /* find brightest component */ for (i = 0; i < 3; i++) { if (color[i] > g) /* keep it */ g = color[i]; } /* scale it back to 1.0 */ if (g > 1.0) VectorScale(color, 1.0 / g, color); R_Color(color); assert(skin->texnum > 0); R_BindTexture(skin->texnum); R_EnableGlowMap(skin->glowmap); R_UpdateLightList(e); R_EnableModelLights(e->lights, e->numLights, e->inShadow, true); /** @todo this breaks the encapsulation - don't call CL_* functions from within the renderer code */ if (r_debug_lights->integer) { for (i = 0; i < e->numLights && i < r_dynamic_lights->integer; i++) CL_ParticleSpawn("lightTracerDebug", 0, e->transform.matrix + 12, e->lights[i]->origin); } if (skin->normalmap) R_EnableBumpmap(skin->normalmap); if (skin->specularmap) R_EnableSpecularMap(skin->specularmap, true); if (skin->roughnessmap) R_EnableRoughnessMap(skin->roughnessmap, true); glPushMatrix(); glMultMatrixf(e->transform.matrix); if (VectorNotEmpty(e->scale)) glScalef(e->scale[0], e->scale[1], e->scale[2]); mesh = R_DrawAliasModelBuffer(e); if (r_state.specularmap_enabled) R_EnableSpecularMap(NULL, false); if (r_state.roughnessmap_enabled) R_EnableRoughnessMap(NULL, false); R_EnableModelLights(NULL, 0, false, false); R_EnableGlowMap(NULL); if (r_state.active_normalmap) R_EnableBumpmap(NULL); R_DrawMeshShadow(e, mesh); if (mod->num_frames == 1) R_ResetArraysAfterStaticMeshRender(); glPopMatrix(); /* show model bounding box */ if (r_showbox->integer) R_DrawBoundingBox(mod->frames[e->as.frame].mins, mod->frames[e->as.frame].maxs); R_Color(NULL); }