void FGLRenderer::DrawTexture(FTexture *img, DrawParms &parms) { double xscale = parms.destwidth / parms.texwidth; double yscale = parms.destheight / parms.texheight; double x = parms.x - parms.left * xscale; double y = parms.y - parms.top * yscale; double w = parms.destwidth; double h = parms.destheight; float u1, v1, u2, v2; int light = 255; FMaterial * gltex = FMaterial::ValidateTexture(img, false); if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0) { // Right now there's only black. Should be implemented properly later light = 255 - APART(parms.colorOverlay); parms.colorOverlay = 0; } gl_SetRenderStyle(parms.style, !parms.masked, false); if (!img->bHasCanvas) { int translation = 0; if (!parms.alphaChannel) { if (parms.remap != NULL && !parms.remap->Inactive) { GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative()); if (pal) translation = -pal->GetIndex(); } } gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, -1, !!(parms.style.Flags & STYLEF_RedIsAlpha)); u1 = gltex->GetUL(); v1 = gltex->GetVT(); u2 = gltex->GetUR(); v2 = gltex->GetVB(); } else { gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, 0, -1, false); u1 = 0.f; v1 = 1.f; u2 = 1.f; v2 = 0.f; gl_RenderState.SetTextureMode(TM_OPAQUE); } if (parms.flipX) { float temp = u1; u1 = u2; u2 = temp; } if (parms.windowleft > 0 || parms.windowright < parms.texwidth) { double wi = MIN(parms.windowright, parms.texwidth); x += parms.windowleft * xscale; w -= (parms.texwidth - wi + parms.windowleft) * xscale; u1 = float(u1 + parms.windowleft / parms.texwidth); u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth); } PalEntry color; if (parms.style.Flags & STYLEF_ColorIsFixed) { color = parms.fillcolor; } else { color = PalEntry(light, light, light); } color.a = (BYTE)(parms.Alpha * 255); // 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; glEnable(GL_SCISSOR_TEST); int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2; glScissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip); gl_RenderState.SetColor(color); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.Apply(); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); ptr->Set(x, y, 0, u1, v1); ptr++; ptr->Set(x, y + h, 0, u1, v2); ptr++; ptr->Set(x + w, y, 0, u2, v1); ptr++; ptr->Set(x + w, y + h, 0, u2, v2); ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); if (parms.colorOverlay) { gl_RenderState.SetTextureMode(TM_MASK); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.SetColor(PalEntry(parms.colorOverlay)); gl_RenderState.Apply(); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); ptr->Set(x, y, 0, u1, v1); ptr++; ptr->Set(x, y + h, 0, u1, v2); ptr++; ptr->Set(x + w, y, 0, u2, v1); ptr++; ptr->Set(x + w, y + h, 0, u2, v2); ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } glScissor(0, 0, screen->GetWidth(), screen->GetHeight()); glDisable(GL_SCISSOR_TEST); gl_RenderState.SetTextureMode(TM_MODULATE); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendEquation(GL_FUNC_ADD); }
void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) { double xscale = parms.destwidth / parms.texwidth; double yscale = parms.destheight / parms.texheight; double x = parms.x - parms.left * xscale; double y = parms.y - parms.top * yscale; double w = parms.destwidth; double h = parms.destheight; float u1, v1, u2, v2, r, g, b; float light = 1.f; FMaterial * gltex = FMaterial::ValidateTexture(img); if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0) { // Right now there's only black. Should be implemented properly later light = 1.f - APART(parms.colorOverlay)/255.f; parms.colorOverlay = 0; } if (!img->bHasCanvas) { if (!parms.alphaChannel) { int translation = 0; if (parms.remap != NULL && !parms.remap->Inactive) { GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative()); if (pal) translation = -pal->GetIndex(); } gltex->BindPatch(CM_DEFAULT, translation); } else { // This is an alpha texture gltex->BindPatch(CM_SHADE, 0); } u1 = gltex->GetUL(); v1 = gltex->GetVT(); u2 = gltex->GetUR(); v2 = gltex->GetVB(); } else { gltex->Bind(CM_DEFAULT, 0, 0); u2=1.f; v2=-1.f; u1 = v1 = 0.f; gl_RenderState.SetTextureMode(TM_OPAQUE); } if (parms.flipX) { float temp = u1; u1 = u2; u2 = temp; } if (parms.windowleft > 0 || parms.windowright < parms.texwidth) { x += parms.windowleft * xscale; w -= (parms.texwidth - parms.windowright + parms.windowleft) * xscale; u1 = float(u1 + parms.windowleft / parms.texwidth); u2 = float(u2 - (parms.texwidth - parms.windowright) / parms.texwidth); } if (parms.style.Flags & STYLEF_ColorIsFixed) { r = RPART(parms.fillcolor)/255.0f; g = GPART(parms.fillcolor)/255.0f; b = BPART(parms.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; glEnable(GL_SCISSOR_TEST); int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2; glScissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip); gl_SetRenderStyle(parms.style, !parms.masked, false); if (img->bHasCanvas) { gl_RenderState.SetTextureMode(TM_OPAQUE); } glColor4f(r, g, b, FIXED2FLOAT(parms.alpha)); gl_RenderState.EnableAlphaTest(false); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(u1, v1); glVertex2d(x, y); glTexCoord2f(u1, v2); glVertex2d(x, y + h); glTexCoord2f(u2, v1); glVertex2d(x + w, y); glTexCoord2f(u2, v2); glVertex2d(x + w, y + h); glEnd(); if (parms.colorOverlay) { gl_RenderState.SetTextureMode(TM_MASK); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.Apply(); glColor4ub(RPART(parms.colorOverlay),GPART(parms.colorOverlay),BPART(parms.colorOverlay),APART(parms.colorOverlay)); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(u1, v1); glVertex2d(x, y); glTexCoord2f(u1, v2); glVertex2d(x, y + h); glTexCoord2f(u2, v1); glVertex2d(x + w, y); glTexCoord2f(u2, v2); glVertex2d(x + w, y + h); glEnd(); } gl_RenderState.EnableAlphaTest(true); glScissor(0, 0, screen->GetWidth(), screen->GetHeight()); glDisable(GL_SCISSOR_TEST); gl_RenderState.SetTextureMode(TM_MODULATE); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendEquation(GL_FUNC_ADD); }