私はウィンドウをオンにして画像を表示できるプログラムを作成しようとしていました(私はゲームを作りたい)。これまでC++でOGLを使っていたので、今回は自分のLWJGLを学びました。私は公式のチュートリアルの助けを借りて窓を開けました。しかし、テクスチャを読み込もうとすると、すぐにクラッシュするようになりました。プログラムはglGenTexturesを呼び出す際にクラッシュし続けます。私は多くの同様の質問を見てきましたが、ほとんどの答えは、スレッドにはコンテキストが欠けていたということでしたが、私もそれを設定しました。ここで私はイメージをロードするために使用するコードは次のとおりです。glGenTexturesを呼び出す際にクラッシュする
public Image(String path) {
this();
try {
InputStream in = new FileInputStream(path);
try {
PNGDecoder decoder = new PNGDecoder(in);
ByteBuffer buf = ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight());
decoder.decode(buf, decoder.getWidth()*4, Format.RGBA);
buf.flip();
ByteBuffer TextureNameGen = ByteBuffer.allocate(8);
glGenTextures(1, TextureNameGen); //<-- This is where the program crashes
TextureID = TextureNameGen.getInt();
ByteBuffer boundTexture = ByteBuffer.allocate(8);
glGetIntegerv(GL_TEXTURE_BINDING_2D, boundTexture);
glBindTexture(GL_TEXTURE_2D, TextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, boundTexture.getInt());
Width = decoder.getWidth();
Height = decoder.getHeight();
} finally {
in.close();
}
list.add(this);
} catch (Exception e) {
//Do nothing
}
}
そして、ここでは、私は、ウィンドウとコンテキストを設定する方法である:
private void init() {
//Setup an error callback
glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
//Initialize GLFW
if (glfwInit() != GLFW_TRUE)
throw new IllegalStateException("Unable to initialize GLFW");
//Create the window
window = glfwCreateWindow(WIDTH, HEIGHT, "RopeProject", NULL, NULL);
if (window == NULL)
throw new RuntimeException("Failed to create the GLFW window");
//Setup a key callback
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
Controls.instance.pushCommand(key, action);
}
}
);
//Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
//Center our window
glfwSetWindowPos(window, (vidmode.width() - WIDTH)/2, (vidmode.height() - HEIGHT)/2);
//Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
//Essential
GL.createCapabilities();
//GL Attributes
glViewport(0, 0, WIDTH, HEIGHT);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
new Image("./gfx/Test.png"); //<-- Here is where I try to load up the texture.
PhysicsThread.instance.start();
}
私は明らかに何かが足りないのですか?私は何か間違っているのですか?私は過去6時間それをしてきました。私は答えを見つけることができません。それが助けになるなら私はクラッシュログを提供することができます。彼らはすべてこれを言っている: EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff9e87ebf60, pid=15984, tid=17180
これはまだ私にとっては正しいとは思われません。私はLWJGLをよく知っているわけではありませんが、OpenGLの名前は 'GLuint'タイプです。これは32ビットタイプです。 8要素の記憶容量を持つバイトバッファーを割り当てています。たった2つの名前を格納するのに十分です。これは元の意図ですか?サイズ2の 'IntBuffer'はあまり疑わしいものではありません。あなたのコードを読んでいる誰かが、OpenGLの名前の大きさを知っているかどうかを尋ねる必要はありません。 –
@ AndonM.Coleman 'GLuint'はC++のテクスチャ名に使われる型です。 Javaでは、通常の 'int'だけで十分です。そのようなものはありません。しかし、Javaにはポインタがないので、 'GLuint' C++の使用法を' ByteBuffer'に変更しなければなりませんでした。それが私が使った理由です。名前のサイズについては、私にそれを知らせてくれてありがとう!私は、将来の参照のためにそれを覚えておいてください。 – Yanthir
@ Yanthir一般的に、BufferUtils.createByteBuffer'ユーティリティメソッドを使用してください。これはあなたのためのバッファ割り当てを処理します。 – javac