void GLWall::RenderWall(int textured, unsigned int *store) { static texcoord tcs[4]; // making this variable static saves us a relatively costly stack integrity check. bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); tcs[0]=lolft; tcs[1]=uplft; tcs[2]=uprgt; tcs[3]=lorgt; if ((flags&GLWF_GLOW) && (textured & RWF_GLOW)) { gl_RenderState.SetGlowPlanes(topplane, bottomplane); gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); } if (!(textured & RWF_NORENDER)) { gl_RenderState.Apply(); gl_RenderState.ApplyLightIndex(dynlightindex); } // the rest of the code is identical for textured rendering and lights FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); unsigned int count, offset; ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v); ptr++; if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr); ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v); ptr++; if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr); ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v); ptr++; if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr); ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v); ptr++; if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); count = GLRenderer->mVBO->GetCount(ptr, &offset); if (!(textured & RWF_NORENDER)) { GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, offset, count); vertexcount += count; } if (store != NULL) { store[0] = offset; store[1] = count; } }
void GLWall::MakeVertices(bool nosplit) { if (vertcount == 0) { bool split = (gl_seamless && !nosplit && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); ptr++; if (split && glseg.fracleft == 0) SplitLeftEdge(ptr); ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); ptr++; if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(ptr); ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v); ptr++; if (split && glseg.fracright == 1) SplitRightEdge(ptr); ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); ptr++; if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(ptr); vertcount = GLRenderer->mVBO->GetCount(ptr, &vertindex); } }
void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) { texcoord tcs[4]; bool glowing; bool split = (gl_seamless && !(textured&4) && !seg->bPolySeg); if (!light) { tcs[0]=lolft; tcs[1]=uplft; tcs[2]=uprgt; tcs[3]=lorgt; glowing = !!(flags&GLWF_GLOW) && (textured & 2); } else { if (!PrepareLight(tcs, light)) return; glowing = false; } if (glowing) gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); gl_RenderState.Apply(!!(flags & GLWF_NOSHADER)); // the rest of the code is identical for textured rendering and lights gl.Begin(GL_TRIANGLE_FAN); // lower left corner if (glowing) gl.VertexAttrib2f(VATTR_GLOWDISTANCE, zceil[0] - zbottom[0], zbottom[0] - zfloor[0]); if (textured&1) gl.TexCoord2f(tcs[0].u,tcs[0].v); gl.Vertex3f(glseg.x1,zbottom[0],glseg.y1); if (split && glseg.fracleft==0) SplitLeftEdge(tcs, glowing); // upper left corner if (glowing) gl.VertexAttrib2f(VATTR_GLOWDISTANCE, zceil[0] - ztop[0], ztop[0] - zfloor[0]); if (textured&1) gl.TexCoord2f(tcs[1].u,tcs[1].v); gl.Vertex3f(glseg.x1,ztop[0],glseg.y1); if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, glowing); // color for right side if (color2) gl.Color4fv(color2); // upper right corner if (glowing) gl.VertexAttrib2f(VATTR_GLOWDISTANCE, zceil[1] - ztop[1], ztop[1] - zfloor[1]); if (textured&1) gl.TexCoord2f(tcs[2].u,tcs[2].v); gl.Vertex3f(glseg.x2,ztop[1],glseg.y2); if (split && glseg.fracright==1) SplitRightEdge(tcs, glowing); // lower right corner if (glowing) gl.VertexAttrib2f(VATTR_GLOWDISTANCE, zceil[1] - zbottom[1], zbottom[1] - zfloor[1]); if (textured&1) gl.TexCoord2f(tcs[3].u,tcs[3].v); gl.Vertex3f(glseg.x2,zbottom[1],glseg.y2); if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, glowing); gl.End(); vertexcount+=4; }
void GLWall::RenderWall(int textured) { gl_RenderState.Apply(); gl_RenderState.ApplyLightIndex(dynlightindex); #ifdef NO_VBO bool nosplit = !!(textured&RWF_NOSPLIT); bool split = (gl_seamless && !nosplit && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); #if 1 // A bit quicker due to batching, still not very fast.. glBegin(GL_TRIANGLE_FAN); // lower left corner if (textured&1) glTexCoord2f(tcs[0].u,tcs[0].v); glVertex3f(glseg.x1,zbottom[0],glseg.y1); //if (split && glseg.fracleft==0) SplitLeftEdge(tcs); // upper left corner if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v); glVertex3f(glseg.x1,ztop[0],glseg.y1); //if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs); // color for right side //if (color2) glColor4fv(color2); // upper right corner if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v); glVertex3f(glseg.x2,ztop[1],glseg.y2); //if (split && glseg.fracright==1) SplitRightEdge(tcs); // lower right corner if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v); glVertex3f(glseg.x2,zbottom[1],glseg.y2); //if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs); glEnd(); vertexcount+=4; #else static FFlatVertex vtx[100]; // Yes this is static. It's only used once, and I think it's faster as the address doesn't keep changing FFlatVertex *ptr = &vtx[0]; ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); ptr++; if (split && glseg.fracleft == 0) SplitLeftEdge(ptr); ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); ptr++; if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(ptr); ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v); ptr++; if (split && glseg.fracright == 1) SplitRightEdge(ptr); ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); ptr++; if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(ptr); // We can workout how many from the difference in pointers vertcount = (ptr - &vtx[0]); glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex),&vtx[0].u); glVertexPointer (3,GL_FLOAT, sizeof(FFlatVertex),&vtx[0].x); glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState (GL_TEXTURE_COORD_ARRAY); glDisableClientState (GL_COLOR_ARRAY); glBindBuffer (GL_ARRAY_BUFFER, 0); // NO VBO glDrawArrays (GL_TRIANGLE_FAN, 0, vertcount); vertexcount += vertcount; #endif #else if (gl.buffermethod != BM_DEFERRED) { MakeVertices(!!(textured&RWF_NOSPLIT)); } else if (vertcount == 0) { // This should never happen but in case it actually does, use the quad drawer as fallback (without edge splitting.) // This way it at least gets drawn. FQuadDrawer qd; qd.Set(0, glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); qd.Set(1, glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); qd.Set(2, glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v); qd.Set(3, glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); qd.Render(GL_TRIANGLE_FAN); vertexcount += 4; return; } GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, vertindex, vertcount); vertexcount += vertcount; #endif }