diff --git a/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java b/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java new file mode 100644 index 0000000..4f19b3d --- /dev/null +++ b/GameEngine/src/main/java/gameEngine/entites/gameComponents/TextMesh.java @@ -0,0 +1,199 @@ +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 fontGlyphs; + private int fontHeight; + private Entity parent; // 親のオブジェクトを持つ + public String text; + + private int spriteWidth = 512; // スプライト幅(今後指定可能にする) + private int spriteHeight = 256; // スプライト高さ(今後指定可能にする) + + + // コンストラクタ + 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); + 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 width of the specified text. + * + * @param text The text + * @return Width of text + */ + public int getWidth(CharSequence text) { + int width = 0; + int lineWidth = 0; + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (c == '\n') { + /* Line end, set width to maximum from line width and stored + * width */ + width = Math.max(width, lineWidth); + lineWidth = 0; + continue; + } + if (c == '\r') { + /* Carriage return, just skip it */ + continue; + } + Glyph g = fontGlyphs.get(c); + lineWidth += g.width; + } + width = Math.max(width, lineWidth); + return width; + } + + /** + * 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; + } +}