Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / gameEngine / entites / gameComponents / TextMesh.java
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;
    }
}