package gameEngine.entites.gameComponents; import gameEngine.entites.Entity; import gameEngine.views.*; import javax.swing.*; import java.util.Map; import static java.awt.Font.*; import static org.lwjgl.opengl.GL11.*; public class TextMesh extends GameComponent{ private Texture fontTexture; // スプライトのテクスチャを保持 private Map<Character, Glyph> fontGlyphs; private int fontHeight; private Entity parent; // 親のオブジェクトを持つ public String text; private int spriteWidth = 1; // サイズとは無関係 private int spriteHeight = 1; // サイズとは無関係 // コンストラクタ public TextMesh(Entity parent, String text) { this.parent = parent; this.text = text; Font font = new Font(new java.awt.Font(SANS_SERIF, PLAIN, 64),true); fontTexture = font.getTexture(); fontGlyphs = font.getGlyphs(); fontHeight = font.getFontHeight(); } @Override public GameComponent copy() { return new TextMesh(this.parent, this.text); } @Override public void init() { renderText(); } @Override public void update() { Integer id = fontTexture.getId(); if (id == null) { fontTexture.init(); } renderText(); // テキストの描画 } public void renderText() { // Switch to 2D rendering mode glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, Window.get().width, Window.get().height, 0, -1000, 1000); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // Bind the font texture for text rendering glBindTexture(GL_TEXTURE_2D, fontTexture.getId()); // Retrieve parent GameObject's transform data float x = parent.transform.position.x; float y = parent.transform.position.y; float z = parent.transform.position.z; float rotationX = parent.transform.rotation.x; float rotationY = parent.transform.rotation.y; float rotationZ = parent.transform.rotation.z; float scaleX = parent.transform.scale.x; float scaleY = parent.transform.scale.y; float scaleZ = parent.transform.scale.z; float zScale = z >= 0 ? 1.0f + (z * 0.1f) : 1.0f / (1.0f + Math.abs(z) * 0.1f); glTranslatef(x + spriteWidth / 2.0f, y + spriteHeight / 2.0f, z); glRotatef(rotationX, 1, 0, 0); glRotatef(rotationY, 0, 1, 0); glRotatef(rotationZ, 0, 0, 1); glScalef(scaleX * zScale, scaleY * zScale, scaleZ); glTranslatef(-(x + spriteWidth / 2.0f), -(y + spriteHeight / 2.0f), z); glEnable(GL_TEXTURE_2D); //ここで文字の背景の透明化 glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //ここまで文字の背景の透明化 glColor4f(1f, 1f, 1f, 1f); // Text drawing logic float drawX = x; float drawY = y; int textHeight = getHeight(text); if (textHeight > fontHeight) { drawY += textHeight - fontHeight; } for (int i = 0; i < text.length(); i++) { char ch = text.charAt(i); if (ch == '\n') { // Handle new line drawY -= fontHeight; drawX = x; continue; } if (ch == '\r') { continue; } Glyph g = fontGlyphs.get(ch); if (g != null) { // Render each character as a textured quad glBegin(GL_QUADS); glTexCoord2f(g.x / (float) fontTexture.getWidth(), g.y / (float) fontTexture.getHeight()); glVertex3f(drawX, drawY, z); glTexCoord2f((g.x + g.width) / (float) fontTexture.getWidth(), g.y / (float) fontTexture.getHeight()); glVertex3f(drawX + g.width, drawY, z); glTexCoord2f((g.x + g.width) / (float) fontTexture.getWidth(), (g.y + g.height) / (float) fontTexture.getHeight()); glVertex3f(drawX + g.width, drawY + g.height, z); glTexCoord2f(g.x / (float) fontTexture.getWidth(), (g.y + g.height) / (float) fontTexture.getHeight()); glVertex3f(drawX, drawY + g.height, z); glEnd(); drawX += g.width; } } // Reset OpenGL states glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Restore the previous matrix state glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); } /** * Gets the height of the specified text. * * @param text The text * @return Height of text */ public int getHeight(CharSequence text) { int height = 0; int lineHeight = 0; for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); if (c == '\n') { /* Line end, add line height to stored height */ height += lineHeight; lineHeight = 0; continue; } if (c == '\r') { /* Carriage return, just skip it */ continue; } Glyph g = fontGlyphs.get(c); lineHeight = Math.max(lineHeight, g.height); } height += lineHeight; return height; } }