OpenGL, Java, LWJGL - Drawing multiple triangles using IBOs, VBOs and VAOs - java

I am trying to render two triangles on the screen at once, using two different VBOs so that I can add textures later (to my understanding, if you want to add different textures, you must make two VBOs?).
I have tried using a combination of VAOs (both examples) and VAOs and IBOs (1st example).
Edit: As Stackoverflow doesn't recognise the tag, I'd like to clarify that IBO stands for Index Buffer Object
In both cases, I get a blank red screen.
I have previously managed to draw four triangles onto the screen using only one VBO and one IBO, but no VAO, putting all of the vertices into the one VBO, however I feel I need to learn how to draw multiple VBOs, as having everything in one VBO will become cumbersome and inefficient as greater numbers of objects are added.
I have already consulted other related questions as well as several tutorials, but have failed to find the information I am looking for in them (the tutorials tending to only describe drawing one item)
https://learnopengl.com/Getting-started/OpenGL
https://www.lwjgl.org/guide
OpenGL - VAO, VBO, IBO, glDrawElements not displaying
What is the role of glBindVertexArrays vs glBindBuffer and what is their relationship?
Textured triangles with OpenGL using VBO/IBO
Here is my source code:
Render loop
private void setupLoop() {
GL.createCapabilities();
debugProc = GLUtil.setupDebugMessageCallback();
// Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
while (!glfwWindowShouldClose(window)) {
Engine.makeAndDrawBuffersForTwoTriangles();
renderLoop();
}
}
private void renderLoop() {
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
float aspect = (float) width / height;
glLoadIdentity();
glOrtho(-aspect, aspect, -1, 1, -1, 1);
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events.
glfwPollEvents();
}
Defining my vertices and declaring my ids
static int vbo_left;
static int vao_left;
static int ibo_left;
static float left_vertices[] = { -0.5f, 0f, -0.25f, 0.5f, 0f, 0f };
static int left_indices[] = { 0, 1, 2, 3, 4, 5 };
static int vbo_right;
static int vao_right;
static int ibo_right;
static float right_vertices[] = { 0f, 0f, 0.25f, -0.5f, 0.5f, 0f };
static int right_indices[] = { 0, 1, 2, 3, 4, 5 };
1st Engine class
public static void makeAndDrawBuffersForTwoTriangles() {
// VBO
vbo_left = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);
// IBO
ibo_left = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_left);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
(IntBuffer) BufferUtils.createIntBuffer(left_indices.length).put(left_indices).flip(), GL_STATIC_DRAW);
glVertexPointer(2, GL_FLOAT, 0, 0L);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// VAO
vao_left = glGenVertexArrays();
glBindVertexArray(vao_left);
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
glBindVertexArray(0);
// VBO
vbo_right = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_right);
glBufferData(GL_ARRAY_BUFFER, right_vertices, GL_STATIC_DRAW);
// IBO
ibo_right = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_right);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
(IntBuffer) BufferUtils.createIntBuffer(right_indices.length).put(right_indices).flip(),
GL_STATIC_DRAW);
glVertexPointer(2, GL_FLOAT, 0, 0L);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// VAO
vao_right = glGenVertexArrays();
glBindVertexArray(vao_right);
glBindBuffer(GL_ARRAY_BUFFER, vbo_right);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
glBindVertexArray(0);
// Unbind all
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Draw elements
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_left);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
glDrawElements(GL_TRIANGLES, left_indices.length, GL_UNSIGNED_INT, 0L);
glBindBuffer(GL_ARRAY_BUFFER, vbo_right);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_right);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
glDrawElements(GL_TRIANGLES, right_indices.length, GL_UNSIGNED_INT, 0L);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
/*
// Draw Arrays
glBindVertexArray(vao_left);
glDrawArrays(GL_TRIANGLES, 0, left_indices.length);
glBindVertexArray(vao_right);
glDrawArrays(GL_TRIANGLES, 0, right_indices.length);
glBindVertexArray(0);
*/
2nd Engine class
public static void makeAndDrawBuffersForTwoTriangles() {
vbo_left = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);
vao_left = glGenVertexArrays();
glBindVertexArray(vao_left);
glBindBuffer(GL_ARRAY_BUFFER, vao_left);
glVertexAttribPointer(vao_left, 2, GL_FLOAT, false, 2, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
vbo_left = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);
vao_left = glGenVertexArrays();
glBindVertexArray(vao_left);
glBindBuffer(GL_ARRAY_BUFFER, vao_left);
glVertexAttribPointer(vao_left, 2, GL_FLOAT, false, 2, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(vao_left);
glDrawArrays(GL_TRIANGLES, 0, left_vertices.length);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(vao_right);
glDrawArrays(GL_TRIANGLES, 0, right_vertices.length);
}

The Index buffers binding is stated in the Vertex Array Object. Invoking glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); breaks the binding of the index buffer to the VAO.
You have to delete glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);.
Furthermore, the vertex specification is stored in the VAO, so the VAO has to be bound, before the array of generic vertex attribute data is specified and the index buffer is bound:
// VBO
vbo_left = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// IBO
ibo_left = glGenBuffers();
// VAO
vao_left = glGenVertexArrays();
glBindVertexArray(vao_left);
// IBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_left);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
(IntBuffer) BufferUtils.createIntBuffer(left_indices.length).put(left_indices).flip(), GL_STATIC_DRAW);
// vertex specification
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
Note, in compare to the index buffer, the array buffer binding is a global state.
Each attribute which is stated in the VAOs state vector may refer to a different ARRAY_BUFFER. This reference is stored when glVertexAttribPointer (respectively glVertexPointer) is called. Then the buffer which is currently bound to the target ARRAY_BUFFER is associated to the attribute and the name (value) of the object is stored in the state vector of the VAO.
But the index buffer is a state of the VAO. When a buffer is bound to the target ELEMENT_ARRAY_BUFFER, then this buffer is associated to the vertex array object which is currently bound.

Related

Skybox textures is transparent

My skybox is displayed, but does not display the textures that I load from the image. Instead, it shows the transparent color if i set glTexImage2D how GL_RGBA, or black color if i set glTexImage2D how GL_RGB.
I am using a render with MultisampledFbo support.
My texture loading code looks like this:
private int loadSkyboxTextures(){
glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glGenVertexArrays(vao);
glBindVertexArray(vao[0]);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glVertexPointer(3, GL_FLOAT, 3 * Float.BYTES, NULL);
glTexCoordPointer (3, GL_FLOAT, 3 * Float.BYTES, NULL);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
int texID = glGenTextures();
glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
for(int i = 0; i < TEXTURE_FILES.length; i++){
InputStream file = getClass().getResourceAsStream(TEXTURE_FILES[i]);
byte[] pixelData = new byte[0];
try {
pixelData = new byte[file.available()];
file.read(pixelData);
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer byteBuffer = ByteBuffer.wrap(pixelData);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 512, 512, 0,
GL_RGB, GL_UNSIGNED_BYTE, byteBuffer);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return texID;
}
Cube Render Code:
private void drawSkybox(){
glColor4f(1,1,1,1);
glDepthMask(false);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBindVertexArray(vao[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glDepthMask(true);
glDisable(GL_TEXTURE_CUBE_MAP);
}
The cube rendering call in the main render function:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
view = viewX || viewY || viewZ;
if(view)
glPushMatrix();
int rot = 180;
glDisable(GL_LIGHTING);
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-max, max, -1, 1, 10, -10);
glRotated(cameraX, 1f, 0f, 0);
glRotated(cameraY, 0f, 1f, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawSkybox(texId);
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
...
//render camera and other objects
For cube map textures, the texture coordinates are 3-dimensional and treated as a vector form the center of the cube map.
Since you draw a cube, which is centered around (0, 0, 0), you can use the the vertex coordinates for the texture coordinates, too. You do not use a shader program, so you have to use fixed function attributes. Specify the vertex coordinates by glVertexPointer and the texture coordinates by glTexCoordPointer. Enable the client-side capability (glEnableClientState) GL_VERTEX_ARRAY and GL_TEXTURE_COORD_ARRAY.
Specify the Vertex Array Object. It is sufficient to execute that code once at intialization:
glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glGenVertexArrays(vao);
glBindVertexArray(vao[0]);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glVertexPointer(3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glTexCoordPointer (3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(0);
When you draw the skybox it is sufficient to bind the cubemap texture to enable cube-mapped texturing and to bind the VAO:
private void drawSkybox(){
GL11.glColor4f(1,1,1,1);
glDepthMask(false);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
glBindVertexArray(vao[0]);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthMask(true);
glDisable(GL_TEXTURE_CUBE_MAP);
}
There are some further issues:
The image is not read correctly. See I have a black texture.
Clear the depth buffer after drawing the skybox. See Skybox textures do not display correctly

VBO and VAO not drawing opengl and LWJGL3

Ive been playing around with open GL for a while now and i got to the point that i can draw 3d shapes, My shapes and vertices and indices are definitely right and my shape was getting messed up. I am now wanting to redo my drawing. I used to only use VBO with no VAO and just bind and draw them. This worked but im suspicious of this being my bug. So i started using VAO's and i dont see anything that is wrong with my code and i still cant get it to draw my white square(no shaders just like the wiki tutorials).
My code for initializing the window is here:
private void initWindow() {
//Makes sure window can work
if (!glfwInit()) {
throw new IllegalStateException("Failed to Initialize GLFW!");
}
//Create window object and set its hints
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
this.windowRef = glfwCreateWindow(width, height, name, NULL, NULL);
if (windowRef == 0) {
throw new IllegalStateException("Failed to create Window!");
}
GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(windowRef, (videoMode.width() - width) / 2, (videoMode.height() - height) / 2);
// Make the OpenGL context current
glfwMakeContextCurrent(windowRef);
// Enable v-sync
glfwSwapInterval(1);
//Make GL capabilites for window
GL.createCapabilities();
glfwShowWindow(windowRef);
}
my code for initializing my buffers and objects is here
public void loadGL() {
float[] vertex = {
0f, 0f, 0f, //0
0.5f, 0, 0, //1
0.5f, 0, 0.5f, //2
0f, 0f, 0.5f, //3
0f, 0.5f, 0f, //4
0.5f, 0.5f, 0, //5
0.5f, 0.5f, 0.5f,//6
0f, 0.5f, 0.5f//7
};
int[] index = {
0, 1, 2, //0
0, 2, 3, //1
0, 3, 4, //2
3, 7, 4,//3
0, 4, 1,//4
1, 5, 4,//5
1, 5, 2,//6
2, 6, 5,//7
2, 3, 6,//8
3, 7, 6,//9
4, 5, 7,//10
5, 6, 7//11
};
size = 12*3;
indicesBuff = BufferUtils.createIntBuffer(index.length);
vertBuff = BufferUtils.createFloatBuffer(vertex.length);
indicesBuff.put(index);
vertBuff.put(vertex);
indicesBuff.flip();
vertBuff.flip();
vao = glGenVertexArrays();
glBindVertexArray(vao);
vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
ibo = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuff, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
and finally my main loop is here, it is called after the window init:
private void mainLoop() {
loadGL();
glClearColor(0.5f, 0.5f, 0.5f, 1);
while (!glfwWindowShouldClose(windowRef)) {
//Render Stuff here
//TODO: later skip this block if nothing has changed
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear
the framebuffer
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
// glBegin(GL_QUADS);
// glVertex3f(-0.5f, -0.5f, 0);
// glVertex3f(-0.5f, 0.5f, 0);
// glVertex3f(0.5f, -0.5f, 0);
// glVertex3f(0.5f, 0.5f, 0);
// glEnd();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glfwSwapBuffers(windowRef);
glfwPollEvents();
}
}
btw drawing it with glBegin and so works but its not efficient for what i want to do.
The modern way of rendering in OpenGL, would be to use a Shader program.
If you don't use a shader program, than you have to define the array of vertex data using the deprected way by glVertexPointer and you have to enable the client-side capability for vertex coordinates by glEnableClientState( GL_VERTEX_ARRAY ):
vao = glGenVertexArrays();
glBindVertexArray(vao);
vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
GL20.glVertexPointer(3, GL_FLOAT, 0, 0); // <--------------
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(vao);
glEnableClientState( GL_VERTEX_ARRAY ); // <--------------
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableClientState( GL_VERTEX_ARRAY ); // <---------------
glBindVertexArray(0);
Further note, that the state of the client-side capability (or vertex attribute array) and the reference to the index (element) buffer is stored in the Vertex Array Objects state vector.
So it is sufficient to enable the vertex coordinates, when the vertex array object is specified and to bid the index buffer when the vertex array object is bound. The enabling and disabling of the vertex coordinates and binding of the index buffer, when drawing the geometry, can be omitted:
vao = glGenVertexArrays();
glBindVertexArray(vao);
vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
GL20.glVertexPointer(3, GL_FLOAT, 0, 0); // <--------------
glEnableClientState( GL_VERTEX_ARRAY ); // <--------------
glBindBuffer(GL_ARRAY_BUFFER, 0);
ibo = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuff, GL_STATIC_DRAW);
// skip glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);

Trying to draw a basic shape with LWJGL3

so i want to draw a shape using VAO and VBOs and i think im doing everything right but whenever i run my code i just get the window with the clear color. I had an issue before when i tried to initialize the triangles before i called create capabilities, am i missing some function to start drawing?
here is my code:
int vaoId, vboId, vertexCount;
float[] vertices = {
// Left bottom triangle
-0.5f, 0.5f,
-0.5f, -0.5f,
0.5f, -0.5f,};
private void init() {
if (!glfwInit()) {
throw new IllegalStateException("Failed to Initialize GLFW!");
}
int width = 1000;
int height = 1000;
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
window = glfwCreateWindow(width, height, "App", NULL, NULL);
if (window == 0) {
throw new IllegalStateException("Failed to create Window!");
}
GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (videoMode.width() - width) / 2, (videoMode.height() - height) / 2);
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
glfwShowWindow(window);
}
private void loop() {
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the GLCapabilities instance and makes the OpenGL
// bindings available for use.
GL.createCapabilities();
initTriangle();
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT); // clear the framebuffer
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
}
}
private void initTriangle() {
FloatBuffer vertBuf = MemoryUtil.memAllocFloat(vertices.length);
vertBuf.put(vertices);
vertBuf.flip();
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vertBuf, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
I hope you guys can help, thanks a lot.
I am not using shaders. Is that my problem? And is it a necessity
The state of the art way of rendering in OpenGL, would be to use a Shader.
If you don't use a shader, than you have to define the array of vertex data by glVertexPointer
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vertBuf, GL_STATIC_DRAW);
glVertexPointer( 2, GL_FLOAT, 0, 0 ); // <---------------
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
and you have to enable the client-side capability for vertex coordinates by glEnableClientState( GL_VERTEX_ARRAY ):
glBindVertexArray(vaoId);
glEnableClientState( GL_VERTEX_ARRAY ); // <---------------
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glDisableClientState( GL_VERTEX_ARRAY ); // <---------------
glBindVertexArray(0);
Note, this state of the client-side capability (or vertex attribute array) is stored in the Vertex Array Object.
So it is sufficient to enable the vertex coordinates, when the vertex array object is specified. The enabling and disabling of the vertex coordinates, when drawing the geometry, can be omitted:
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vertBuf, GL_STATIC_DRAW);
glVertexPointer( 2, GL_FLOAT, 0, 0 );
glEnableClientState( GL_VERTEX_ARRAY ); // <---------------
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindVertexArray(vaoId);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glBindVertexArray(0);

How to use glDrawArrays to display cube in JOGL

I am new in with Java OpenGL (JOGL). I want to display a 3D cube in JOGL.
I have vertex array information with me.
double vertices[]= {
0 0 0,
0 0 1,
0 1 0,
0 1 1,
1 0 0,
1 0 1,
1 1 0,
1 1 1,
};
I want to use glDrawArrays() to display it. Since I have display a model having a huge amount of vertices.
The display method is given below.
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glBegin(GL_TRIANGLE_STRIP);
gl.glEnd();
}
I need to use GL_TRIANGLES or GL_TRIANGLE_STRIP only and not GL_QUADS.
If anyone knows how to use glDrawArrays(); in JOGL please help me. I want JOGL syntax and not opengl.
If you want to use glDrawArrays(); then you have to create a VBO (Vertex Buffer Objects) or a VA (Vertex Arrays). If you're after speed, then choose VBO, though they require some extra lines of code to be made!
The best way I think I can explain how to create a VBO to you, is by giving you an example!
VBO Example
Here is a little example of a VBO storing Vertices and Colors for a Triangle and rendering it and also how to delete it!
Creating the VBO
This is the code where you create the actual Vertex and Color Buffer and bind them to the VBO.
int vertices = 3;
int vertex_size = 3; // X, Y, Z,
int color_size = 3; // R, G, B,
FloatBuffer vertex_data = BufferUtils.createFloatBuffer(vertices * vertex_size);
vertex_data.put(new float[] { -1f, -1f, 0f, });
vertex_data.put(new float[] { 1f, -1f, 0f, });
vertex_data.put(new float[] { 1f, 1f, 0f, });
vertex_data.flip();
FloatBuffer color_data = BufferUtils.createFloatBuffer(vertices * color_size);
color_data.put(new float[] { 1f, 0f, 0f, });
color_data.put(new float[] { 0f, 1f, 0f, });
color_data.put(new float[] { 0f, 0f, 1f, });
color_data.flip();
int vbo_vertex_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
int vbo_color_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glBufferData(GL_ARRAY_BUFFER, color_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
You can of course add more Vertices and Colors to the vertex_data and color_data if you want to! But always remember that the amount of vertex data, need to match with the amount of color data and vice versa!
Important: Only create the VBO(s) once, and only update them when necessary! Don't create them for each frame, since them you will end up with a frame-rate worse than when using immediate mode for rendering!
Rendering the VBO
This is the code you need to call, to render the VBO.
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);
glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glColorPointer(color_size, GL_FLOAT, 0, 0l);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, vertices);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
Deleting the VBO
Then when you're done with the VBO and you don't need it anymore, you can delete it by doing the following.
glDeleteBuffers(vbo_vertex_handle);
glDeleteBuffers(vbo_color_handle);

Java LWJGL 2D VBO's Slow FPS Performance

a friend and I are currently working on some LWJGL 2D related things. I was working on VBOs and was able to get it to work. Now when using this to draw tiles, they work. however, my FPS drops significantly. Perhaps I'm doing something wrong.
Here's my code.
public void drawTextureRect(float x, float y, float width, float height,
String textureName) {
// Bind the texture to draw
texture = loadTexture(textureName);
texture.bind();
// Set triangle vertex data
FloatBuffer vertices = BufferUtils.createFloatBuffer(6);
vertices.put(new float[] { x, y, x + width, y, x, height + y });
// Set texture coordinates
FloatBuffer textcoord = BufferUtils.createFloatBuffer(6);
textcoord.put(new float[] { 0, 0, 1, 0, 0, 1 });
// Allow OpenGL to interpret the Text Coordinates & Vertex Data
textcoord.flip();
vertices.flip();
int VertexHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, VertexHandle);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
int TextureHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, TextureHandle);
glBufferData(GL_ARRAY_BUFFER, textcoord, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VertexHandle);
glVertexPointer(2, GL_FLOAT, 0, 0L);
glBindBuffer(GL_ARRAY_BUFFER, TextureHandle);
glTexCoordPointer(2, GL_FLOAT, 0, 0L);
// Enable Vertex and Texture Arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Draw Triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
// Unable Vertex and Textures
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
/* SECOND TRIANGLE */
// Set Second Triangle Coordinates
FloatBuffer vertices2 = BufferUtils.createFloatBuffer(6);
vertices2.put(new float[] { x + width, y + height, x, height + y,
x + width, y });
// Set Second Texture Coordinates
FloatBuffer textcoord2 = BufferUtils.createFloatBuffer(6);
textcoord2.put(new float[] { 1, 1, 0, 1, 1, 0 });
// Allow OpenGl to interpret the Text Coordinates & Vertex Data
textcoord2.flip();
vertices2.flip();
int VertexHandle2 = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, VertexHandle2);
glBufferData(GL_ARRAY_BUFFER, vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
int TexCord = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, TexCord);
glBufferData(GL_ARRAY_BUFFER, textcoord2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VertexHandle2);
glVertexPointer(2, GL_FLOAT, 0, 0L);
glBindBuffer(GL_ARRAY_BUFFER, TexCord);
glTexCoordPointer(2, GL_FLOAT, 0, 0L);
// Enable Vertex and Texture Arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Draw Triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
// Unable Vertex and Textures
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDeleteBuffers(TextureHandle);
glDeleteBuffers(TexCord);
glDeleteBuffers(VertexHandle);
glDeleteBuffers(VertexHandle2);
}`

Categories

Resources