void FMD3Model::RenderFrame(FTexture * skin, int frameno, int cm, Matrix3x4 *modeltoworld, int translation) { if (frameno>=numFrames) return; MD3Frame * frame = &frames[frameno]; // I can't confirm correctness of this because no model I have tested uses this information // gl.MatrixMode(GL_MODELVIEW); // gl.Translatef(frame->origin[0], frame->origin[1], frame->origin[2]); for(int i=0;i<numSurfaces;i++) { MD3Surface * surf = &surfaces[i]; // [BB] In case no skin is specified via MODELDEF, check if the MD3 has a skin for the current surface. // Note: Each surface may have a different skin. FTexture *surfaceSkin = skin; if (!surfaceSkin) { if (surf->numSkins==0) return; surfaceSkin = surf->skins[0]; if (!surfaceSkin) return; } FGLTexture * tex = FGLTexture::ValidateTexture(surfaceSkin); tex->Bind(cm, 0, translation); RenderTriangles(surf, surf->vertices + frameno * surf->numVertices, modeltoworld); } }
void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, Matrix3x4 *modeltoworld, int translation) { if (frameno>=numFrames || frameno2>=numFrames) return; for(int i=0;i<numSurfaces;i++) { MD3Surface * surf = &surfaces[i]; // [BB] In case no skin is specified via MODELDEF, check if the MD3 has a skin for the current surface. // Note: Each surface may have a different skin. FTexture *surfaceSkin = skin; if (!surfaceSkin) { if (surf->numSkins==0) return; surfaceSkin = surf->skins[0]; if (!surfaceSkin) return; } FGLTexture * tex = FGLTexture::ValidateTexture(surfaceSkin); tex->Bind(cm, 0, translation); MD3Vertex* verticesInterpolated = new MD3Vertex[surfaces[i].numVertices]; MD3Vertex* vertices1 = surf->vertices + frameno * surf->numVertices; MD3Vertex* vertices2 = surf->vertices + frameno2 * surf->numVertices; // [BB] Calculate the interpolated vertices by linear interpolation. for( int k = 0; k < surf->numVertices; k++ ) { verticesInterpolated[k].x = (1-inter)*vertices1[k].x+ (inter)*vertices2[k].x; verticesInterpolated[k].y = (1-inter)*vertices1[k].y+ (inter)*vertices2[k].y; verticesInterpolated[k].z = (1-inter)*vertices1[k].z+ (inter)*vertices2[k].z; // [BB] Apparently RenderTriangles doesn't use nx, ny, nz, so don't interpolate them. } RenderTriangles(surf, verticesInterpolated, modeltoworld); delete[] verticesInterpolated; } }
//========================================================================== // // // //========================================================================== void gl_DrawTexture(FTexInfo *texInfo) { float x, y, w, h; float ox, oy, cx, cy, r, g, b; float light = 1.f; x = texInfo->x; y = texInfo->y; w = texInfo->width; h = texInfo->height; FGLTexture * gltex = FGLTexture::ValidateTexture(texInfo->tex); const PatchTextureInfo * pti; if (!texInfo->tex->bHasCanvas) { if (!texInfo->loadAlpha) { int translationindex; if (texInfo->tex->UseType == FTexture::TEX_FontChar) { // Try to get the true color mapping from the paletted mapping which is being passed here // // Too bad that there is no decent way to get the index directly so the only way to get it // is to analyze the table's contents. byte * index0 = texInfo->font->GetColorTranslation(CR_BRICK); byte * index1 = texInfo->font->GetColorTranslation(CR_TAN); translationindex = (texInfo->translation - index0) / (index1 - index0); if (translationindex<0 || translationindex>=NUM_TEXT_COLORS) { translationindex=CR_UNTRANSLATED; } // now get the corrseponding True Color table from the font. byte * tctstart = index0 + (NUM_TEXT_COLORS * (index1-index0)); texInfo->translation = tctstart + 3 * (index1-index0) * translationindex; } else { // If ZDoom changes its use of translation tables this has to be adjusted for it // because the texture manager doesn't implement a generic translation table handling. // if (texInfo->translation == DIM_MAP) { // reducing the light produces better results than using a palette-limited translation table. light = .5f; translationindex = 0; } else if (texInfo->translation >= translationtables[TRANSLATION_Players] && texInfo->translation < translationtables[TRANSLATION_Players] + (MAXPLAYERS+1)*256) { // Aside from fonts these are the only ones being used by ZDoom and they are better passed by ID. // int in = texInfo->translation - translationtables[TRANSLATION_Players]; translationindex = TRANSLATION(TRANSLATION_Players, in); } else { translationindex=0; } texInfo->translation=NULL; } pti = gltex->BindPatch(CM_DEFAULT, translationindex, texInfo->translation); } else { // This is an alpha texture pti = gltex->BindPatch(CM_SHADE, 0); } if (!pti) return; cx = pti->GetUR(); cy = pti->GetVB(); } else { gltex->Bind(CM_DEFAULT); cx=1.f; cy=-1.f; } ox = oy = 0.f; if (texInfo->flipX) { float temp = ox; ox = cx; cx = temp; } // also take into account texInfo->windowLeft and texInfo->windowRight // just ignore for now... if (texInfo->windowLeft || texInfo->windowRight != texInfo->tex->GetScaledWidth()) return; if (texInfo->fillColor > 0 || texInfo->RenderStyle == STYLE_Shaded || texInfo->RenderStyle == STYLE_TranslucentStencil || texInfo->RenderStyle == STYLE_Stencil) { r = RPART(texInfo->fillColor)/255.0f; g = GPART(texInfo->fillColor)/255.0f; b = BPART(texInfo->fillColor)/255.0f; } else { r = g = b = light; } // scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates int btm = (SCREENHEIGHT - screen->GetHeight()) / 2; btm = SCREENHEIGHT - btm; gl.Enable(GL_SCISSOR_TEST); int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2; // ugh... gl.Scissor(texInfo->clipLeft, btm - texInfo->clipBottom+space, texInfo->clipRight - texInfo->clipLeft, texInfo->clipBottom - texInfo->clipTop); if (texInfo->RenderStyle == STYLE_TranslucentStencil || texInfo->RenderStyle == STYLE_Stencil) { gl_SetTextureMode(TM_MASK); } else if (!texInfo->masked) { gl_SetTextureMode(TM_OPAQUE); } gl.Color4f(r, g, b, texInfo->alpha); gl.Disable(GL_ALPHA_TEST); gl.Begin(GL_TRIANGLE_STRIP); gl.TexCoord2f(ox, oy); gl.Vertex2i(x, y); gl.TexCoord2f(ox, cy); gl.Vertex2i(x, y + h); gl.TexCoord2f(cx, oy); gl.Vertex2i(x + w, y); gl.TexCoord2f(cx, cy); gl.Vertex2i(x + w, y + h); gl.End(); gl.Enable(GL_ALPHA_TEST); gl.Scissor(0, 0, screen->GetWidth(), screen->GetHeight()); gl.Disable(GL_SCISSOR_TEST); if (!texInfo->masked || texInfo->RenderStyle == STYLE_TranslucentStencil || texInfo->RenderStyle == STYLE_Stencil) { gl_SetTextureMode(TM_MODULATE); } }
//========================================================================== // // Draw the plane segment into the gap // //========================================================================== void GLDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, bool ceiling) { GLSectorPlane plane; int lightlevel; FColormap Colormap; FGLTexture * gltexture; plane.GetFromSector(sec, ceiling); gltexture=FGLTexture::ValidateTexture(plane.texture); if (!gltexture) return; if (gl_fixedcolormap) { Colormap.GetFixedColormap(); lightlevel=255; } else { Colormap=sec->ColorMap; if (gltexture->tex->isFullbright()) { Colormap.LightColor.r = Colormap.LightColor.g = Colormap.LightColor.b = 0xff; lightlevel=255; } else lightlevel=abs(ceiling? GetCeilingLight(sec) : GetFloorLight(sec)); } int rel = extralight * gl_weaponlight; gl_SetColor(lightlevel, rel, &Colormap, 1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); gltexture->Bind(Colormap.LightColor.a); gl_SetPlaneTextureRotation(&plane, gltexture); float fviewx = TO_GL(viewx); float fviewy = TO_GL(viewy); float fviewz = TO_GL(viewz); gl_ApplyShader(); gl.Begin(GL_TRIANGLE_FAN); float prj_fac1 = (planez-fviewz)/(ws->z1-fviewz); float prj_fac2 = (planez-fviewz)/(ws->z2-fviewz); float px1 = fviewx + prj_fac1 * (ws->x1-fviewx); float py1 = fviewy + prj_fac1 * (ws->y1-fviewy); float px2 = fviewx + prj_fac2 * (ws->x1-fviewx); float py2 = fviewy + prj_fac2 * (ws->y1-fviewy); float px3 = fviewx + prj_fac2 * (ws->x2-fviewx); float py3 = fviewy + prj_fac2 * (ws->y2-fviewy); float px4 = fviewx + prj_fac1 * (ws->x2-fviewx); float py4 = fviewy + prj_fac1 * (ws->y2-fviewy); gl.TexCoord2f(px1 / 64, -py1 / 64); gl.Vertex3f(px1, planez, py1); gl.TexCoord2f(px2 / 64, -py2 / 64); gl.Vertex3f(px2, planez, py2); gl.TexCoord2f(px3 / 64, -py3 / 64); gl.Vertex3f(px3, planez, py3); gl.TexCoord2f(px4 / 64, -py4 / 64); gl.Vertex3f(px4, planez, py4); gl.End(); gl.MatrixMode(GL_TEXTURE); gl.PopMatrix(); gl.MatrixMode(GL_MODELVIEW); }