Can someone please help me complete this sample code?

classic Classic list List threaded Threaded
6 messages Options
s3a
Reply | Threaded
Open this post in threaded view
|

Can someone please help me complete this sample code?

s3a
I am reading C++ OpenGL tutorials on random websites and this is the translation I made. I am using JOGL 1.1.1/OpenGL 2.1 (and I am avoiding deprecated code).

My current problem is understanding what these two lines do (or if I translated them correctly from C++ since my Java is good but my C++ isn't so great - I am working on my C++ skills separately):

gl.glGenBuffers(1, &positionBufferObject);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, positionBufferObject);

If I did anything else wrong, please correct me for that too. I'm still trying to make a polygon or some kind of shape display in 3D without using syntax like glBegin and glEnd as a "Hello world" type of program so that I can get started for real. Basically, I think I am avoiding the fixed function pipeline and aiming at using the programmable shader pipeline.

Here is the mini-JOGL code sample I made:

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.swing.JFrame;

public class Third implements GLEventListener
{
    public void init(GLAutoDrawable glad) {

    }

    public void display(GLAutoDrawable drawable) {
        // What I know works
        GL gl = drawable.getGL();
        gl.glClearColor(0.1f, 0.5f, 1.0f, 0.7f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glFlush();

        // What I'm trying to learn now
        int theProgram = gl.glCreateProgram();
        gl.glUseProgram(theProgram);

        gl.glGenBuffers(1, &positionBufferObject); // This seems pointer-ish (I do not know much about C++ pointers yet) - is it incorrect in Java use?
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, positionBufferObject); // I am trying to create a positionBufferObject object reference variable on the line above
        gl.glEnableVertexAttribArray(0);
        gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT, false, 0, 0);

        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);

        gl.glDisableVertexAttribArray(0);
        gl.glUseProgram(0);

//        gl.glutSwapBuffers();
    }

    public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3) {

    }

    public void displayChanged(GLAutoDrawable glad, boolean bln, boolean bln1) {

    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("TheFrame");
        GLCanvas canvas = new GLCanvas();
        canvas.addGLEventListener(new Third());
        frame.add(canvas);
        frame.setSize(300,300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Any input would be greatly appreciated!
Thanks in advance!
Reply | Threaded
Open this post in threaded view
|

Re: Can someone please help me complete this sample code?

JStoecker
>> gl.glGenBuffers(1, &positionBufferObject);

This is invalid syntax for a Java program and won't work.

In C or C++ you can have pointers to primitives like int, double, float, etc. That allows you to have functions that change the value of primitive type variables passed as arguments. For example:

void foo(int* x) {
  *x = 10;
}

int main() {
  int number = 5;
  foo(&number); // after this call number = 10
  return 0;
}

In Java, you can't have a method that will change the value of a primitive type variable like in the above example. You can, of course, pass an object as an argument and modify its contents. That's why you have the wrapper classes like Integer, Boolean, Double, etc.

OpenGL is a C library, and it is very common in C code to have functions where "output" is provided to a caller by changing the values of the arguments. You can see this with the glGenBuffers(GLsizei n, GLuint* buffers) function. This function will create n OpenGL-managed buffers and return some integers to the caller. These integers will be stored in the "buffers" argument, which could be 1 GLuint or an array of GLuint (pointers and arrays are closely linked in C).

So in C, you would call this as follows to create a single buffer:

GLuint buffer;
glGenBuffers(1, &buffer);

or multiple buffers:

GLuint buffers[3];
glGenBuffers(3, buffers);

In Java, you don't have this concept of a traditional pointers. There are two options in the JOGL API:

glGenBuffers(int n, int[] buffers, int buffers_offset)

This first choice takes an array and would be used like this (including the bind call to set the buffer):

int[] buffer = new int[1];
gl.glGenBuffers(1, buffer, 0);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, buffer[0]);

or for multiple:

int[] buffers = new int[3];
gl.glGenBuffers(3, buffers, 0);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, buffers[0]);

Why is there a third parameter? This is in case you want to start filling the array at an index after 0. For example, an array with size 5 and you want to put the buffer value in the 3rd element. This isn't a useful parameter in the C API because you can do pointer arithmetic: glGenBuffers(1, buffers+2);

The second option in JOGL: glGenBuffers(int n, IntBuffer buffers)

Here, IntBuffer is an object that can store values just like an array. There is no third parameter because Buffer objects in Java have a position field that determines where reading starts, so you could offset it like this (which would put the value in the third element):

IntBuffer buffers = IntBuffer.allocate(3);
gl.glGenBuffers(1, buffers.position(2));
s3a
Reply | Threaded
Open this post in threaded view
|

Re: Can someone please help me complete this sample code?

s3a
This post was updated on .
Thanks for your answer. I ported some other C++ code I found online (because it looked more straightforward and like it would yield faster results) taking into account what you said as you will see in the code that will follow but I would again really appreciate to know if it's all been ported properly as well as what to put as the second parameter in the glBufferData method. I apologize if I ask anything obvious as I probably have in the past but I think I'm almost reaching a stage where I can "take the training wheels off" and be less dependent on the JOGL community for trivial things.

Here is the current code I am dealing with:

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;

public class MyClass implements GLEventListener
{

    public void init(GLAutoDrawable glad) {
        // code
    }

    public void display(GLAutoDrawable drawable) {
        
        GL gl = drawable.getGL();

        // An array of 3 vectors which represents 3 vertices
        /*static final */float[] g_vertex_buffer_data = {
           -1.0f, -1.0f, 0.0f,
           1.0f, -1.0f, 0.0f,
           0.0f,  1.0f, 0.0f,
        };

        // This will identify our vertex buffer
        int[] vertexbuffer = new int[1];

        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        gl.glGenBuffers(1, vertexbuffer, 0);

        // The following commands will talk about our 'vertexbuffer' buffer
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexbuffer[0]);

        // Give our vertices to OpenGL.
        gl.glBufferData(GL.GL_ARRAY_BUFFER, /*sizeof(g_vertex_buffer_data)*/, g_vertex_buffer_data, GL.GL_STATIC_DRAW); // WHAT DO I PUT AS THE SECOND PARAMETER?

        // 1rst attribute buffer : vertices
        gl.glEnableVertexAttribArray(0);
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexbuffer[0]);
        gl.glVertexAttribPointer(
           0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
           3,                  // size
           GL.GL_FLOAT,           // type
           false,           // normalized?
           0,                  // stride
           /*(void*)*/0            // array buffer offset
        );

        // Draw the triangle !
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

        gl.glDisableVertexAttribArray(0);
    }

    public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3) {
        // code
    }

    public void displayChanged(GLAutoDrawable glad, boolean bln, boolean bln1) {
        // code
    }

}

P.S.
Is there no way to elegantly place code in this forum? I tried checking "Message is in HTML Format" and then <code></code> but that didn't work.
Reply | Threaded
Open this post in threaded view
|

Re: Can someone please help me complete this sample code?

Wade Walker
Administrator
You might try "More options > Raw text", which inserts <raw> and </raw> tags.
s3a
Reply | Threaded
Open this post in threaded view
|

Re: Can someone please help me complete this sample code?

s3a
Okay thanks, I made the code more legible. So yeah, if someone can help me with my main issue, it would be much appreciated.
Reply | Threaded
Open this post in threaded view
|

Re: Can someone please help me complete this sample code?

Wade Walker
Administrator
You might check out the example program posted in http://forum.jogamp.org/glBufferData-and-glBufferSubData-seems-not-to-work-td3267295.html. After the fix at the end of the thread, it works and shows how to draw with vertex buffers and index buffers.