package gameEngine.entites.gameComponents; import gameEngine.entites.Entity; import gameEngine.entites.GameObject; import gameEngine.views.Texture; import gameEngine.views.Window; import static org.lwjgl.opengl.GL11.*; public class Mesh extends GameComponent { public enum MeshType { SPRITE, CUBE } private final MeshType type; private Texture texture; // スプライトのテクスチャを保持 private final Entity parent; // 親のオブジェクトを持つ private int spriteWidth = 64; // スプライト幅(今後指定可能にする) private int spriteHeight = 64; // スプライト高さ(今後指定可能にする) public Mesh(Entity parent, MeshType type, String texturePath) { this.parent = parent; this.type = type; if (type == MeshType.SPRITE) { this.texture = new Texture(texturePath); // Load the image } } public Mesh(Mesh original, Entity newParent) { this.type = original.type; this.texture = original.texture; // Textureをそのまま参照 this.parent = newParent; // 新しい親オブジェクトに設定 } @Override public GameComponent copy() { return this; } @Override public void init() { if (type == MeshType.SPRITE) { renderSprite(); // スプライトの描画 } } @Override public void update() { if (type == MeshType.SPRITE) { Integer id = texture.getId(); if(id == null){ texture.init(); } renderSprite(); // スプライトの描画 } } public void setTexturePath(String texturePath){ this.texture = new Texture(texturePath); } private void renderSprite() { // 2Dの描画モードに切り替え glMatrixMode(GL_PROJECTION);// 投影行列の設定モードに切り替え glPushMatrix(); // 現在の投影行列を保存 glLoadIdentity(); // 単位行列をロードして投影行列をリセット // ピクセル単位の座標系に設定 (画面左上が原点、画面サイズはWindowの幅と高さ) /* x軸: 左が0、右がWindow.get().width(ウィンドウの幅) y軸: 上が0、下がWindow.get().height(ウィンドウの高さ) z軸: -1000から1000の範囲で設定 */ glOrtho(0, Window.get().width, Window.get().height, 0, -1000, 1000); // モデルビュー行列に切り替えて、描画する位置を決める glMatrixMode(GL_MODELVIEW); // モデルビュー行列の設定モードに切り替え glPushMatrix(); // 現在のモデルビュー行列を保存 glLoadIdentity(); // 単位行列をロードしてモデルビュー行列をリセット // テクスチャをバインド (テクスチャIDをOpenGLに設定) glBindTexture(GL_TEXTURE_2D, texture.getId()); // 親のGameObjectの座標と回転を取得 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; if (z >= 0) { zScale = 1.0f + (z * 0.1f); } else { zScale = 1.0f / (1.0f + Math.abs(z) * 0.1f); } // 回転の適用 glTranslatef(x + spriteWidth / 2.0f, y + spriteHeight / 2.0f, z); // 回転中心をスプライトの中心に glRotatef(rotationX, 1, 0, 0); // X軸周りの回転 glRotatef(rotationY, 0, 1, 0); // Y軸周りの回転 glRotatef(rotationZ, 0, 0, 1); // Z軸周りの回転 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); // テクスチャを有効にして、イメージの座標とサイズを指定 glEnable(GL_TEXTURE_2D); // テクスチャを有効化 glColor4f(1f, 1f, 1f, 1f);// 色を白に設定 (テクスチャそのままの色で表示) // 四角形を描画 (テクスチャ座標と画面座標を対応付け) glBegin(GL_QUADS); // 四角形を描画する glTexCoord2f(0, 0); glVertex3f(x, y, z); // 左上の頂点 (テクスチャ座標0,0と画面座標) glTexCoord2f(1, 0); glVertex3f(x + spriteWidth, y, z); // 右上の頂点 (テクスチャ座標1,0と画面座標) glTexCoord2f(1, 1); glVertex3f(x + spriteWidth, y + spriteHeight, z); // 右下の頂点 (テクスチャ座標1,1と画面座標) glTexCoord2f(0, 1); glVertex3f(x, y + spriteHeight, z); // 左下の頂点 (テクスチャ座標0,1と画面座標) glEnd(); // 四角形の描画を終了 // テクスチャの使用を終了 glDisable(GL_TEXTURE_2D); // テクスチャの無効化 glBindTexture(GL_TEXTURE_2D, 0); // テクスチャのバインドを解除 // 行列を元に戻す (PushしたものをPopで復元) glPopMatrix(); // モデルビュー行列を元に戻す glMatrixMode(GL_PROJECTION); // 投影行列の設定モードに切り替え glPopMatrix(); // 投影行列を元に戻す } }