Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Нужна помощь в решении проблеммы


Автор: Egnech 21.11.2007, 18:00
День добрый. 
Такая проблемма, я бы даже сказал проблемища. 
Есть программа, которая должна выводить на экран 3Д модельку, параметры которой должны подниматься из XML файла. Все успешно работало, до того момента пока я не стал обрабатывать нормали, которые подгружаю из тойже XML"ки. Нормали худо-бедно отображаються, но вертуальная машина стала выдавать EXEPTION_ACCES_VIOLATION при запуске программы. Ещё бывает программа поработает некоторое время,  а потом только выдаст ошибку.
Причем чем меньше полигонов в модельке, тем дольше прорабатывает программа.
Помогите пожалуйста разобраться в чем причина ошибки. Ниже приведен весь код программы.

Тут выводится на экран моделька.
Код

public class Renderer implements GLEventListener {
    arrayFiller af = new arrayFiller();
    XMLReader xrd = new XMLReader();
    public static float angel = 0;
    public static int x = 0;
    public static int y = 0;
    public static int z = -20;
    
    public Renderer() {    
    }    
    public void init(GLAutoDrawable drawable) {    
        GL gl = drawable.getGL();    
        GLU glu = new GLU();    
        gl.glClearColor(0.5f, 0.5f, 0.5f, 0f);    
        gl.glClearDepth(3f);    
        gl.glDepthFunc(GL.GL_LESS);    
        gl.glEnable(GL.GL_DEPTH_TEST);    
        gl.glShadeModel(GL.GL_SMOOTH);    
        gl.glMatrixMode(GL.GL_PROJECTION);    
        gl.glLoadIdentity();    
        glu.gluPerspective(45f, 4f/3f, 0.1f, 100f);    
        gl.glMatrixMode(GL.GL_MODELVIEW);    
        gl.glEnable(GL.GL_LIGHTING);
        //gl.glEnable (gl.GL_AUTO_NORMAL);
        gl.glEnable(GL.GL_LIGHT0);    
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, new float[]{0.5f, 0.5f, 0.5f, 0f}, 0);    
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[]{0f, 10f, -5f, 1f}, 0);
  }    
    public void display(GLAutoDrawable drawable) {    
        GL gl = drawable.getGL();
        
        GLUT glut = new GLUT();    
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);    
        gl.glLoadIdentity();
        gl.glTranslated( x ,y,z);
        gl.glRotated (angel,0,1,0);
        af.loadToBuffer ();
        
              
      gl.glEnableClientState(gl.GL_NORMAL_ARRAY);
      gl.glEnableClientState(GL.GL_VERTEX_ARRAY);                
        
        gl.glNormalPointer (GL.GL_FLOAT, 0,af.normalsBuf);
        
        gl.glVertexPointer(3, GL.GL_DOUBLE, 0, af.VerticesBuf);      
        
        gl.glDrawElements(GL.GL_TRIANGLES, xrd.sizeFace, GL.GL_UNSIGNED_INT, af.indicesBuf);
        
        
      gl.glDisableClientState(gl.GL_NORMAL_ARRAY);
      gl.glDisableClientState(gl.GL_VERTEX_ARRAY);

      
    }    
    
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {    
    }    
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {    
    }    
     
}

Код

public class GLFrame extends Frame implements  KeyListener {
    
    private GLCanvas canvas;    
    private Animator anim;    
   static Renderer rd = new Renderer();
    arrayFiller af = new arrayFiller();
    XMLReader xrd= new XMLReader();
    public GLFrame() {    
        GLCanvas canvas = new GLCanvas();    
        canvas.setIgnoreRepaint(true);    
        canvas.setSize(640, 480);
                             
        setTitle("Sample OpenGL Java application");    
        setResizable(false);    
        setLayout(new BorderLayout());    
        add( canvas, BorderLayout.CENTER);
    
        
        setSize(getPreferredSize());    
         
        canvas.addGLEventListener(new Renderer());    
         
        anim = new Animator(canvas);    
        anim.setRunAsFastAsPossible(true);    
         
        anim.start();    
        
        addKeyListener(this);
        requestFocus();
        
        addWindowListener(new WindowAdapter() {    
            public void windowClosing(WindowEvent e) {    
                anim.stop();    
                dispose();    
            }    
        });    
    }    
     
    public static void main(String[] args) throws Exception {    
        
        XMLReader xrd = new XMLReader();
        arrayFiller af = new arrayFiller();
        xrd.getArraysSize();
        
        xrd.loadModelProp();
        
        
        GLFrame frame = new GLFrame();    
        frame.setVisible(true);    
        
        
    }    

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode () == KeyEvent.VK_1)
            rd.angel += 10f;
        if (e.getKeyCode () == KeyEvent.VK_RIGHT)
            rd.y += 2;
        if (e.getKeyCode () == KeyEvent.VK_LEFT)
            rd.y -= 2;
        if (e.getKeyCode () == KeyEvent.VK_3)
            rd.z += 2;
        if (e.getKeyCode () == KeyEvent.VK_4)
            rd.z -= 2;
    }

    public void keyReleased(KeyEvent e) {
    }
}

Тут она читается из XML'ки.
Сначала читается и устанавливается размер массивов, потом они наполняются.
Код

public class XMLReader {
public static int  sizeVert, sizeFace, sizeNormal;



 static arrayFiller af = new arrayFiller();
 String string = new String("test3.xml");
 
 public void getArraysSize(){
     try {
  File file = new File(string);
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  DocumentBuilder db = dbf.newDocumentBuilder();
  Document doc = db.parse(file);
  doc.getDocumentElement().normalize();
  NodeList nodeLst = doc.getElementsByTagName("array");
  for (int s = 0; s < nodeLst.getLength(); s++) {

      Node arraySize = nodeLst.item(s);

      Element array = (Element) arraySize;
      
      NodeList vertexArraySize = array.getElementsByTagName("allvertex");
      Element vertexArray = (Element) vertexArraySize.item(0);
      NodeList vertex = vertexArray.getChildNodes();
      System.out.println("All Vertex: " + ((Node) vertex.item(0)).getNodeValue());
      sizeVert = new Integer (((Node) vertex.item(0)).getNodeValue()).intValue ();
      
      NodeList faceArraySize = array.getElementsByTagName("allfaces");
      Element faceArray = (Element) faceArraySize.item(0);
      NodeList face = faceArray.getChildNodes();
      System.out.println("All Face: " + ((Node) face.item(0)).getNodeValue());
      sizeFace = new Integer (((Node) face.item(0)).getNodeValue()).intValue ();
      
      NodeList normalArraySize = array.getElementsByTagName("allnormals");
      Element normalArray = (Element) normalArraySize.item(0);
      NodeList normal = normalArray.getChildNodes();
      System.out.println("All Normal: " + ((Node) normal.item(0)).getNodeValue());
      sizeNormal = new Integer (((Node) normal.item(0)).getNodeValue()).intValue ();
      
      af.setArraySize (sizeVert,sizeFace,sizeNormal);
    }
   } catch (Exception e) {
    e.printStackTrace();
 }
 }
 public void loadModelProp() {
try {
  File file = new File(string);
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  DocumentBuilder db = dbf.newDocumentBuilder();
  Document doc = db.parse(file);
  doc.getDocumentElement().normalize();
  System.out.println("File type: " + doc.getDocumentElement().getNodeName());
  NodeList nodeLst = doc.getElementsByTagName("array");

  
  for (int s = 0; s < nodeLst.getLength(); s++) {

    Node fstNode = nodeLst.item(s);


      Element fstElmnt = (Element) fstNode;
      
      NodeList vertexArrayFill = fstElmnt.getElementsByTagName("vertex");
      for (int i = 0; i < sizeVert; i++){
      Element vertexArray = (Element) vertexArrayFill.item(i);
      NodeList vertex = vertexArray.getChildNodes();
     
      System.out.println("Vetex: "  + ((Node) vertex.item(0)).getNodeValue() );
      af.vertices[i] = (new Double (((Node) vertex.item(0)).getNodeValue()).doubleValue ());
      }
      
      NodeList normalArrayFill = fstElmnt.getElementsByTagName("normals");
      for (int i = 0; i < sizeNormal; i++){
      Element normalArray = (Element) normalArrayFill.item(i);
      NodeList normal = normalArray.getChildNodes();
     
      System.out.println("Normal: "  + ((Node) normal.item(0)).getNodeValue() );
      af.normals[i] = (new Float (((Node) normal.item(0)).getNodeValue()).floatValue ()) ;
      }
      
      NodeList faceArrayFill = fstElmnt.getElementsByTagName("face");
      for (int i = 0; i < sizeFace; i++){
      Element faceArray = (Element) faceArrayFill.item(i);
      NodeList face = faceArray.getChildNodes();
     
      System.out.println("Face: "  + ((Node) face.item(0)).getNodeValue() );
      af.indices[i] = (new Integer (((Node) face.item(0)).getNodeValue()).intValue ());
      }
              
  }
  } catch (Exception e) {
    e.printStackTrace();
  }
 }
}

Тут из массивов  данные перегоняются в буффер.
Код

public class arrayFiller {
   static XMLReader xrd = new XMLReader();
    public int elementsForRender;
    public static int indices[];
    public static float normals[];
    public static double vertices[];

    DoubleBuffer VerticesBuf = BufferUtil.newDoubleBuffer(xrd.sizeVert);//объявляем буфер для вершин
    IntBuffer indicesBuf = BufferUtil.newIntBuffer(xrd.sizeFace);//объявляем буфер для индексов
    FloatBuffer normalsBuf = BufferUtil.newFloatBuffer(xrd.sizeNormal);//объявляем буфер для нормалей
    
    public void setArraySize(int sizeVert, int sizeFace, int sizeNormal){
       vertices = new double[sizeVert]; 
       indices  = new int[sizeFace];
       normals = new float[sizeNormal];
    }
    
    
    public void loadToBuffer() {

    for (int i = 0; i < xrd.sizeVert; i++)
      VerticesBuf.put(vertices[i]); 
      VerticesBuf.rewind();

    for (int i = 0; i < xrd.sizeFace; i++){
      indicesBuf.put(indices[i]); }              //заполняем буффер индексов из массива
      indicesBuf.rewind();

    for (int i = 0; i < xrd.sizeNormal; i++){
      normalsBuf.put(normals[i]);}
      normalsBuf.rewind();
      
    }
}



PS. В качастве 3D библиотеки я использую JOGL.

Автор: Hidrag 22.11.2007, 00:56
Попробуй продебажить проект, чтобы найти в каком месте падает, глядя на код это трудно увидеть, а для воспроизведения необходимо иметь копию проекта, а не просто листинги...
Debug акбар...

Автор: powerOn 22.11.2007, 09:00

M
powerOn
Название темы должно отражать ее суть!

Автор: Egnech 22.11.2007, 16:15
Вылетает на glDrawElements, и только при условии отображения нормалей. Я уже построчно перебрал все... что же мои кривые руки не так сделали то...

Автор: Egnech 22.11.2007, 16:50
Етить... во я дурак... Я в скрипте экспорта неправильно считал кол-во нормалей...
smile Одну проблемму решил   smile Осталось только сделать так чтобы нормали нормально отображались.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)