/* Each frame, update warping textures */ void R_UpdateWarpTextures (void) { texture_t *tx; int i; float x, y, x2, warptess; if (r_oldwater.value || cl.bIsPaused || r_drawflat_cheatsafe || r_lightmap_cheatsafe) return; warptess = 128.0f / Math_Clamp(3.0f, floor(r_waterquality.value), 64.0f); for (i=0; i<cl.worldmodel->numtextures; i++) { tx = cl.worldmodel->textures[i]; if(!tx) continue; if(!tx->update_warp) continue; //render warp GL_SetCanvas (CANVAS_WARPIMAGE); Video_SetTexture(tx->gltexture); for (x=0.0; x<128.0; x=x2) { x2 = x + warptess; glBegin (GL_TRIANGLE_STRIP); for (y=0.0; y<128.01; y+=warptess) // .01 for rounding errors { glTexCoord2f (WARPCALC(x,y), WARPCALC(y,x)); glVertex2f (x,y); glTexCoord2f (WARPCALC(x2,y), WARPCALC(y,x2)); glVertex2f (x2,y); } glEnd(); } //copy to texture Video_SetTexture(tx->warpimage); glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly+glheight-gl_warpimagesize, gl_warpimagesize, gl_warpimagesize); tx->update_warp = FALSE; } //if viewsize is less than 100, we need to redraw the frame around the viewport scr_tileclear_updates = 0; }
void Sky_DrawSkyBox (void) { int i; for(i = 0; i < 6; i++) { if (skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]) continue; Video_SetTexture(gSkyBoxTexture[skytexorder[i]]); #if 1 //FIXME: this is to avoid tjunctions until i can do it the right way skymins[0][i] = -1; skymins[1][i] = -1; skymaxs[0][i] = 1; skymaxs[1][i] = 1; #endif glBegin(GL_QUADS); Sky_EmitSkyBoxVertex (skymins[0][i], skymins[1][i], i); Sky_EmitSkyBoxVertex (skymins[0][i], skymaxs[1][i], i); Sky_EmitSkyBoxVertex (skymaxs[0][i], skymaxs[1][i], i); Sky_EmitSkyBoxVertex (skymaxs[0][i], skymins[1][i], i); glEnd(); rs_skypolys++; rs_skypasses++; if (Fog_GetDensity() > 0 && r_skyfog.value > 0) { float *c; c = Fog_GetColor(); VideoLayer_Enable(VIDEO_BLEND); VideoLayer_Disable(VIDEO_TEXTURE_2D); glColor4f(c[0], c[1], c[2], Math_Clamp(0, r_skyfog.value, 1.0f)); glBegin(GL_QUADS); Sky_EmitSkyBoxVertex (skymins[0][i], skymins[1][i], i); Sky_EmitSkyBoxVertex (skymins[0][i], skymaxs[1][i], i); Sky_EmitSkyBoxVertex (skymaxs[0][i], skymaxs[1][i], i); Sky_EmitSkyBoxVertex (skymaxs[0][i], skymins[1][i], i); glEnd(); glColor3f(1.0f,1.0f,1.0f); VideoLayer_Enable(VIDEO_TEXTURE_2D); VideoLayer_Disable(VIDEO_BLEND); rs_skypasses++; } } }
void Sky_DrawFaceQuad(glpoly_t *p) { float s,t, *v; int i; glColor3f(1.0f,1.0f,1.0f); Video_SetTexture(gCloudTexture); VideoLayer_Enable(VIDEO_BLEND); VideoLayer_BlendFunc(VIDEO_BLEND_ONE, VIDEO_BLEND_ONE); glBegin(GL_QUADS); for (i = 0, v = p->verts[0]; i < 4; i++, v += VERTEXSIZE) { Sky_GetTexCoord(v,cv_sky_scrollspeed.value,&s,&t); glTexCoord2f(s,t); glVertex3fv(v); } glEnd(); VideoLayer_BlendFunc(VIDEO_BLEND_DEFAULT); rs_skypolys++; rs_skypasses++; if(Fog_GetDensity() > 0 && r_skyfog.value > 0) { float *c = Fog_GetColor(); VideoLayer_Disable(VIDEO_TEXTURE_2D); glColor4f(c[0], c[1], c[2], Math_Clamp(0.0, r_skyfog.value, 1.0)); glBegin(GL_QUADS); for(i = 0,v = p->verts[0]; i < 4; i++,v += VERTEXSIZE) glVertex3fv(v); glEnd(); glColor3f(1.0f,1.0f,1.0f); VideoLayer_Enable(VIDEO_TEXTURE_2D); rs_skypasses++; } VideoLayer_Disable(VIDEO_BLEND); }
/* Typically called before an object is drawn. */ void Material_Draw(Material_t *Material, int Skin, VideoVertex_t *ObjectVertex, VideoPrimitive_t ObjectPrimitive, unsigned int ObjectSize, bool ispost) { if (r_drawflat_cheatsafe || !Material) return; if ((Material->override_wireframe && (r_showtris.iValue != 1) || !Material->override_wireframe) && (r_lightmap_cheatsafe || r_showtris.bValue)) { if (!ispost) { // Select the first TMU. Video_SelectTexture(0); // Set it as white. Video_SetTexture(g_mGlobalColour->msSkin[MATERIAL_COLOUR_WHITE].mtTexture->gMap); } return; } MaterialSkin_t *msCurrentSkin; if (Material->iFlags & MATERIAL_FLAG_ANIMATED) msCurrentSkin = Material_GetAnimatedSkin(Material); else msCurrentSkin = Material_GetSkin(Material, Skin); if (!msCurrentSkin) Sys_Error("Failed to get valid skin! (%s)\n", Material->cName); // Handle any generic blending. if ((msCurrentSkin->uiFlags & MATERIAL_FLAG_BLEND) || (Material->fAlpha < 1)) { if (!ispost) { vlDepthMask(false); VideoLayer_Enable(VIDEO_BLEND); if (msCurrentSkin->uiFlags & MATERIAL_FLAG_ADDITIVE) // Additive blending isn't done by default. VideoLayer_BlendFunc(VIDEO_BLEND_ADDITIVE); } else { vlDepthMask(true); VideoLayer_Disable(VIDEO_BLEND); if (msCurrentSkin->uiFlags & MATERIAL_FLAG_ADDITIVE) // Return blend mode to its default. VideoLayer_BlendFunc(VIDEO_BLEND_DEFAULT); } } unsigned int i, uiCurrentUnit; for (i = 0, uiCurrentUnit = 0; i < msCurrentSkin->uiTextures; i++, uiCurrentUnit++) { #ifdef VIDEO_LIGHTMAP_HACKS // Skip the lightmap, since it's manually handled. if (uiCurrentUnit == VIDEO_TEXTURE_LIGHT) uiCurrentUnit++; #endif // Attempt to select the unit (if it's already selected, then it'll just return). Video_SelectTexture(uiCurrentUnit); if (!ispost) { // Enable it. VideoLayer_Enable(VIDEO_TEXTURE_2D); // Bind it. Video_SetTexture(msCurrentSkin->mtTexture[i].gMap); // Allow us to manipulate the texture. if (msCurrentSkin->mtTexture[i].matrixmod) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); if ((msCurrentSkin->mtTexture[i].vScroll[0] > 0) || (msCurrentSkin->mtTexture[i].vScroll[0] < 0) || (msCurrentSkin->mtTexture[i].vScroll[1] > 0) || (msCurrentSkin->mtTexture[i].vScroll[1] < 0)) glTranslatef( msCurrentSkin->mtTexture[i].vScroll[0] * cl.time, msCurrentSkin->mtTexture[i].vScroll[1] * cl.time, 0); if ((msCurrentSkin->mtTexture[i].fRotate > 0) || (msCurrentSkin->mtTexture[i].fRotate < 0)) glRotatef(msCurrentSkin->mtTexture[i].fRotate*cl.time, 0, 0, 1.0f); glMatrixMode(GL_MODELVIEW); } } switch (msCurrentSkin->mtTexture[i].mttType) { case MATERIAL_TEXTURE_LIGHTMAP: case MATERIAL_TEXTURE_DIFFUSE: if (!ispost) { #if 0 // TODO: Material shader assignments!!!! VideoShader_SetVariablei(iDiffuseUniform, Video.current_textureunit); #endif if (uiCurrentUnit > 0) { VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_DECAL); // Check if we've been given a video object to use... if (ObjectVertex) { unsigned int j; // Go through the whole object. for (j = 0; j < ObjectSize; j++) { // Copy over original texture coords. Video_ObjectTexture(&ObjectVertex[j], uiCurrentUnit, // Use base texture coordinates as a reference. ObjectVertex[j].mvST[0][0], ObjectVertex[j].mvST[0][1]); } } } else VideoLayer_SetTextureEnvironmentMode(msCurrentSkin->mtTexture[i].EnvironmentMode); if ((msCurrentSkin->mtTexture[i].uiFlags & MATERIAL_FLAG_ALPHA) || (msCurrentSkin->uiFlags & MATERIAL_FLAG_ALPHA)) VideoLayer_Enable(VIDEO_ALPHA_TEST); } else { if ((msCurrentSkin->mtTexture[i].uiFlags & MATERIAL_FLAG_ALPHA) || (msCurrentSkin->uiFlags & MATERIAL_FLAG_ALPHA)) { VideoLayer_Disable(VIDEO_ALPHA_TEST); if ((msCurrentSkin->uiFlags & MATERIAL_FLAG_ALPHATRICK) && (cv_video_alphatrick.bValue && (ObjectSize > 0))) { vlDepthMask(false); VideoLayer_Enable(VIDEO_BLEND); // Draw the object again (don't bother passing material). Video_DrawObject(ObjectVertex, ObjectPrimitive, ObjectSize, NULL, 0); VideoLayer_Disable(VIDEO_BLEND); vlDepthMask(true); } } VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_MODULATE); } break; case MATERIAL_TEXTURE_DETAIL: if (!ispost) { if (!cv_video_drawdetail.bValue) { Video_DisableCapabilities(VIDEO_TEXTURE_2D); break; } VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 2); // Check if we've been given a video object to use... if (ObjectVertex) { unsigned int j; // Go through the whole object. for (j = 0; j < ObjectSize; j++) { // Copy over original texture coords. Video_ObjectTexture(&ObjectVertex[j], uiCurrentUnit, // Use base texture coordinates as a reference. ObjectVertex[j].mvST[0][0] * cv_video_detailscale.value, ObjectVertex[j].mvST[0][1] * cv_video_detailscale.value); // TODO: Modify them to the appropriate scale. } } } else { VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1); } break; case MATERIAL_TEXTURE_FULLBRIGHT: if (!ispost) { if (!gl_fullbrights.bValue) { Video_DisableCapabilities(VIDEO_TEXTURE_2D); break; } VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_ADD); if (uiCurrentUnit > 0) { // Check if we've been given a video object to use... if (ObjectVertex) { unsigned int j; // Go through the whole object. for (j = 0; j < ObjectSize; j++) { // Copy over original texture coords. Video_ObjectTexture(&ObjectVertex[j], uiCurrentUnit, // Use base texture coordinates as a reference. ObjectVertex[j].mvST[0][0], ObjectVertex[j].mvST[0][1]); } } } } else VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_MODULATE); break; case MATERIAL_TEXTURE_SPHERE: if (!ispost) { VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_COMBINE); Video_GenerateSphereCoordinates(); VideoLayer_Enable(VIDEO_TEXTURE_GEN_S | VIDEO_TEXTURE_GEN_T); } else { VideoLayer_SetTextureEnvironmentMode(VIDEO_TEXTURE_MODE_MODULATE); VideoLayer_Disable(VIDEO_TEXTURE_GEN_S | VIDEO_TEXTURE_GEN_T); } break; default: Sys_Error("Invalid texture type for material! (%s) (%i)\n", Material->cPath, msCurrentSkin->mtTexture[i].mttType); } if (ispost) { // Reset any manipulation within the matrix. if (msCurrentSkin->mtTexture[i].matrixmod) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(0, 0, 0); glRotatef(0, 0, 0, 0); glMatrixMode(GL_MODELVIEW); } // Disable the texture. VideoLayer_Disable(VIDEO_TEXTURE_2D); } } }