From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.Client/GuiComponent.cpp | 136 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 Minecraft.Client/GuiComponent.cpp (limited to 'Minecraft.Client/GuiComponent.cpp') diff --git a/Minecraft.Client/GuiComponent.cpp b/Minecraft.Client/GuiComponent.cpp new file mode 100644 index 00000000..92abf36d --- /dev/null +++ b/Minecraft.Client/GuiComponent.cpp @@ -0,0 +1,136 @@ +#include "stdafx.h" +#include "GuiComponent.h" +#include "Tesselator.h" + +void GuiComponent::hLine(int x0, int x1, int y, int col) +{ + if (x1 < x0) + { + int tmp = x0; + x0 = x1; + x1 = tmp; + } + fill(x0, y, x1 + 1, y + 1, col); +} + +void GuiComponent::vLine(int x, int y0, int y1, int col) +{ + if (y1 < y0) + { + int tmp = y0; + y0 = y1; + y1 = tmp; + } + fill(x, y0 + 1, x + 1, y1, col); +} + +void GuiComponent::fill(int x0, int y0, int x1, int y1, int col) +{ + if (x0 < x1) + { + int tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 < y1) + { + int tmp = y0; + y0 = y1; + y1 = tmp; + } + float a = ((col >> 24) & 0xff) / 255.0f; + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; + Tesselator *t = Tesselator::getInstance(); + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(r, g, b, a); + t->begin(); + t->vertex((float)(x0), (float)( y1), (float)( 0)); + t->vertex((float)(x1), (float)( y1), (float)( 0)); + t->vertex((float)(x1), (float)( y0), (float)( 0)); + t->vertex((float)(x0), (float)( y0), (float)( 0)); + t->end(); + glEnable(GL_TEXTURE_2D); + glDisable(GL_BLEND); +} + +void GuiComponent::fillGradient(int x0, int y0, int x1, int y1, int col1, int col2) +{ + float a1 = ((col1 >> 24) & 0xff) / 255.0f; + float r1 = ((col1 >> 16) & 0xff) / 255.0f; + float g1 = ((col1 >> 8) & 0xff) / 255.0f; + float b1 = ((col1) & 0xff) / 255.0f; + + float a2 = ((col2 >> 24) & 0xff) / 255.0f; + float r2 = ((col2 >> 16) & 0xff) / 255.0f; + float g2 = ((col2 >> 8) & 0xff) / 255.0f; + float b2 = ((col2) & 0xff) / 255.0f; + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel(GL_SMOOTH); + + Tesselator *t = Tesselator::getInstance(); + t->begin(); + t->color(r1, g1, b1, a1); + t->vertex((float)(x1), (float)( y0), blitOffset); + t->vertex((float)(x0), (float)( y0), blitOffset); + t->color(r2, g2, b2, a2); + t->vertex((float)(x0), (float)( y1), blitOffset); + t->vertex((float)(x1), (float)( y1), blitOffset); + t->end(); + + glShadeModel(GL_FLAT); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glEnable(GL_TEXTURE_2D); +} + +GuiComponent::GuiComponent() +{ + blitOffset = 0; +} + +void GuiComponent::drawCenteredString(Font *font, const wstring& str, int x, int y, int color) +{ + font->drawShadow(str, x - (font->width(str)) / 2, y, color); +} + +void GuiComponent::drawString(Font *font, const wstring& str, int x, int y, int color) +{ + font->drawShadow(str, x, y, color); +} + +void GuiComponent::blit(int x, int y, int sx, int sy, int w, int h) +{ + float us = 1 / 256.0f; + float vs = 1 / 256.0f; + Tesselator *t = Tesselator::getInstance(); + t->begin(); + + // This is a bit of a mystery. In general this ought to be 0.5 to match the centre of texels & pixels in the DX9 version of things. However, when scaling the GUI by a factor of 1.5, I'm + // really not sure how exactly point sampled rasterisation works, but when shifting by 0.5 we get a discontinuity down the diagonal of quads. Setting this shift to 0.75 in all cases seems to work fine. + const float extraShift = 0.75f; + + // 4J - subtracting extraShift (actual screen pixels, so need to compensate for physical & game width) from each x & y coordinate to compensate for centre of pixels in directx vs openGL + float dx = ( extraShift * (float)Minecraft::GetInstance()->width ) / (float)Minecraft::GetInstance()->width_phys; + // 4J - Also factor in the scaling from gui coordinate space to the screen. This varies based on user-selected gui scale, and whether we are in a viewport mode or not + dx /= Gui::currentGuiScaleFactor; + float dy = extraShift / Gui::currentGuiScaleFactor; + // Ensure that the x/y, width and height are actually pixel aligned at our current scale factor - in particular, for split screen mode with the default (3X) + // scale, we have an overall scale factor of 3 * 0.5 = 1.5, and so any odd pixels won't align + float fx = (floorf((float)x * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor; + float fy = (floorf((float)y * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor; + float fw = (floorf((float)w * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor; + float fh = (floorf((float)h * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor; + + t->vertexUV(fx + 0 - dx, fy + fh - dy, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + h) * vs)); + t->vertexUV(fx + fw - dx, fy + fh - dy, (float)( blitOffset), (float)( (sx + w) * us), (float)( (sy + h) * vs)); + t->vertexUV(fx + fw - dx, fy + 0 - dy, (float)( blitOffset), (float)( (sx + w) * us), (float)( (sy + 0) * vs)); + t->vertexUV(fx + 0 - dx, fy + 0 - dy, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + 0) * vs)); + t->end(); +} \ No newline at end of file -- cgit v1.2.3