2014-04-06 2 views
1

Я пытаюсь создать игру Pong в LWJGL. Мне удалось нарисовать «летучую мышь» и мяч, и я также могу сделать движение летучей мыши вверх и вниз с помощью клавиш W и S.LWJGL - Игра вылетает после glEnableVertexAttribArray (1)

Теперь я пытаюсь покрасить летучую мышь с использованием шейдеров, но я столкнулся с ошибкой, когда пытаюсь - glEnableVertexAttribArray (1) - включить второй массив вершин (в цикле), который содержит цвет. Второй массив вершин получает включен, но игра вылетает, когда он пытается привлечь мою биту - glDrawElements (GL11.GL_TRIANGLES, bat.getIndicesCount(), GL11.GL_UNSIGNED_BYTE, 0).

Если удалить glEnableVertexAttribArray (1) он рисует биту и как-то цвета моя летучая мышь с красным цветом. Я попытался изменить информацию о цвете в классе Batt, но ничего не происходит, поэтому я не уверен, откуда он получает цвет.

P.S: Я бегу системы x64 Arch Linux.

Роковая ошибка это одна:

A fatal error has been detected by the Java Runtime Environment: 
SIGSEGV (0xb) at pc=0x000000004027ef4b, pid=7664, tid=139636374128384 
# 
# JRE version: OpenJDK Runtime Environment (7.0_51-b31) (build 1.7.0_51-b31) 
# Java VM: OpenJDK 64-Bit Server VM (24.51-b03 mixed mode linux-amd64 compressed oops) 
# Problematic frame: 
# C 0x000000004027ef4b 
# 
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again 
# 
# An error report file with more information is saved as: 
# /home/borg/workspace/LWJGL-Test/hs_err_pid7664.log 
# 
# If you would like to submit a bug report, please include 
# instructions on how to reproduce the bug and visit: 
# http://icedtea.classpath.org/bugzilla 

Файл, который содержит все остальные ошибки это один (я положил его в ссылку Pastebin, чтобы сделать его более удобным для чтения) http://pastebin.com/hSnJuAar

Теперь для самой программы.

Основной класс:

package myPackage; 

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 

import myPackage.Bat; 
import myPackage.Ball; 

import org.lwjgl.LWJGLException; 
import org.lwjgl.opengl.*; 

public class Test { 

    // Setup variables 
    private int WIDTH = 800; 
    private int HEIGHT = 600; 
    private String title = "PONG GAME"; 

    private Bat bat; 
    private Ball ball; 

    //Shader variables 
    private int vsId = 0; 
    private int fsId = 0; 
    private int pId = 0; 


    public Test() { 

     // Initialize 
     System.out.println("-->Initializing OpenGL<--"); 
     setupOpenGL(); 
     System.out.println("OpenGL initialized"); 

     System.out.println("-->Preparing to draw ...<--"); 
     setupDraw(); 
     setupShaders(); 
     System.out.println("...Everything is initialized..."); 
     System.out.println("Entering loop ..."); 
     while (!Display.isCloseRequested()) { 

      loop(); 

      Display.update(); 
      Display.sync(60); 

     } 
     System.out.println("--> EXITING LOOP "); 
     System.out.println("-->Cleaning memory<--"); 
     destroyOpenGL(); 

    } 

    public void setupOpenGL() { 

     try { 

      Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); // Create 
      // the 
      // display 
      Display.setTitle(title); 
      Display.create(); 
      System.out.println("Display created"); 

     } catch (LWJGLException e) { 
      e.printStackTrace(); 
      System.exit(-1); // If error , exit program 
     } 

     GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Clears the screen with 
     // black color 

    } 

    public void setupDraw() { 

     bat = new Bat(-1f,0.3f,0,1,0.07f,0.6f); 
     ball = new Ball(0.03f,0,0); 

    } 

    private void setupShaders() { 

     // Load the vertex shader 
     vsId = loadShader("/home/borg/workspace/LWJGL-Test/src/myPackage/vertex.glsl", GL20.GL_VERTEX_SHADER); 
     // Load the fragment shader 
     fsId = loadShader("/home/borg/workspace/LWJGL-Test/src/myPackage/fragment.glsl", GL20.GL_FRAGMENT_SHADER); 

     // Create a new shader program that links both shaders 
     pId = GL20.glCreateProgram(); 
     GL20.glAttachShader(pId, vsId); 
     GL20.glAttachShader(pId, fsId); 

     // Position information will be attribute 0 
     GL20.glBindAttribLocation(pId, 0, "in_Position"); 
     // Color information will be attribute 1 
     GL20.glBindAttribLocation(pId, 1, "in_Color"); 

     GL20.glLinkProgram(pId); 
     GL20.glValidateProgram(pId); 

     System.out.println("Shaders initialized"); 
    } 

    public void loop() { 

     //BAT 
     GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); // Clears the screen color using 
     // glClearColor in setupOpenGL() 


     GL20.glUseProgram(pId); 

     // Bind to the VAO that has all the information about the vertices 
     GL30.glBindVertexArray(bat.getVao()); 
     GL20.glEnableVertexAttribArray(0); 
     GL20.glEnableVertexAttribArray(1); 

     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, bat.getVboi()); 
     System.out.println("Indices buffer bound"); 

     // Draw the vertices 
     GL11.glDrawElements(GL11.GL_TRIANGLES, bat.getIndicesCount(), GL11.GL_UNSIGNED_BYTE, 0); 
     System.out.println("Drawing bat with indices"); 

     // Put everything back to default (deselect) 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 
     GL20.glDisableVertexAttribArray(0); 
     GL20.glDisableVertexAttribArray(1); 
     GL30.glBindVertexArray(0); 
     GL20.glUseProgram(0); 

     bat.readInput(); 

     //CIRCLE 
     GL30.glBindVertexArray(ball.getVao()); 
     GL20.glEnableVertexAttribArray(0); 

     // Draw the vertices 

     GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, 0, ball.getCircleVertexSize()/2); 

     // Put everything back to default (deselect) 
     GL20.glDisableVertexAttribArray(0); 
     GL30.glBindVertexArray(0); 

    } 

    public int loadShader(String filename, int type) { 
     StringBuilder shaderSource = new StringBuilder(); 
     int shaderID = 0; 

     try { 
      BufferedReader reader = new BufferedReader(new FileReader(filename)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       shaderSource.append(line).append("\n"); 
      } 
      reader.close(); 
     } catch (IOException e) { 
      System.err.println("Could not read file."); 
      e.printStackTrace(); 
      System.exit(-1); 
     } 

     shaderID = GL20.glCreateShader(type); 
     GL20.glShaderSource(shaderID, shaderSource); 
     GL20.glCompileShader(shaderID); 

     return shaderID; 
    } 


    public void destroyOpenGL() { 
     // Delete the shaders 
       GL20.glUseProgram(0); 
       GL20.glDetachShader(pId, vsId); 
       GL20.glDetachShader(pId, fsId); 

       GL20.glDeleteShader(vsId); 
       GL20.glDeleteShader(fsId); 
       GL20.glDeleteProgram(pId); 

     GL30.glBindVertexArray(bat.getVao()); 
     GL30.glBindVertexArray(ball.getVao()); 

     GL20.glDisableVertexAttribArray(0); 
     GL20.glDisableVertexAttribArray(1); 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 
     GL15.glDeleteBuffers(bat.getVbo()); 
     GL15.glDeleteBuffers(ball.getVbo()); 

     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 
     GL15.glDeleteBuffers(bat.getVboi()); 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 
     GL15.glDeleteBuffers(bat.getVboc()); 

     GL30.glBindVertexArray(0); 
     GL30.glDeleteVertexArrays(bat.getVao()); 
     //GL30.glDeleteVertexArrays(ball.getVao()); 
     System.out.println("Everything deleted"); 
     Display.destroy(); 
     System.out.println("Display destroyed"); 
    } 


    public static void main(String[] args) { 

     new Test(); 

    } 

} 

Bat класс:

package myPackage; 

import java.nio.ByteBuffer; 

import java.nio.FloatBuffer; 

import org.lwjgl.BufferUtils; 
import org.lwjgl.input.Keyboard; 
import org.lwjgl.opengl.Display; 
import org.lwjgl.opengl.GL11; 
import org.lwjgl.opengl.GL15; 
import org.lwjgl.opengl.GL20; 
import org.lwjgl.opengl.GL30; 


public class Bat { 

    float x,y,z,w,height,width; 
    float yp = 0; 
    private int vao = 0; 
    private int vbo = 0; 
    private int vboi = 0; 
    private int vboc = 0; 
    private int indicesCount; 
    float[] batVertex ; 
    byte[] indices; 
    float[] colors; 

    public Bat(float x, float y, float z, float w, float width, float height) { 

     this.x = x; 
     this.y = y; 
     this.z = z; 
     this.w = w; 
     this.height = height; 
     this.width = width; 

     batVertex = new float[]{ // Vertex coordinates 

       x, y, z, w,      // ID = 0 
       x + width, y , z, w,    // ID = 1 
       x + width, y - height, z, w,  // ID = 2 
       x , -y , z , w     // ID = 3 

     }; 

     FloatBuffer batBuffer = BufferUtils.createFloatBuffer(batVertex.length); 
      batBuffer.put(batVertex); 
      batBuffer.flip(); 

     colors = new float[] { 
       1f, 0f, 0f, 1f, 
       0f, 1f, 0f, 1f, 
       0f, 0f, 1f, 1f, 
       1f, 1f, 1f, 1f, 
       }; 


     FloatBuffer colorsBuffer = BufferUtils.createFloatBuffer(colors.length); 
     colorsBuffer.put(colors); 
     colorsBuffer.flip(); 


     //QUAD INDICES 
     indices = new byte[] { 
      0,3,2, 
      2,1,0 
     }; 

     indicesCount = indices.length; 
     ByteBuffer indicesBuffer = BufferUtils.createByteBuffer(indicesCount); 
     indicesBuffer.put(indices); 
     indicesBuffer.flip(); 
     //=============================== 




     //BAT VBO AND ARRAY 
     vao = GL30.glGenVertexArrays(); 
     GL30.glBindVertexArray(vao); 

     vbo = GL15.glGenBuffers(); 
     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo); 
     GL15.glBufferData(GL15.GL_ARRAY_BUFFER, batBuffer, GL15.GL_STATIC_DRAW); 
     GL20.glVertexAttribPointer(0, 4, GL11.GL_FLOAT, false, 0, 0); 
     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 
     GL30.glBindVertexArray(0); 
     //===================================== 


     //Colors vbo 
     vboc = GL15.glGenBuffers(); 
     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboc); 
     GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorsBuffer, GL15.GL_STATIC_DRAW); 
     GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0,0); 
     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 
     //====================================== 

     GL30.glBindVertexArray(0); 

     //Indices vbo 
     vboi = GL15.glGenBuffers(); 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboi); 
     GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW); 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 
     //======================================= 


     System.out.println("Bat initialized"); 
    } 

    public void moveUp() { 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, getVbo()); 


     //System.out.println("x : " + bat.getVertices()[0] + " y : " + bat.getVertices()[1]); 

     if (getVertices()[1] >= 1.0f) { 

      yp = 0; 
      for (int i = 1; i < getVertexSize(); i = i + 4) { 
       getVertices()[i] = getVertices()[i] + yp; 

      } 
     } 

     else { 
      yp = 0.025f; 
      for (int i = 1; i < getVertexSize(); i = i + 4) { 
       getVertices()[i] = getVertices()[i] + yp; 

      } 
     } 

     FloatBuffer vertexFloatBuffer = BufferUtils 
       .createFloatBuffer(getVertexSize()); 
     vertexFloatBuffer.put(getVertices()); 
     vertexFloatBuffer.flip(); 

     GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, vertexFloatBuffer); 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 

    } 

    public void moveDown() { 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, getVbo()); 
     //System.out.println("x : " + bat.getVertices()[0] + " y : " + bat.getVertices()[1]); 

     if (getVertices()[13] < -1.0f) { 
      yp = 0; 
      for (int i = 1; i < getVertexSize(); i = i + 4) { 
       getVertices()[i] = getVertices()[i] - yp; 

      } 
     } 

     else { 
      yp = 0.025f; 
      for (int i = 1; i < getVertexSize(); i = i + 4) { 
       getVertices()[i] = getVertices()[i] - yp; 

      } 
     } 

     FloatBuffer vertexFloatBuffer = BufferUtils 
       .createFloatBuffer(getVertexSize()); 
     vertexFloatBuffer.put(getVertices()); 
     vertexFloatBuffer.flip(); 

     GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, vertexFloatBuffer); 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 

    } 

    public void readInput() { 

     if (Keyboard.isKeyDown(Keyboard.KEY_W)) { 

      moveUp(); 
     } 

     if (Keyboard.isKeyDown(Keyboard.KEY_S)) { 

      moveDown(); 
     } 

     if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { 

      System.exit(0); 
      Display.destroy(); 
     } 

    } 

    public int getVao() { 
     return vao; 
    } 


    public int getVbo() { 
     return vbo; 
    } 

    public int getVboi() { 
     return vboi; 
    } 

    public int getVboc() { 
     return vboc; 
    } 

    public int getVertexSize(){ 

     return batVertex.length; 

    } 

    public int getIndicesCount(){ 
     return indicesCount; 
    } 

    public float[] getVertices() { 

     return batVertex; 

    } 

    public byte[] getIndices() { 
     return indices; 
    } 



} 

Болл класс:

package myPackage; 

import java.nio.FloatBuffer; 

import org.lwjgl.BufferUtils; 
import org.lwjgl.opengl.GL11; 
import org.lwjgl.opengl.GL15; 
import org.lwjgl.opengl.GL20; 
import org.lwjgl.opengl.GL30; 

public class Ball { 

    float r = 0.03f; 
    float x; 
    float y; 
    float offSetX = 0; 
    float offSetY = 0; 
    private int vao = 0; 
    private int vbo = 0; 
    float[] circleVertex ; 

    public Ball(float r, float offSetX, float offSetY) { 

     this.r = r; 

     this.offSetX = offSetX; 
     this.offSetY = offSetY; 

     int SUBDIVISIONS = 20; 

     circleVertex = new float[(SUBDIVISIONS) * 2]; 

     for (int i = 2; i < circleVertex.length; i = i + 2) { 

      double angle = Math.PI * 2 * i/SUBDIVISIONS; 

      x = (float) Math.cos(angle) * r; 
      y = (float) Math.sin(angle) * r; 

      circleVertex[i] = x + offSetX; 
      circleVertex[i + 1] = y + offSetY; 

     } 

     circleVertex[0] = 0 + offSetX; 
     circleVertex[1] = 0 + offSetY; 

     FloatBuffer circleBuffer = BufferUtils 
       .createFloatBuffer(circleVertex.length); 
     circleBuffer.put(circleVertex); 
     circleBuffer.flip(); 

     vao = GL30.glGenVertexArrays(); 
     GL30.glBindVertexArray(vao); 

     vbo = GL15.glGenBuffers(); 
     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo); 
     GL15.glBufferData(GL15.GL_ARRAY_BUFFER, circleBuffer, 
       GL15.GL_STATIC_DRAW); 

     GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0); 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 
     System.out.println("Ball initialized"); 
    } 

    public int getVao() { 
     return vao; 
    } 

    public int getVbo() { 
     return vbo; 
    } 

    public int getCircleVertexSize() { 
     return circleVertex.length; 
    } 


} 

Фрагмент шейдеры:

#version 150 

in vec4 pass_Color; 

out vec4 out_Color; 

void main(void) { 
    out_Color = pass_Color; 
} 

Vertex шейдеров:

#version 150 

in vec4 in_Position; 
in vec4 in_Color; 

out vec4 pass_Color; 

void main(void){ 
    gl_Position = in_Position; 
    pass_Color = in_Color; 

} 

ответ

2

Около линии 88 в классе Бат, перед определением цветового буфера, у вас есть дополнительный GL30.glBindVertexArray(0);.

Из-за этого, буфер цвета никогда не заканчивается в правильном массиве, а это связано ни к чему.

Смежные вопросы