void GLWall::RenderTextured(int rflags) { int tmode = gl_RenderState.GetTextureMode(); int rel = rellight + getExtraLight(); if (flags & GLWF_GLOW) { gl_RenderState.EnableGlow(true); gl_RenderState.SetGlowPlanes(topplane, bottomplane); gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); } gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false); if (type == RENDERWALL_M2SNF) { if (flags & GLT_CLAMPY) { if (tmode == TM_MODULATE) gl_RenderState.SetTextureMode(TM_CLAMPY); } gl_SetFog(255, 0, NULL, false); } float absalpha = fabsf(alpha); if (lightlist == NULL) { gl_SetColor(lightlevel, rel, Colormap, absalpha); if (type != RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, RenderStyle == STYLE_Add); RenderWall(rflags); } else { gl_RenderState.EnableSplit(true); for (unsigned i = 0; i < lightlist->Size(); i++) { secplane_t &lowplane = i == (*lightlist).Size() - 1 ? bottomplane : (*lightlist)[i + 1].plane; // this must use the exact same calculation method as GLWall::Process etc. float low1 = lowplane.ZatPoint(vertexes[0]); float low2 = lowplane.ZatPoint(vertexes[1]); if (low1 < ztop[0] || low2 < ztop[1]) { int thisll = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel; FColormap thiscm; thiscm.FadeColor = Colormap.FadeColor; thiscm.CopyFrom3DLight(&(*lightlist)[i]); gl_SetColor(thisll, rel, thiscm, absalpha); if (type != RENDERWALL_M2SNF) gl_SetFog(thisll, rel, &thiscm, RenderStyle == STYLE_Add); gl_RenderState.SetSplitPlanes((*lightlist)[i].plane, lowplane); RenderWall(rflags); } if (low1 <= zbottom[0] && low2 <= zbottom[1]) break; } gl_RenderState.EnableSplit(false); } gl_RenderState.SetTextureMode(tmode); gl_RenderState.EnableGlow(false); }
void GLWall::RenderFogBoundary() { if (gl_fogmode && mDrawer->FixedColormap == 0) { if (!gl.legacyMode) { int rel = rellight + getExtraLight(); mDrawer->SetFog(lightlevel, rel, &Colormap, false); gl_RenderState.EnableDrawBuffers(1); gl_RenderState.SetEffect(EFF_FOGBOUNDARY); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); RenderWall(RWF_BLANK); glPolygonOffset(0.0f, 0.0f); glDisable(GL_POLYGON_OFFSET_FILL); gl_RenderState.SetEffect(EFF_NONE); gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount()); } else { RenderFogBoundaryCompat(); } } }
//========================================================================== // // // //========================================================================== void GLWall::RenderMirrorSurface() { if (GLRenderer->mirrortexture == NULL) return; // For the sphere map effect we need a normal of the mirror surface, FVector3 v = glseg.Normal(); if (!gl.legacyMode) { // we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is. tcs[LOLFT].u = tcs[LORGT].u = tcs[UPLFT].u = tcs[UPRGT].u = v.X; tcs[LOLFT].v = tcs[LORGT].v = tcs[UPLFT].v = tcs[UPRGT].v = v.Z; gl_RenderState.EnableTextureMatrix(true); gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix); } else { glNormal3fv(&v[0]); } // Use sphere mapping for this gl_RenderState.SetEffect(EFF_SPHEREMAP); mDrawer->SetColor(lightlevel, 0, Colormap ,0.1f); mDrawer->SetFog(lightlevel, 0, &Colormap, true); gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); gl_RenderState.AlphaFunc(GL_GREATER,0); glDepthFunc(GL_LEQUAL); FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture, false); gl_RenderState.SetMaterial(pat, CLAMP_NONE, 0, -1, false); flags &= ~GLWF_GLOW; RenderWall(RWF_BLANK); gl_RenderState.EnableTextureMatrix(false); gl_RenderState.SetEffect(EFF_NONE); // Restore the defaults for the translucent pass gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); glDepthFunc(GL_LESS); // This is drawn in the translucent pass which is done after the decal pass // As a result the decals have to be drawn here. if (seg->sidedef->AttachedDecals) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); glDepthMask(false); DoDrawDecals(); glDepthMask(true); glPolygonOffset(0.0f, 0.0f); glDisable(GL_POLYGON_OFFSET_FILL); gl_RenderState.SetTextureMode(TM_MODULATE); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } }
void GLWall::RenderTranslucentWall() { bool transparent = gltexture? gltexture->GetTransparent() : false; // currently the only modes possible are solid, additive or translucent // and until that changes I won't fix this code for the new blending modes! bool isadditive = RenderStyle == STYLE_Add; if (gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_BUFFER_STORAGE)) { SetupLights(); } if (!transparent) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); int extra; if (gltexture) { gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false); extra = getExtraLight(); } else { gl_RenderState.EnableTexture(false); extra = 0; } int tmode = gl_RenderState.GetTextureMode(); gl_SetColor(lightlevel, extra, Colormap, fabsf(alpha)); if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive); else { if (flags & GLT_CLAMPY) { if (tmode == TM_MODULATE) gl_RenderState.SetTextureMode(TM_CLAMPY); } gl_SetFog(255, 0, NULL, false); } RenderWall(RWF_TEXTURED|RWF_NOSPLIT); // restore default settings if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (!gltexture) { gl_RenderState.EnableTexture(true); } gl_RenderState.EnableGlow(false); gl_RenderState.SetTextureMode(tmode); }
void GLWall::RenderFogBoundary() { if (gl_fogmode && gl_fixedcolormap == 0) { int rel = rellight + getExtraLight(); gl_SetFog(lightlevel, rel, &Colormap, false); gl_RenderState.SetEffect(EFF_FOGBOUNDARY); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); RenderWall(RWF_BLANK); glPolygonOffset(0.0f, 0.0f); glDisable(GL_POLYGON_OFFSET_FILL); gl_RenderState.SetEffect(EFF_NONE); } }
//========================================================================== // // // //========================================================================== void GLWall::Draw(int pass) { gl_RenderState.SetNormal(glseg.Normal()); switch (pass) { case GLPASS_LIGHTSONLY: SetupLights(); break; case GLPASS_ALL: SetupLights(); // fall through case GLPASS_PLAIN: RenderTextured(RWF_TEXTURED); break; case GLPASS_TRANSLUCENT: switch (type) { case RENDERWALL_MIRRORSURFACE: RenderMirrorSurface(); break; case RENDERWALL_FOGBOUNDARY: RenderFogBoundary(); break; default: RenderTranslucentWall(); break; } break; case GLPASS_LIGHTTEX: case GLPASS_LIGHTTEX_ADDITIVE: case GLPASS_LIGHTTEX_FOGGY: RenderLightsCompat(pass); break; case GLPASS_TEXONLY: gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false); RenderWall(RWF_TEXTURED); break; } }
void GLWall::RenderTranslucentWall() { if (gltexture) { if (mDrawer->FixedColormap == CM_DEFAULT && gl_lights && gl.lightmethod == LM_DIRECT) { SetupLights(); } if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); RenderTextured(RWF_TEXTURED | RWF_NOSPLIT); if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); mDrawer->SetColor(lightlevel, 0, Colormap, fabsf(alpha)); mDrawer->SetFog(lightlevel, 0, &Colormap, RenderStyle == STYLE_Add); gl_RenderState.EnableTexture(false); RenderWall(RWF_NOSPLIT); gl_RenderState.EnableTexture(true); } }
void RenderFace (tFaceProps *propsP) { tFaceProps props = *propsP; CBitmap *bmBot = NULL; CBitmap *bmTop = NULL; int i, bIsMonitor, bIsTeleCam, bHaveMonitorBg, nCamNum, bCamBufAvail; g3sPoint *pointList [8], **pp; CSegment *segP = SEGMENTS + props.segNum; CSide *sideP = segP->m_sides + props.sideNum; CCamera *cameraP = NULL; if (props.nBaseTex < 0) return; if (gameStates.render.nShadowPass == 2) { #if DBG_SHADOWS if (!bWallShadows) return; #endif G3SetCullAndStencil (0, 0); RenderFaceShadow (propsP); G3SetCullAndStencil (1, 0); RenderFaceShadow (propsP); return; } #if DBG //convenient place for a debug breakpoint if (props.segNum == nDbgSeg && ((nDbgSide < 0) || (props.sideNum == nDbgSide))) props.segNum = props.segNum; if (props.nBaseTex == nDbgBaseTex) props.segNum = props.segNum; if (props.nOvlTex == nDbgOvlTex) props.segNum = props.segNum; # if 0 else return; # endif #endif gameData.render.vertexList = gameData.segs.fVertices.Buffer (); Assert(props.nVertices <= 4); for (i = 0, pp = pointList; i < props.nVertices; i++, pp++) *pp = gameData.segs.points + props.vp [i]; if (!(gameOpts->render.debug.bTextures || IsMultiGame)) goto drawWireFrame; #if 1 if (gameStates.render.nShadowBlurPass == 1) { G3DrawWhitePoly (props.nVertices, pointList); gameData.render.vertexList = NULL; return; } #endif SetVertexColors (&props); if (gameStates.render.nType == 2) { #if DBG //convenient place for a debug breakpoint if (props.segNum == nDbgSeg && ((nDbgSide < 0) || (props.sideNum == nDbgSide))) props.segNum = props.segNum; #endif RenderColoredSegFace (props.segNum, props.sideNum, props.nVertices, pointList); gameData.render.vertexList = NULL; return; } nCamNum = IsMonitorFace (props.segNum, props.sideNum, 0); if ((bIsMonitor = gameStates.render.bUseCameras && (nCamNum >= 0))) { cameraP = cameraManager.Camera (nCamNum); cameraP->SetVisible (1); bIsTeleCam = cameraP->GetTeleport (); #if RENDER2TEXTURE bCamBufAvail = cameraP->HaveBuffer (1) == 1; #else bCamBufAvail = 0; #endif bHaveMonitorBg = cameraP->Valid () && /*!cameraP->bShadowMap &&*/ (cameraP->HaveTexture () || bCamBufAvail) && (!bIsTeleCam || EGI_FLAG (bTeleporterCams, 0, 1, 0)); } else bIsTeleCam = bHaveMonitorBg = bCamBufAvail = 0; if (RenderWall (&props, pointList, bIsMonitor)) { //handle semi-transparent walls gameData.render.vertexList = NULL; return; } if (props.widFlags & WID_RENDER_FLAG) { if (props.nBaseTex >= gameData.pig.tex.nTextures [gameStates.app.bD1Data]) { sideP->m_nBaseTex = 0; } if (!(bHaveMonitorBg && gameOpts->render.cameras.bFitToWall)) { if (gameStates.render.nType == 3) { bmBot = bmpCorona; bmTop = NULL; props.uvls [0].u = props.uvls [0].v = props.uvls [1].v = props.uvls [3].u = I2X (1) / 4; props.uvls [1].u = props.uvls [2].u = props.uvls [2].v = props.uvls [3].v = I2X (3) / 4; } else if (gameOpts->ogl.bGlTexMerge) { bmBot = LoadFaceBitmap (props.nBaseTex, sideP->m_nFrame); if (props.nOvlTex) bmTop = LoadFaceBitmap ((short) (props.nOvlTex), sideP->m_nFrame); } else { if (props.nOvlTex != 0) { bmBot = TexMergeGetCachedBitmap (props.nBaseTex, props.nOvlTex, props.nOvlOrient); #if DBG if (!bmBot) bmBot = TexMergeGetCachedBitmap (props.nBaseTex, props.nOvlTex, props.nOvlOrient); #endif } else { bmBot = gameData.pig.tex.bitmapP + gameData.pig.tex.bmIndexP [props.nBaseTex].index; LoadBitmap (gameData.pig.tex.bmIndexP [props.nBaseTex].index, gameStates.app.bD1Mission); } } } if (bHaveMonitorBg) { cameraP->GetUVL (NULL, props.uvls, NULL, NULL); if (bIsTeleCam) { #if DBG bmBot = &cameraP->Texture (); gameStates.render.grAlpha = 1.0f; #else bmTop = &cameraP->Texture (); gameStates.render.grAlpha = 0.7f; #endif } else if (gameOpts->render.cameras.bFitToWall || (props.nOvlTex > 0)) bmBot = &cameraP->Texture (); else bmTop = &cameraP->Texture (); } SetFaceLight (&props); #if DBG //convenient place for a debug breakpoint if (props.segNum == nDbgSeg && props.sideNum == nDbgSide) props.segNum = props.segNum; #endif #if DBG if (bmTop) fpDrawTexPolyMulti ( props.nVertices, pointList, props.uvls, # if LIGHTMAPS props.uvl_lMaps, # endif bmBot, bmTop, # if LIGHTMAPS NULL, //lightmaps + props.segNum * 6 + props.sideNum, # endif &props.vNormal, props.nOvlOrient, !bIsMonitor || bIsTeleCam, props.segNum); else # if LIGHTMAPS == 0 G3DrawTexPoly (props.nVertices, pointList, props.uvls, bmBot, &props.vNormal, !bIsMonitor || bIsTeleCam, props.segNum); # else fpDrawTexPolyMulti ( props.nVertices, pointList, props.uvls, props.uvl_lMaps, bmBot, NULL, NULL, //lightmaps + props.segNum * 6 + props.sideNum, &props.vNormal, 0, !bIsMonitor || bIsTeleCam, props.segNum); # endif #else fpDrawTexPolyMulti ( props.nVertices, pointList, props.uvls, # if LIGHTMAPS props.uvl_lMaps, # endif bmBot, bmTop, # if LIGHTMAPS NULL, //lightmaps + props.segNum * 6 + props.sideNum, # endif &props.vNormal, props.nOvlOrient, !bIsMonitor || bIsTeleCam, props.segNum); #endif } gameStates.render.grAlpha = 1.0f; gameStates.ogl.fAlpha = 1; // render the CSegment the CPlayerData is in with a transparent color if it is a water or lava CSegment //if (nSegment == OBJECTS->nSegment) #if DBG if (bOutLineMode) DrawOutline (props.nVertices, pointList); #endif drawWireFrame: if (gameOpts->render.debug.bWireFrame && !IsMultiGame) DrawOutline (props.nVertices, pointList); }
//========================================================================== // // // //========================================================================== void GLWall::Draw(int pass) { int rel; int tmode; #ifdef _DEBUG if (seg->linedef-lines==879) { int a = 0; } #endif switch (pass) { case GLPASS_LIGHTSONLY: SetupLights(); break; case GLPASS_ALL: SetupLights(); // fall through case GLPASS_PLAIN: rel = rellight + getExtraLight(); gl_SetColor(lightlevel, rel, Colormap,1.0f); tmode = gl_RenderState.GetTextureMode(); if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false); else { if (flags & GLT_CLAMPY) { if (tmode == TM_MODULATE) gl_RenderState.SetTextureMode(TM_CLAMPY); } gl_SetFog(255, 0, NULL, false); } gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); gl_RenderState.SetMaterial(gltexture, flags & 3, false, -1, false); RenderWall(RWF_TEXTURED|RWF_GLOW); gl_RenderState.EnableGlow(false); gl_RenderState.SetTextureMode(tmode); break; case GLPASS_TRANSLUCENT: switch (type) { case RENDERWALL_MIRRORSURFACE: RenderMirrorSurface(); break; case RENDERWALL_FOGBOUNDARY: RenderFogBoundary(); break; case RENDERWALL_COLORLAYER: glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); RenderTranslucentWall(); glDisable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0, 0); default: RenderTranslucentWall(); break; } } }