package gameEngine.entites.gameComponents; import gameEngine.entites.Entity; import gameEngine.views.*; 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; public int textSize; private Color color = new Color(0f,0f,0f,1f); private int spriteWidth = 1; // サイズとは無関係 private int spriteHeight = 1; // サイズとは無関係 // コンストラクタ public TextMesh(Entity parent, String text, int textSize) { this.parent = parent; this.text = text; this.textSize = textSize; Font font = new Font(new java.awt.Font(SANS_SERIF, PLAIN, textSize),true); fontTexture = font.getTexture(); fontGlyphs = font.getGlyphs(); fontHeight = font.getFontHeight(); } public TextMesh(TextMesh original, Entity newParent) { this.parent = newParent; this.text = original.text; this.textSize = original.textSize; this.fontGlyphs = original.fontGlyphs; this.fontTexture = original.fontTexture; this.fontHeight = original.fontHeight; } @Override public GameComponent copy() { return this; } @Override public void init() { renderText(); } @Override public void update() { Integer id = fontTexture.getId(); if (id == null) { fontTexture.init(); } renderText(); // テキストの描画 } public void setText(String newText){ this.text = newText; renderText(); } public void setTextSize(int newTextSize) { if(newTextSize < 3 || newTextSize > 127) return; this.textSize = newTextSize; Font font = new Font(new java.awt.Font(SANS_SERIF, PLAIN, textSize), true); this.fontTexture = font.getTexture(); this.fontGlyphs = font.getGlyphs(); this.fontHeight = font.getFontHeight(); renderText(); } public void setColor(Color color){ this.color = color; 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(color.r, color.g, color.b, color.a); // 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; } }