Vertex Arrays Problems

Hello, probably this problem has an obviuos solution, but I’m new at Java and JoGL (I come from C++) and I cant find the solution. Well, this is my problem:
I am trying to render a simple cube, through vertex arrays (not inmediate mode), but just after the glVertexPointer call, I get an exception. Here is my code:

    float vertices[] = {-5,-5,-5,  5,-5,-5,  5,5,-5, -5,5,-5,  
                                  -5,-5,5,   5,-5,5,   5,5,5,  -5,5,5};                              
    FloatBuffer vert = FloatBuffer.allocate(24);        
    vert.put(vertices);        
    gl.glVertexPointer(3, gl.GL_FLOAT, 0, vert);  

and this is the error that I am getting:

An unexpected error has been detected by HotSpot Virtual Machine:

EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000, pid=196, tid=3820

Java VM: Java HotSpot™ Client VM (1.5.0_04-b05 mixed mode, sharing)

Problematic frame:

C 0x00000000

An error report file with more information is saved as hs_err_pid196.log

If you would like to submit a bug report, please visit:

http://java.sun.com/webapps/bugreport/crash.jsp

Any help would be appreciated,
Thanks

add vert.flip(); before you call the gl command

After Added .flip(); I get just the same error.

It’s LWJGL who uses the position and limit. JOGL just ignores it.

The error is possibly somewhere else. Can you post the code where you draw the vertices?

ah, my bad, I just assumed JOGL would use the buffers in the same way…

Did you remember to enable the vertex array?


float vertices[] = {-5,-5,-5,  5,-5,-5,  5,5,-5, -5,5,-5, 
                                      -5,-5,5,   5,-5,5,   5,5,5,  -5,5,5};                             
        FloatBuffer vert = FloatBuffer.allocate(24);       
        vert.put(vertices);
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3, gl.GL_FLOAT, 0, vert);

FloatBuffer.allocate(24);

is an array-backed buffer, not a direct-buffer

use:


ByteBuffer.allocateDirect(24 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();
or
BufferUtils.createFloatBuffer(24); // which does the same as the line above

Could you post more of your program? If you were trying to pass a non-direct buffer to glVertexPointer it should have thrown an exception, not crashed the JVM. Are you trying to call OpenGL routines while your GLEventListener’s callbacks are not active on the stack?


ByteBuffer.allocateDirect(24 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();

This “works”, in the meaning that the VM does not crash, and I can see a quad, so I must clean the rest of my gl code.

Here is the whole code of the rendering class (I am following a tutorial, so not all this code is mine):


import net.java.games.jogl.*;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.nio.ByteBuffer;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.*;
import java.nio.*;


public class JoglPanel extends JPanel implements GLEventListener, Animated 
{
    private GLCanvas canvas;
    private float angle;
    ByteBuffer texture;
    int[] textures;
    int tWidth;
    int tHeight;
    
    
    public JoglPanel() 
    {
        super();
        this.textures=new int[1];
        GLCapabilities capabilities = new GLCapabilities();
        capabilities.setHardwareAccelerated(true);
        capabilities.setDoubleBuffered(true);           
        canvas = GLDrawableFactory.getFactory().createGLCanvas(capabilities);
        canvas.addGLEventListener(this);
        this.add(canvas);
        this.setSize(640,480);
        canvas.setSize(640,480);
        canvas.setVisible(true);        
    }

    public void BuildCube(GL myGL)
    {    	          	
        float vertices[] = {-5,-5,-5,  5,-5,-5,  5,5,-5, -5,5,-5,  
                            -5,-5,5,   5,-5,5,   5,5,5,  -5,5,5};                              
        float texCoords[] = {0,0,  1,0,  1,1,  0,1,
                             1,1,  0,1,  0,0,  1,0};
        
        FloatBuffer vert = FloatBuffer.allocate(24);
        //FloatBuffer vert = ByteBuffer.allocateDirect(24 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();        //this is the new way that seems to work
        vert.put(vertices);
        vert.flip();
        
      /*  FloatBuffer  tex = FloatBuffer allocate(8 * 2 * 8);
        for(int i=0;i<8 * 2 * 8;i++)
            tex.putFloat(texCoords[i]);*/
                                           
        myGL.glVertexPointer(3, GL.GL_FLOAT, 0,(Buffer)vert);        
        //myGL.glTexCoordPointer(2, GL.GL_FLOAT, 0, tex);			    
    }
    
    public void init(GLDrawable glDrawable) 
    {
        GL myGL = glDrawable.getGL();
        BuildCube(myGL);
        myGL.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        myGL.glShadeModel(GL.GL_SMOOTH);
        myGL.glGenTextures(0, textures);
        myGL.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
        loadTexture();
        myGL.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, tWidth, tHeight, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture);        
        myGL.glShadeModel(GL.GL_SMOOTH);
        myGL.glEnable(GL.GL_TEXTURE_2D);
        myGL.glEnable(GL.GL_DEPTH_TEST);
        myGL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
        myGL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
    }

    public void reshape(GLDrawable glDrawable, int i, int i1, int i2, int i3) 
    {
        GL myGL = glDrawable.getGL();
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        myGL.glMatrixMode(GL.GL_PROJECTION);
        myGL.glLoadIdentity();        
        glDrawable.getGLU().gluPerspective(45, (float)width/height, 1, 1000);
        myGL.glMatrixMode(GL.GL_MODELVIEW);
        myGL.glLoadIdentity();
    }

    public void display(GLDrawable glDrawable)
    {
        GL myGL = glDrawable.getGL();
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        myGL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);       
        myGL.glLoadIdentity();
        
        myGL.glTranslatef(0,0,-50);
        myGL.glRotatef(angle,0,0,1); 
        
        myGL.glEnableClientState(GL.GL_VERTEX_ARRAY);
        //myGL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
        int cube[]  = {2,1,3,0, 
				       5,6,4,7, 
				       6,2,7,3, 
				       1,5,0,4,     
				       3,0,7,4, 
				       6,5,2,1};             
        myGL.glDrawElements(GL.GL_QUADS, 24, GL.GL_INT, cube);       
        
        myGL.glDisableClientState(GL.GL_VERTEX_ARRAY);
       // myGL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
          
        myGL.glFlush();
    }
    
    public void displayChanged(GLDrawable glDrawable, boolean b, boolean b1) 
    {
       
    }

    public void timeStep(long time) 
    {
        angle+=2;
        canvas.repaint();
    }
    
    public void loadTexture() 
    {
        try 
        {
            BufferedImage buff = ImageIO.read(new File("o.jpg"));
            Raster r = buff.getRaster();
            int[] img = null;
            img = r.getPixels(0, 0, buff.getWidth(), buff.getHeight(), img);

            texture = ByteBuffer.allocateDirect(buff.getWidth() * buff.getHeight() * 3);
            for (int y = 0; y < buff.getHeight(); y++)
            {
                for (int x = 0; x < buff.getWidth(); x++) 
                {
                    texture.put((byte) img[(y * buff.getWidth() + x) * 3]);
                    texture.put((byte) img[(y * buff.getWidth() + x) * 3 + 1]);
                    texture.put((byte) img[(y * buff.getWidth() + x) * 3 + 2]);
                }
            }
            tWidth = buff.getWidth();
            tHeight = buff.getHeight();
        }
        catch (IOException e) 
        {
            e.printStackTrace();  
        }
    }

Modification: With the changes in the creating buffer process, now all works fine, many thanks :slight_smile:

FloatBuffer vert = FloatBuffer.allocate(24);
        //FloatBuffer vert = ByteBuffer.allocateDirect(24 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();        //this is the new way that seems to work
        vert.put(vertices);
        vert.flip();
       
      /*  FloatBuffer  tex = FloatBuffer allocate(8 * 2 * 8);
        for(int i=0;i<8 * 2 * 8;i++)
            tex.putFloat(texCoords[i]);*/
                                           
        myGL.glVertexPointer(3, GL.GL_FLOAT, 0,(Buffer)vert);       
        //myGL.glTexCoordPointer(2, GL.GL_FLOAT, 0, tex); 

Eeeeep!

glVertexPointer doesn’t do any copying, it just holds on to a pointer to the raw data. So after that function returns ‘vert’ is unreferenced and potentially can be gc’d. If that happens before you do your glDrawElements then you’ll be rendering junk data. :o