2016-04-09 4 views
0

私はウィンドウをオンにして画像を表示できるプログラムを作成しようとしていました(私はゲームを作りたい)。これまで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

答えて

1

私は質問を投稿するとすぐに私は答えを見つける。 ByteBuffersが直接的である必要があることが判明したので、ByteBuffer.allocateDirect(n)メソッドを使用しなければなりませんでした。すべての私のByteBuffersを変更するとすぐに、すべてがスムーズに実行されました。

+0

これはまだ私にとっては正しいとは思われません。私はLWJGLをよく知っているわけではありませんが、OpenGLの名前は 'GLuint'タイプです。これは32ビットタイプです。 8要素の記憶容量を持つバイトバッファーを割り当てています。たった2つの名前を格納するのに十分です。これは元の意図ですか?サイズ2の 'IntBuffer'はあまり疑わしいものではありません。あなたのコードを読んでいる誰かが、OpenGLの名前の大きさを知っているかどうかを尋ねる必要はありません。 –

+0

@ AndonM.Coleman 'GLuint'はC++のテクスチャ名に使われる型です。 Javaでは、通常の 'int'だけで十分です。そのようなものはありません。しかし、Javaにはポインタがないので、 'GLuint' C++の使用法を' ByteBuffer'に変更しなければなりませんでした。それが私が使った理由です。名前のサイズについては、私にそれを知らせてくれてありがとう!私は、将来の参照のためにそれを覚えておいてください。 – Yanthir

+0

@ Yanthir一般的に、BufferUtils.createByteBuffer'ユーティリティメソッドを使用してください。これはあなたのためのバッファ割り当てを処理します。 – javac

関連する問題