質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

Q&A

解決済

1回答

279閲覧

JavaとLWJGLでobjファイルの3Dビュー画面を作りたい

Do2940

総合スコア3

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

0グッド

0クリップ

投稿2023/12/12 05:36

編集2023/12/12 12:33

実現したいこと

ここに実現したいことを箇条書きで書いてください。
objファイルを読み込んで、3Dビューで描画されるようにしたい

前提

ここに質問の内容を詳しく書いてください。

明滅を無くして3Dオブジェクトを描画、視点操作をできるようにするにはどこを直せばよろしいでしょうか
描画されない原因だけでも知りたいです、、

発生している問題・エラーメッセージ

ウィンドウを展開し、その中でobjファイルを取り込む部分まではできてると思うのですが、
(デバッグをしてもエラーは出なかったので)
画面が青→黒と明滅するだけで何も表示されません。
青になるのはglClearColorで値を青になるようにしてるのでわかるのですが
何も描画されないので手詰まりです、、
キー操作も入力後コンソールに文字を出力できたのでなので押していれば視点変更で何か映るはずなのですがずっと明滅してるだけです

エラーメッセージ

該当のソースコード

Java
OpenGL(LWJGL)

ソースコード import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.*; import org.lwjgl.assimp.AIFace; import org.lwjgl.assimp.AIMesh; import org.lwjgl.assimp.AIScene; import org.lwjgl.assimp.AIVector3D; import org.lwjgl.assimp.Assimp; import org.lwjgl.glfw.GLFWKeyCallback; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLUtil; import org.lwjgl.system.MemoryUtil; public class Game3D { private long window; private float rotationX = 45.0f; private float rotationY = 45.0f; private GLFWKeyCallback KeyCallback; public void run() { init(); loop(); //glfwFreeCallbacks(window); glfwDestroyWindow(window); glfwTerminate(); cleanup(); glfwSetErrorCallback(null).free(); } private void init() { if (!glfwInit()) { throw new IllegalStateException("Unable to initialize GLFW"); } glfwDefaultWindowHints(); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); window = glfwCreateWindow(800, 600, "Simple 3D Game", MemoryUtil.NULL, MemoryUtil.NULL); if (window == MemoryUtil.NULL) { throw new RuntimeException("Failed to create the GLFW window"); } glfwSetKeyCallback(window, KeyCallback = new GLFWKeyCallback() { @Override public void invoke(long window, int key, int scancode, int action, int mods) { if (action == GLFW_PRESS) { switch (key) { case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(window, true); break; case GLFW_KEY_W: rotationX += 5.0f;                 System.out.println("wが押された"); break; case GLFW_KEY_S: rotationX -= 5.0f; break; case GLFW_KEY_A: rotationY += 5.0f; break; case GLFW_KEY_D: rotationY -= 5.0f; break; } } } }); GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); glfwSetWindowPos(window, (vidMode.width() - 800) / 2, (vidMode.height() - 600) / 2); glfwMakeContextCurrent(window); glfwSwapInterval(1); glfwShowWindow(window); GL.createCapabilities(); glEnable(GL_DEPTH_TEST); GLUtil.setupDebugMessageCallback(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthFunc(GL_LEQUAL); } private void loop() { glClearColor(0.0f, 0.0f, 5.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //描画内容の初期化 while (!glfwWindowShouldClose(window)) { glfwPollEvents(); render(); glfwSwapBuffers(window); } cleanup(); } private void render() { glRotatef(rotationX, 1.0f, 0.0f, 0.0f); glRotatef(rotationY, 0.0f, 1.0f, 0.0f); AIScene obj = Assimp.aiImportFile("ここにファイルパス", 1); for (int i = 0; i < obj.mNumMeshes(); i++) { AIMesh mesh = AIMesh.create(obj.mMeshes().get(i)); renderMesh(mesh); } glfwSwapBuffers(window); glfwPollEvents(); Assimp.aiReleaseImport(obj); } private void cleanup() { KeyCallback.free(); } private void renderMesh(AIMesh mesh) { System.out.println("Rendering mesh with " + mesh.mNumFaces() + "faces."); glBegin(GL_TRIANGLES); for (int i = 0; i < mesh.mNumFaces(); i++) { AIFace face = mesh.mFaces().get(i); for ( int j = 0; j < face.mNumIndices(); j++) { int index = face.mIndices().get(j); AIVector3D vertex = mesh.mVertices().get(index); glVertex3f(vertex.x(), vertex.y(), vertex.z()); } } glEnd(); } public static void main(String[] args) { new Game3D().run(); } }

試したこと

・初期視点部分の値(rotationX,rotationYの部分)を変更しましたが変わらず明滅するだけでした。

・キー操作を受け取ったらその内容をコンソールに出力する、を試しました。
表示されたのでキー操作の認識はできてると思います

・上と同じ方法で、objの頂点メッシュの値もコンソールに出力されました。(renderMeshメソッド内のSystem.outの部分です)

・loopメソッド内のglfwPollEvents(); render(); glfwSwapBuffers(window);の順番をそれぞれ入れ替えましたが変わりませんでした。

補足情報(FW/ツールのバージョンなど)

イメージ説明
ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

LWJGLは知りませんが、見る限りC言語のOpenGL/GLFWを呼んでいるだけのようなので、おおよそ何をやっているか検討は付きます。
その観点で見ても、おかしい点がいくつかあります。

まず、glClearは描画処理の最初に行うこと。

java

1 // ここではなく。 2 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //描画内容の初期化 3 4 while (!glfwWindowShouldClose(window)) { 5 glfwPollEvents(); 6 7 // 描画処理の前で行う。 8 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //描画内容の初期化 9 render(); 10 11 glfwSwapBuffers(window); 12 13 } 14

また、glfwSwapBuffersglfwPollEvents の呼び出しが、renderメソッドの中と外で呼ばれているのもおかしいです。

GLFWのコードであれば、大抵、

  1. glClear
  2. 描画処理
  3. glfwSwapBuffers
  4. glfwPollEvents

という順で呼び出し、これを繰り返すようになるはずです。

また、ビュー(カメラ)やプロジェクション(投影)の座標変換の処理が見当たらないのも気になります。
これらの設定をしないで、まともに表示できるとは思えません。
この辺りの話はここで説明して理解できるほど簡単な話ではありませんが、OpenGLの3Dプログラミングでは理解しなければならない重要な話です。
それだけに、OpenGLの勉強をしていれば必ず出てくる話だと思いますので、しっかり理解してください。
(gluPerspective とか gluLookAt などをキーワードにして検索すれば、情報が出てくるかと思います)

もしかすると、LWJGLの情報は少ないかもしれませんが、一般的にあるC言語を対象としたOpenGLやGLFWの情報でも参考になるはずです。
Javaだから、といってスルーせずに参考にすることをおすすめします。


もう一つ付け加えると、objファイルの読み込みをレンダリングするたびに行っているようですが、モデルの読み込みは処理としては重いものであり、かつ一度読めばまず変更する必要がないはずなので、最初に一回呼んでおき、不要になったら解放する、というのが一般的かと思います。

投稿2023/12/13 14:44

katsuko

総合スコア3471

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Do2940

2023/12/15 18:02

透視投映行列、カメラのことなど全く知りませんでした… ご指摘いただいた呼び出しの位置を変え、透視投映行列の処理を調べて実装したところ、ひとまず明滅は無くなり描画まで来れました(少し潰れていますが)。 このままカメラまで実装してみようと思います。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問