2016-04-09 28 views
0

Bir pencereyi açacak ve görüntüleri görüntüleyebilecek bir program oluşturmaya çalışıyorum (bir oyun yapmak istiyorum). C++ 'da önce OGL ile çalıştığım için, bu sefer bir Java öğrenmeye karar verdim ve kendimi LWJGL aldım. Resmi eğitici yardımıyla pencereyi kurdum ve her şey yolundaydı. Ama dokuları yüklemeyi denediğimde, çarpışmalara rastladım. Program glGenTextures çağırarak çöküyor. Birçok benzer soru gördüm ve çoğu cevap iş parçacığının bir bağlam eksikliğiydi, ama bunu da ayarlamıştım.GlGenTextures çağıran kilitlenme

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(); 
} 

ben belirgin bir şey eksik: Ben pencere ve bağlam kurmak nasıl burada olduğu

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 
    } 
} 

Ve: İşte kod ben resim yüklemek için kullandığınız edilir? Yanlış bir şey mi yapıyorum? Son 6 saat boyunca burada bulundum ve cevabı bulamıyorum. Yardım etmek için bir çarpışma günlüğü sağlayabilirim. Hepsi şu demektedir: EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff9e87ebf60, pid=15984, tid=17180

cevap

1

Elbette bir soru yayınladığımda cevabı buluyorum. ByteBuffers'ın doğrudan olması gerektiği için, ByteBuffer.allocateDirect(n) yöntemini kullanmak zorunda kaldım. ByteBuffer'larımın hepsini değiştirmesi için her şeyi değiştirir bitirmez, her şey yolunda gitti.

+0

Bu hala bana doğru görünmüyor. LWJGL'yi bildiğim kadarıyla kabul etmiyorum, ama OpenGL'deki isimler "GLuint" türündedir. Bu 32-bit bir türüdür. Depolama için 8 öğeye sahip bir bayt arabelleği ayırdınız. En fazla iki isim saklamak için yeterli. Bu senin orijinal niyetin miydi? Boyutu 2 olan bir “IntBuffer” daha az sorgulanabilir olacaktır - tıpkı bir başkasının, OpenGL'de bir ismin ne kadar büyük olduğunun farkında olmanız halinde, kodunuzu okuyan birinin kendilerine sorması gerekmeyecektir. –

+0

@ AndonM.Coleman 'GLuint ', C++' daki doku adları için kullanılan türüdür. Java'da böyle bir şey yoktur, sadece düzenli bir 'int' yeterlidir. Ancak Java'da hiçbir işaretçi olmadığı için, “GLuint” C++ kullanımını “ByteBuffer” olarak değiştirmek zorunda kaldılar. Ve bu yüzden onu kullandım. İsim büyüklüğüne gelince, beni bilgilendirdiğin için teşekkürler! Gelecekte başvurmak için hatırlayacağım. – Yanthir

+0

@Yanthir Genelde, arabellek ayırma işlemini sizin için halledecek olan 'BufferUtils.createByteBuffer' yardımcı programını kullanmalısınız. – javac