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
Related
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);
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);
First, I'll start with my code because I've identified which block is causing the issue.
// init
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glEnable(GL11.GL_TEXTURE_2D);
// BEGINNING OF OFFENDING CODE
BufferedImage image = ImageIO.read(new File("res/button.png"));
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
IntBuffer buffer = BufferUtils.createIntBuffer(pixels.length);
for (int pixel : pixels)
buffer.put(pixel);
buffer.flip();
int button = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
//Setup wrap mode
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
// END OF OFFENDING CODE
This is what things are supposed to look like without the textured quad.
This is what happens when I render with the offending code (with the textured quad).
This is what happens when I render with the offending code (without the textured quad).
For reference, this is the texture
I can't seem to figure out which GL11 call is affecting the rest of the Display and why it would be affecting the rest of the display. From what I understand, all of the calls that follow GL11.glBindTexture are limited to the bound texture, aren't they?
Edit: Additional Rendering Code
private static void renderQuad(int x, int y, int width, int height) {
GL11.glPushMatrix();
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(x, y);
GL11.glVertex2f(x + width, y);
GL11.glVertex2f(x + width, y + height);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
}
The method used for the red quads.
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glColor3f(0.5f,0.5f,1.0f);
renderQuad(0, 0, 800, 600);
// render action bar
GL11.glColor3f(0.2f,0.2f,1.0f);
renderQuad(0, 0, 800, 200);
GL11.glColor3f(1.0f,0.0f,0.0f);
renderQuad(50, 50, 100, 60);
renderQuad(200, 50, 100, 60);
// render textured quad
GL11.glPushMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(0.0,1.0);
GL11.glVertex2f(x, y);
GL11.glTexCoord2d(1.0,1.0);
GL11.glVertex2f(x + width, y);
GL11.glTexCoord2d(1.0,0.0);
GL11.glVertex2f(x + width, y + height);
GL11.glTexCoord2d(0.0,0.0);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
First of all, I think there's a problem with your texture loading. I believe the order of the bytes is reversed or something similar, which is why you get the red on black. Here's a working load-texture-from-BufferedImage example taken from my own code:
BufferedImage image = ImageIO.read(new File("<file path>.png"));
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
for(int y = 0; y < image.getHeight(); y++){
for(int x = 0; x < image.getWidth(); x++){
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
buffer.put((byte) (pixel & 0xFF)); // Blue component
buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA
}
}
buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS
// You now have a ByteBuffer filled with the color data of each pixel.
// Now just create a texture ID and bind it. Then you can load it using
// whatever OpenGL method you want, for example:
int textureID = GL11.glGenTextures(); //Generate texture ID
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID); //Bind texture ID
//Setup wrap mode
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
//Setup texture scaling filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
//Send texel data to OpenGL
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
Now, to the actual rendering problem:
For OpenGL, GL_TEXTURE_2D must be enabled or disabled depending on whether or not the polygon you are drawing is textured. If you do not supply texture coordinates for each vertex, then the last texture coords call still holds and is used for each vertex. So, you'll get a quad using one pixel's worth of texture. This is what's causing the black quads - it's taking from one pixel from a corner of your improperly loaded texture. So, your fixed rendering code:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(0.5f,0.5f,1.0f);
renderQuad(0, 0, 800, 600);
// render action bar
GL11.glColor3f(0.2f,0.2f,1.0f);
renderQuad(0, 0, 800, 200);
GL11.glColor3f(1.0f,0.0f,0.0f);
renderQuad(50, 50, 100, 60);
renderQuad(200, 50, 100, 60);
GL11.glEnable(GL11.GL_TEXTURE_2D);
// render textured quad
GL11.glColor3f(1.0f, 1.0f, 1.0f);
GL11.glPushMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(0.0,1.0);
GL11.glVertex2f(x, y);
GL11.glTexCoord2d(1.0,1.0);
GL11.glVertex2f(x + width, y);
GL11.glTexCoord2d(1.0,0.0);
GL11.glVertex2f(x + width, y + height);
GL11.glTexCoord2d(0.0,0.0);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
On a side note, you can use simply glEnable() instead of GL11.glEnable() if you do:
import static org.lwjgl.opengl.GL11.*;
instead of simply
import org.lwjgl.opengl.GL11;
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);
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);
}`