LWJGL 3 not rendering anything - java
I can create the window, but I cannot render anything. Here's my code:
LWJGLTutorial.java:
package core;
import logger.Logger;
import model.ModelLoader;
import model.RawModel;
import org.lwjgl.Version;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;
import java.nio.IntBuffer;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
// Main class
public class LWJGLTutorial {
// The window
private long window;
// The game
private void run() {
// Create logger
Logger logger = new Logger("MAIN");
// Validate LWJGL installation
logger.log("LWJGL Version: " + Version.getVersion());
// Set a error callback
GLFWErrorCallback.createPrint(System.err).set();
// Initialize and configure GLFW
if(!glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
logger.log("Initialized GLFW");
// Create window
window = glfwCreateWindow(800, 600, "LWJGL Tutorial", NULL, NULL);
if(window == NULL)
throw new RuntimeException("Failed to create window");
logger.log("Created window");
// Set a key callback
glfwSetKeyCallback(window, new GLFWKeyCallback() {
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
});
// Set a framebuffer size callback
glfwSetFramebufferSizeCallback(window, new GLFWFramebufferSizeCallback() {
#Override
public void invoke(long window, int width, int height) {
glViewport(0, 0, width, height);
}
});
logger.log("Callbacks set");
// Get the thread stack and push a new frame
try(MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1);
IntBuffer pHeight = stack.mallocInt(1);
glfwGetWindowSize(window, pWidth, pHeight);
GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidMode.width() - pWidth.get(0)) / 2, (vidMode.height() - pHeight.get(0)) / 2);
}
// Make OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Show window
glfwShowWindow(window);
// This line is critical for LWJGL's interoperation with GLFW's OpenGL context
GL.createCapabilities();
float[] vertices = {
// Left bottom triangle
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
// Right top triangle
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f
};
RawModel model = ModelLoader.load(vertices);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Render loop
while(!glfwWindowShouldClose(window)) {
// Set clear color
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
// Clear framebuffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Render models
Renderer.render(model);
// Swap color buffer
glfwSwapBuffers(window);
// Poll IO events
glfwPollEvents();
}
// Clean up
logger.log("Clean up...");
ModelLoader.cleanUp();
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
// Terminate GLFW and free error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
logger.log("Normal exit");
}
public static void main(String[] args) {
new LWJGLTutorial().run();
}
}
ModelLoader.java:
package model;
import org.lwjgl.BufferUtils;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import static org.lwjgl.opengl.GL30.*;
// Loads data into a RawModel
public class ModelLoader {
// A list of VAOs
private static List<Integer> VAOs = new ArrayList<>();
// A list of VBOs
private static List<Integer> VBOs = new ArrayList<>();
// Load data into a RawModel
public static RawModel load(float[] data) {
int vao = createVAO();
int vbo = createVBO();
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
FloatBuffer buffer = storeDataInFloatBuffer(data);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
return new RawModel(vao, data.length / 3);
}
// Deletes all created VAO and VBO
public static void cleanUp() {
for(int VAO : VAOs)
glDeleteVertexArrays(VAO);
for(int VBO : VBOs)
glDeleteBuffers(VBO);
}
// Generates a new VAO and stores it into the VAO list
private static int createVAO() {
int vao = glGenVertexArrays();
VAOs.add(vao);
return vao;
}
// Generates a new VBO and stores it into the VBO list
private static int createVBO() {
int vbo = glGenBuffers();
VBOs.add(vbo);
return vbo;
}
// Convert data into FloatBuffer
private static FloatBuffer storeDataInFloatBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
Renderer.java:
package core;
import model.RawModel;
import static org.lwjgl.opengl.GL30.*;
// Renderer that render stuff onto the screen
public class Renderer {
// Render a RawModel
public static void render(RawModel model) {
glBindVertexArray(model.getVAO());
glDrawArrays(GL_TRIANGLES, 0, model.getVertexCount());
}
}
RawModel.java:
package model;
import lombok.Getter;
// Represents a model that can be rendered
public class RawModel {
// VAO
#Getter
private int VAO;
// Number of vertices
#Getter
private int vertexCount;
public RawModel(int VAO, int vertexCount) {
this.VAO = VAO;
this.vertexCount = vertexCount;
}
}
I should be able to render a rectangle, but nothing is showing. I knew that it is not the problem with lombok, and I suspect that something went wrong in ModelLoader.java or Renderer.java. What is wrong with my code?
I don't see a shader created or being used in your code. A shader is what essentially renders the program. Do you have one?
Related
How to use VAOs and VBOs to render triangles in LWJGL3? - erroneous code included
I've been trying to resolve this problem for the past three days, but in vain. Therefore, I'd be very grateful for any help. I am currently learning how to draw triangles with VBOs and VAOs, so all of the code is included in one single "test" class. package quad; import java.nio.FloatBuffer; import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; import static org.lwjgl.system.MemoryUtil.*; import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.GL_FALSE; import static org.lwjgl.opengl.GL11.GL_TRUE; import static org.lwjgl.opengl.GL.*; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL15.*; import static org.lwjgl.opengl.GL20.*; import static org.lwjgl.opengl.GL30.*; public class Quad { private long window; private final String WINDOW_TITLE = "The Quad: glDrawArrays"; private final int WIDTH = 1920; private final int HEIGHT = 1080; // Quad variables private int vaoId = 0; private int vboId = 0; private int vertexCount = 0; private boolean running = false; public static void main(String[] args) { new Quad().start(); } public void start() { running = true; setupOpenGL(); setupQuad(); while (running) { loopCycle(); update(); if(glfwWindowShouldClose(window)) { running = false; } } destroyOpenGL(); } public void setupOpenGL() { if(!glfwInit()) { throw new IllegalStateException("Unable to initialize GLFW!"); } glfwDefaultWindowHints(); glfwWindowHint(GLFW_VISIBLE, GL_FALSE); glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); window = glfwCreateWindow(WIDTH, HEIGHT, WINDOW_TITLE, NULL, NULL); if (window == NULL) { throw new RuntimeException("Cannot create window!"); } glfwMakeContextCurrent(window); GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); glfwSetWindowPos(window, (vidmode.width() - WIDTH) / 2, (vidmode.height() - HEIGHT) / 2); glfwShowWindow(window); GL.createCapabilities(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); } public void setupQuad() { float[] vertices = { // Left bottom triangle -0.5f, 0.5f, 0f, -0.5f, -0.5f, 0f, 0.5f, -0.5f, 0f, // Right top triangle 0.5f, -0.5f, 0f, 0.5f, 0.5f, 0f, -0.5f, 0.5f, 0f }; FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length); verticesBuffer.put(vertices); verticesBuffer.flip(); vertexCount = 6; // Create a new Vertex Array Object in memory and select it (bind) // A VAO can have up to 16 attributes (VBO's) assigned to it by default vaoId = glGenVertexArrays(); glBindVertexArray(vaoId); // Create a new Vertex Buffer Object in memory and select it (bind) // A VBO is a collection of Vectors which in this case resemble the location of each vertex. vboId = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, vboId); glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW); // Put the VBO in the attributes list at index 0 glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); // Deselect (bind to 0) the VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // Deselect (bind to 0) the VAO glBindVertexArray(0); } public void loopCycle() { glClear(GL_COLOR_BUFFER_BIT); // Bind to the VAO that has all the information about the quad vertices glBindVertexArray(vaoId); glEnableVertexAttribArray(0); // Draw the vertices glDrawArrays(GL_TRIANGLES, 0, vertexCount); // Put everything back to default (deselect) glDisableVertexAttribArray(0); glBindVertexArray(0); } public void destroyOpenGL() { // Disable the VBO index from the VAO attributes list glDisableVertexAttribArray(0); // Delete the VBO glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(vboId); // Delete the VAO glBindVertexArray(0); glDeleteVertexArrays(vaoId); glfwDestroyWindow(window); glfwTerminate(); } public void update() { glfwSwapBuffers(window); glfwPollEvents(); } } Note: I've modernised this tutorial code example so LWJGL3 is used (none of the old Displays etc). Everything functions correctly at the first glance, but when the code is run, only a window with black colour (which is set by glClearColor(0.0f, 0.0f, 0.0f, 0.0f) inside the setupOpengl() method. Why are the quads not showing up?
JavaVM crashing when drawing using OpenGL
I've got the folowing code: package test.opengl; import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL30; import com.badlogic.gdx.utils.BufferUtils; import java.io.IOException; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.file.Files; import java.nio.file.Paths; import static com.badlogic.gdx.graphics.GL20.*; public class GLClass extends ApplicationAdapter { private int shaderProgram; private GL30 gl; FloatBuffer vertices; IntBuffer vao = BufferUtils.newIntBuffer(1); IntBuffer vbo = BufferUtils.newIntBuffer(1); #Override public void create() { gl = Gdx.gl30; compileShaders(); vertices = BufferUtils.newFloatBuffer(9); vertices.put(new float[] { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f }); gl.glEnable(GL_DEPTH_TEST); gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); gl.glGenVertexArrays(1, vao); gl.glGenBuffers(1, vbo); gl.glBindVertexArray(vao.get(0)); gl.glBindBuffer(GL_ARRAY_BUFFER, vbo.get(0)); gl.glBufferData(GL_ARRAY_BUFFER, 9, vertices, GL_STATIC_DRAW); gl.glVertexAttribPointer(0, 3, GL_FLOAT, false, 3, 0); gl.glEnableVertexAttribArray(0); gl.glBindVertexArray(0); } #Override public void render() { gl.glClearColor(0.2f, 0.2f, 0.2f, 1); gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl.glUseProgram(shaderProgram); gl.glBindVertexArray(vao.get(0)); gl.glDrawArrays(GL_TRIANGLES, 0, 3); gl.glBindVertexArray(0); int err = gl.glGetError(); if (err != 0) System.err.println("ERROR: " + err); } #Override public void resize(int width, int height) { gl.glViewport(0, 0, width, height); } private void compileShaders() { String vsSource; String fsSource; try { vsSource = new String(Files.readAllBytes(Paths.get("shaders/shader.vert"))); fsSource = new String(Files.readAllBytes(Paths.get("shaders/shader.frag"))); } catch (IOException e) { throw new RuntimeException(e); } shaderProgram = gl.glCreateProgram(); int vertexShader = gl.glCreateShader(GL_VERTEX_SHADER); gl.glShaderSource(vertexShader, vsSource); gl.glCompileShader(vertexShader); System.err.println(gl.glGetShaderInfoLog(vertexShader)); gl.glAttachShader(shaderProgram, vertexShader); int fragmentShader = gl.glCreateShader(GL_FRAGMENT_SHADER); gl.glShaderSource(fragmentShader, fsSource); gl.glCompileShader(fragmentShader); System.err.println(gl.glGetShaderInfoLog(fragmentShader)); gl.glAttachShader(shaderProgram, fragmentShader); gl.glLinkProgram(shaderProgram); gl.glDeleteShader(vertexShader); gl.glDeleteShader(fragmentShader); } } The code for shader.vert: #version 330 core layout (location = 0) in vec3 position; void main() { gl_Position = vec4(position.x, position.y, position.z, 1.0); } The code for shader.frag: #version 330 out vec4 out_Color; void main() { out_Color = vec4(1.0f, 0.5f, 0.2f, 1.0f); } It is running on desktop and the program crashes as soon as the first call of render() is completed, without a stacktrace and a segfault log. config.useGL30 is set to true. Why is it crashing? Am I doing anything wrong?
Testing out some LWJGL OpenGL, won't make box. What should I do?
Had this working on OpenGL ES 1.0 & 2.0. Goal: Make a box, then display it Won't work with LWJGL on Win 7. Loads a green box (as it should), and then starts to display a bunch of really thick white lines that won't stay as a box. There is a lot of flickering. Here is a picture. Here is the code for windows. Main.java package play.box; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.lwjgl.opengl.GL11; public class Main { public static final boolean VSYNC = true; public static final int WIDTH = 800; public static final int HEIGHT = 600; public static final boolean FULLSCREEN = false; protected boolean running = false; public static void main(String[] args) { try { start(); } catch (LWJGLException e) { e.printStackTrace(); } } public static void start() throws LWJGLException { Display.setTitle("Display example"); Display.setResizable(false); Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); Display.setVSyncEnabled(VSYNC); Display.setFullscreen(FULLSCREEN); Display.create(); // Setup OpenGL GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); GL11.glOrtho(-3, 3, -2, 2, -1, 1); GL11.glMatrixMode(GL11.GL_MODELVIEW); new Renderer().run(); } } Renderer.java package play.box; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; public class Renderer implements Runnable { public Renderer() { } #Override public void run() { while(!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT); GL11.glClearColor(0.0f, 0.5f, 0.0f, 1.0f); // Rendering // /*GL11.glBegin(GL11.GL_TRIANGLES); GL11.glColor3f(1.0f, 0.0f, 0.0f); GL11.glVertex2f(0.0f, 1.0f); GL11.glColor3f(1.0f, 0.0f, 0.0f); GL11.glVertex2f(1.0f, 1.0f); GL11.glColor3f(1.0f, 0.0f, 0.0f); GL11.glVertex2f(1.0f, -1.0f); GL11.glEnd();*/ Box box = new Box(); box.draw(); // End of Rendering // Display.update(); try { Thread.sleep(1000); } catch(Exception e) { e.printStackTrace(); } } } } Box.java package play.box; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import org.lwjgl.opengl.GL11; public class Box { private float verticies[] = { -1.0f, 1.0f, // Left Top (0) -1.0f, -1.0f, // Left Bottom (1) 1.0f, -1.0f, // Right Bottom (2) 1.0f, 1.0f // Right Top (4) }; private short indicies[] = { 0, 1, 2, 2, 3, 0 }; private FloatBuffer vertBuff; private ShortBuffer indexBuff; public Box() { this.setupBuffers(); } private void setupBuffers() { ByteBuffer bBuff = ByteBuffer.allocateDirect(this.verticies.length * 4); bBuff.order(ByteOrder.nativeOrder()); this.vertBuff = bBuff.asFloatBuffer(); this.vertBuff.put(this.verticies); this.vertBuff.position(0); ByteBuffer pbBuff = ByteBuffer.allocateDirect(this.indicies.length * 2); pbBuff.order(ByteOrder.nativeOrder()); this.indexBuff = pbBuff.asShortBuffer(); this.indexBuff.put(this.indicies); this.indexBuff.position(0); } public void draw() { GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY); GL11.glVertexPointer(2, GL11.GL_FLOAT, this.vertBuff); GL11.glDrawElements(GL11.GL_TRIANGLES, this.indexBuff); GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY); } } Updated Code: package play.box; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; public class Box { private float verticies[] = { -1.0f, 1.0f, // Left Top (0) -1.0f, -1.0f, // Left Bottom (1) 1.0f, -1.0f, // Right Bottom (2) 1.0f, 1.0f // Right Top (4) }; private short indicies[] = { 0, 1, 2, 2, 3, 0 }; private FloatBuffer vertBuff; private ShortBuffer indexBuff; private int vbo_handle; private int ibo_handle; private int vao_handle; private String vShaderStr = "attribute vec4 vPosition; \n" + "void main() { \n" + " gl_Position = vPosition;\n" + "} \n"; private String fShaderStr = "precision mediump float; \n" + "void main() { \n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" + "} \n"; private int vertexShader; private int fragmentShader; private int programObject; public Box() { } public void create() { ByteBuffer bBuff = ByteBuffer.allocateDirect(this.verticies.length * 4); bBuff.order(ByteOrder.nativeOrder()); this.vertBuff = bBuff.asFloatBuffer(); this.vertBuff.put(this.verticies); //this.vertBuff.flip(); this.vertBuff.position(0); ByteBuffer pbBuff = ByteBuffer.allocateDirect(this.indicies.length * 2); pbBuff.order(ByteOrder.nativeOrder()); this.indexBuff = pbBuff.asShortBuffer(); this.indexBuff.put(this.indicies); //this.indexBuff.flip(); this.indexBuff.position(0); // Create VBO this.vbo_handle = GL15.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.vbo_handle); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, this.vertBuff, GL15.GL_DYNAMIC_DRAW); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); // Create IBO this.ibo_handle = GL15.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, this.ibo_handle); GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, this.indexBuff, GL15.GL_DYNAMIC_DRAW); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); // Create VAO this.vao_handle = GL30.glGenVertexArrays(); GL30.glBindVertexArray(vao_handle); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo_handle); GL20.glEnableVertexAttribArray(0); GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo_handle); GL30.glBindVertexArray(0); // Setup Shaders this.vertexShader = this.loadShader(GL20.GL_VERTEX_SHADER, this.vShaderStr); this.fragmentShader = this.loadShader(GL20.GL_FRAGMENT_SHADER, this.fShaderStr); // Setup Program int program = GL20.glCreateProgram(); if(program == 0) { return; } GL20.glAttachShader(program, this.vertexShader); GL20.glAttachShader(program, this.fragmentShader); GL20.glBindAttribLocation(program, 0, "vPosition"); GL20.glLinkProgram(program); if(GL20.glGetProgrami(program, GL20.GL_LINK_STATUS) == 0) { System.out.println("Error Creating Program: " + GL20.glGetProgramInfoLog(program, Integer.MAX_VALUE)); GL20.glDeleteProgram(program); return; } this.programObject = program; } public void draw() { this.create(); GL20.glUseProgram(this.programObject); GL30.glBindVertexArray(vao_handle); GL11.glDrawElements(GL11.GL_TRIANGLES, 2, GL11.GL_FLOAT, 0); GL30.glBindVertexArray(0); this.dispose(); } public void draw(boolean useVAO) { if(useVAO) { this.draw(); } else { this.create(); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.vbo_handle); GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0L); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, this.ibo_handle); GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY); GL11.glDrawElements(GL11.GL_TRIANGLES, this.indicies.length, GL11.GL_UNSIGNED_SHORT, 0L); GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY); this.dispose(); } } public void dispose() { GL30.glDeleteVertexArrays(vao_handle); GL30.glDeleteVertexArrays(vbo_handle); GL30.glDeleteVertexArrays(ibo_handle); this.vao_handle = -1; this.vbo_handle = -1; this.ibo_handle = -1; } private int loadShader(int type, String shaderSrc) { int shader; shader = GL20.glCreateShader(type); if(shader == 0) { return 0; } GL20.glShaderSource(shader, shaderSrc); GL20.glCompileShader(shader); if(GL20.glGetShaderi(shader, GL20.GL_COMPILE_STATUS) == 0) { System.out.println("Error Loading Shader: " + GL20.glGetShaderInfoLog(shader, Integer.MAX_VALUE)); GL20.glDeleteShader(shader); return 0; } return shader; } }
Instead of just showing you what you asked for in the comments, I will demonstrate how you create, render and dispose a VAO using a VBO and IBO. VAO <=> Vertex Array Object VBO <=> Vertex Buffer Object IBO <=> Index Buffer Object Creating VAO, VBO & IBO The vao_handle, vbo_handle and ibo_handle is 3 integers containing the id/handle, these 3 variables are used in the whole following code. vbo_data <=> FloatBuffer containing the vertices ibo_data <=> IntBuffer containing the indices The two above variables are used in the following code. // Creating the VBO vbo_handle = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, vbo_handle); glBufferData(GL_ARRAY_BUFFER, vbo_data, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // Creating the IBO ibo_handle = glGenBuffers(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_handle ); glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibo_data, GL_DYNAMIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Creating the VAO vao_handle = glGenVertexArrays(); glBindVertexArray(vao_handle); glBindBuffer(GL_ARRAY_BUFFER, vbo_handle); glEnableVertexAttribArray(INDEX); // Place your own INDEX value in the parenthesis glVertexAttribPointer(INDEX, SIZE, TYPE, NORMALIZED, STRIDE, OFFSET); // Replace all the VARIABLES with the values which fit to your VAO, VBO and IBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_handle); glBindVertexArray(0); /* * Remember that the INDEX given in the * glEnableVertexAttribArray() and in * glVertexAttribPointer() is the same * INDEX used in Shaders (GLSL) * * If the INDEX is 0 then in GLSL it * should look like this * GLSL: layout(location = 0) in vec3 position; * * ^ we can ignore this if you aren't * using Shaders, though keep it in mind * since we might need it in the future */ Rendering VAO glBindVertexArray(vao_handle); glDrawElements(MODE, SIZE, TYPE, OFFSET); // Again replace the variables, so it fits to your VAO, VBO and IBO glBindVertexArray(0); Dispose VAO, VBO & IBO This is how you delete the different buffers, which is a good thing to do, when you close the program or if at some point you don't need them anymore. glDeleteVertexArrays(vao_handle); // Deletes the VAO glDeleteBuffers(vbo_handle); // Deletes the VBO glDeleteBuffers(ibo_handle); // Deletes the IBO vao_handle = -1; vbo_handle = -1; ibo_handle = -1;
lwjgl glDrawArrays gives Invalid operation error
When learning how to use OpenGL 3.2 through lwjgl, i followed the tutorial at here. I keep getting invalid operation error on the method call glDrawArrays. This error even occurs if I copy the source code from the tutorial. My operating system is Mac OS X 10.8.3 and after a quick search do not turn up anything. My Code(Adapted code from tutorial): render method: public void render() { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); // Bind to the VAO that has all the information about the quad vertices GL30.glBindVertexArray(vaoId); GL20.glEnableVertexAttribArray(0); this.exitOnGLError("Error before DrawArrays"); // Draw the vertices GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCount); this.exitOnGLError("Error in DrawArrays"); // Put everything back to default (deselect) GL20.glDisableVertexAttribArray(0); GL30.glBindVertexArray(0); this.exitOnGLError("Error in render"); } Rest of code: import java.nio.FloatBuffer; import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.ContextAttribs; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.PixelFormat; import org.lwjgl.util.glu.GLU; public class TestOpenGL { // Entry point for the application public static void main(String[] args) { new TestOpenGL(); } // Setup variables private final String WINDOW_TITLE = "The Quad: glDrawArrays"; private final int WIDTH = 320; private final int HEIGHT = 240; // Quad variables private int vaoId = 0; private int vboId = 0; private int vertexCount = 0; public TestOpenGL() { // Initialize OpenGL (Display) this.setupOpenGL(); this.setupQuad(); while (!Display.isCloseRequested()) { // Do a single loop (logic/render) render(); // Force a maximum FPS of about 60 Display.sync(60); // Let the CPU synchronize with the GPU if GPU is tagging behind Display.update(); } // Destroy OpenGL (Display) this.destroyOpenGL(); } public void setupOpenGL() { // Setup an OpenGL context with API version 3.2 try { PixelFormat pixelFormat = new PixelFormat(); ContextAttribs contextAtrributes = new ContextAttribs(3, 2) .withForwardCompatible(true) .withProfileCore(true); Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); Display.setTitle(WINDOW_TITLE); Display.create(pixelFormat, contextAtrributes); System.out.println(GL11.glGetString(GL11.GL_VERSION)); GL11.glViewport(0, 0, WIDTH, HEIGHT); } catch (LWJGLException e) { e.printStackTrace(); System.exit(-1); } // Setup an XNA like background color GL11.glClearColor(0.4f, 0.6f, 0.9f, 0f); // Map the internal OpenGL coordinate system to the entire screen GL11.glViewport(0, 0, WIDTH, HEIGHT); this.exitOnGLError("Error in setupOpenGL"); } public void setupQuad() { // OpenGL expects vertices to be defined counter clockwise by default float[] vertices = { // Left bottom triangle -0.5f, 0.5f, 0f, -0.5f, -0.5f, 0f, 0.5f, -0.5f, 0f, // Right top triangle 0.5f, -0.5f, 0f, 0.5f, 0.5f, 0f, -0.5f, 0.5f, 0f }; // Sending data to OpenGL requires the usage of (flipped) byte buffers FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length); verticesBuffer.put(vertices); verticesBuffer.flip(); vertexCount = 6; // Create a new Vertex Array Object in memory and select it (bind) // A VAO can have up to 16 attributes (VBO's) assigned to it by default vaoId = GL30.glGenVertexArrays(); GL30.glBindVertexArray(vaoId); // Create a new Vertex Buffer Object in memory and select it (bind) // A VBO is a collection of Vectors which in this case resemble the location of each vertex. vboId = GL15.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW); // Put the VBO in the attributes list at index 0 GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0); // Deselect (bind to 0) the VBO GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); // Deselect (bind to 0) the VAO GL30.glBindVertexArray(0); this.exitOnGLError("Error in setupQuad"); } public void destroyOpenGL() { // Disable the VBO index from the VAO attributes list GL20.glDisableVertexAttribArray(0); // Delete the VBO GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); GL15.glDeleteBuffers(vboId); // Delete the VAO GL30.glBindVertexArray(0); GL30.glDeleteVertexArrays(vaoId); Display.destroy(); } public void exitOnGLError(String errorMessage) { int errorValue = GL11.glGetError(); if (errorValue != GL11.GL_NO_ERROR) { String errorString = GLU.gluErrorString(errorValue); System.err.println("ERROR - " + errorMessage + ": " + errorString); if (Display.isCreated()) Display.destroy(); System.exit(-1); } } } The output is 3.2 INTEL-8.10.44 ERROR - Error in DrawArrays: Invalid operation
You're code appears not be to using shaders entirely. As you are requesting a forward compatible OpenGL context there is no support for the fixed function pipeline therefor shaders are neccessary. You will have to either use shaders to proccess your vertices or use a compatibility context in order to have OpenGl do you vertex and fragment processing.
OpenGL ES Object is Displaying Strangely / Distorted - Android
EDIT OK - I grabbed a device and..guess what...it displays correctly ? Does anyone know why this would be happening on the simulator only ? Thank you. I am trying to draw an object using glDrawElements on Android. I am using the code below to read in my vertice and indice data and then draw the object in my render method. I am testing this on the simulator rather than a real device. This is my scene object code : import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; import javax.microedition.khronos.opengles.GL10; public class SceneObject { public FloatBuffer mVertexBuffer; public FloatBuffer mTextureBuffer; public ShortBuffer indexBuffer; public FloatBuffer mMatriceBuffer; public FloatBuffer mPivotBuffer; public short[] indicesTest = {0,1,2,3,4,5,3,5,6,7,5,8,7,8,9,10,7,9,11,10,9,12,1,0,13,12,14,15,13,14,14,10,11,15,14,11,0,14,12,16,17,18,19,16,18,18,20,19,21,16,19,22,21,19,22,19,23,4,24,25,25,26,27,25,27,28,4,25,28,5,4,28,5,28,8,29,30,31,29,31,19,29,19,20,32,33,31,32,31,30,32,34,33,35,22,23,36,35,23,37,36,23,37,23,38,39,37,38,40,39,38,41,40,38,41,38,1,42,41,1,12,43,1,42,1,43,17,27,26,26,18,17,44,45,46,46,47,44,48,49,50,51,52,53,53,54,51,55,51,54,54,56,55,57,48,50,50,58,57,52,59,60,60,53,52,59,44,47,47,60,59,61,62,63,63,64,61,65,66,67,67,68,65,69,70,71,71,72,69,66,69,72,72,67,66,73,65,68,68,74,73,70,75,76,76,71,70,75,61,64,64,76,75,77,78,79,79,80,77,81,82,62,62,61,81,83,81,61,61,75,83,84,63,62,62,82,84,63,84,85,86,87,88,89,90,91,92,93,87,87,86,92,94,95,96,96,97,94,98,99,100,100,101,98,102,103,104,104,105,102,106,107,108,108,109,106,110,111,112,78,77,113,114,115,78,112,111,116,117,118,115,119,116,120,121,122,123,123,124,121,125,126,127,127,128,125,129,130,131,132,133,5,5,133,6,5,134,135,135,134,136,134,137,136,137,138,136,129,139,130,139,140,141,140,142,141,137,141,138,141,142,138,141,130,139,143,144,145,144,146,145,147,145,146,144,148,146,148,149,146,146,149,150,151,132,152,153,152,154,154,152,155,152,132,155,132,5,155,155,5,135,156,157,158,158,157,146,146,157,147,159,160,158,158,160,156,34,160,159,149,161,150,161,162,150,162,163,150,150,163,164,163,165,164,165,166,164,166,167,164,164,167,129,167,168,129,169,139,129,129,168,169,154,143,153,145,153,143,170,171,172,173,172,171,174,175,176,177,178,179,180,179,178,178,181,180,182,180,181,175,183,176,184,176,183,185,177,186,179,186,177,171,185,173,186,173,185,187,188,189,190,189,188,191,192,193,194,193,192,195,196,197,198,197,196,196,191,198,193,198,191,192,199,194,200,194,199,201,195,202,197,202,195,188,201,190,202,190,201,203,204,205,206,205,204,207,208,187,188,187,208,208,209,188,201,188,209,189,210,187,207,187,210,210,189,211,212,213,214,215,216,217,218,219,220,221,220,219,222,223,224,225,226,227,228,229,230,231,230,229,232,233,234,235,236,237,238,239,240,241,242,243,123,244,124,245,246,203,204,203,246,247,248,203,249,250,251,252,253,247,248,247,253,159,33,34,254,255,256,256,257,254,255,244,123,123,256,255,244,258,121,121,124,244,259,260,125,125,128,259}; public float[] verticeTest = {20360.8f,20679.5f,611.547f,24248.7f,13527f,1074.93f,24207.4f,23005.5f,1503.19f,9819.59f,14845.7f,8.81875f,11126.3f,13982.2f,32.0718f,8379.01f,17678.5f,0.00115749f,8379.01f,15141.6f,0.00111471f,12137.8f,17973.8f,60.0461f,14591.9f,14509.2f,164.113f,15621.5f,15846.6f,223.075f,15136.7f,18549.5f,194.186f,16918.2f,16705.3f,310.215f,21081.8f,15846.6f,687.576f,19789f,16705.3f,554.435f,18467.9f,19868.7f,433.258f,18354.3f,17001.2f,423.539f,14591.9f,7402.34f,164.113f,13930.5f,9087.62f,131.015f,13039.7f,9096.18f,92.3283f,19110.4f,-8011.43f,490.311f,12811.7f,7228.03f,83.5128f,15621.5f,6064.9f,223.074f,16918.2f,5206.21f,310.215f,21807.5f,-426.492f,768.658f,11221.5f,13854f,34.3347f,12150f,12649.6f,60.4329f,12811.7f,10964.3f,83.513f,13702.6f,10955.8f,120.472f,13930.5f,12823.9f,131.015f,12150f,5542.76f,60.4327f,11119f,4205.31f,31.902f,15341.7f,-15792.9f,206.155f,9819.59f,3346.62f,8.81857f,10735.6f,-21752.5f,23.5976f,8379.01f,3050.73f,0.000981022f,18354.3f,4910.32f,423.538f,19789f,5206.21f,554.434f,21081.8f,6064.9f,687.576f,23336.1f,6399.27f,954.364f,22106.6f,7402.34f,803.393f,22764f,9087.62f,882.485f,22990.5f,10955.8f,910.595f,22764f,12823.9f,882.485f,22106.6f,14509.2f,803.393f,24248.7f,8492.36f,-3249.03f,24207.4f,17415.3f,-3297.97f,24207.4f,23005.5f,1503.19f,24248.7f,13527f,1074.93f,12728.3f,-24463.4f,-4243.56f,15341.7f,-20827.5f,-4117.81f,15341.7f,-15792.9f,206.155f,19110.4f,-13046f,-3833.65f,21807.5f,-5461.09f,-3555.3f,21807.5f,-426.492f,768.658f,19110.4f,-8011.43f,490.311f,15341.7f,-20827.5f,-4117.81f,15341.7f,-15792.9f,206.155f,10735.6f,-26787.1f,-4300.36f,10735.6f,-21752.5f,23.5976f,23336.1f,1364.68f,-3369.59f,23336.1f,6399.27f,954.364f,24883.8f,8123.11f,-2819.08f,24859.5f,16025.8f,-2803.12f,24207.4f,17415.3f,-3297.97f,24248.7f,8492.36f,-3249.03f,13363.4f,-24832.7f,-3813.62f,15976.8f,-21196.8f,-3687.86f,15341.7f,-20827.5f,-4117.81f,12728.3f,-24463.4f,-4243.56f,19745.5f,-13415.3f,-3403.7f,22442.7f,-5830.35f,-3125.36f,21807.5f,-5461.09f,-3555.3f,19110.4f,-13046f,-3833.65f,10915.8f,-27847.5f,-3863.23f,10735.6f,-26787.1f,-4300.36f,23222.6f,-2518.03f,-3057.67f,23336.1f,1364.68f,-3369.59f,10301.8f,-40240.8f,-15469.8f,10482f,-40907.1f,-14694f,10915.8f,-27847.5f,-3863.23f,10735.6f,-26787.1f,-4300.36f,25648.8f,8121.58f,-2817.31f,25624.5f,16024.2f,-2801.34f,24056.1f,-2550.94f,-3019.36f,25678.7f,16560.2f,-2907.29f,25594.2f,17951.2f,-3237.71f,25624.5f,-88046.9f,-92182.7f,25678.7f,-87767f,-92508.6f,25678.7f,16560.2f,-2907.29f,25678.7f,16560.2f,-2907.29f,25624.5f,16024.2f,-2801.34f,25624.5f,-88046.9f,-92182.7f,25624.5f,-88413.1f,-92497.2f,25678.7f,-88133.2f,-92823.1f,24765.7f,-88413.1f,-92497.2f,24820f,-88133.2f,-92823.1f,25678.7f,-88133.2f,-92823.1f,25624.5f,-88413.1f,-92497.2f,24765.7f,-89895.8f,-93770.7f,24820f,-89615.9f,-94096.6f,24820f,-88133.2f,-92823.1f,24765.7f,-88413.1f,-92497.2f,25678.7f,-89596.5f,-94079.9f,25678.7f,-88133.2f,-92823.1f,24820f,-88133.2f,-92823.1f,24820f,-89615.9f,-94096.6f,23222.6f,-93458.9f,-81162.2f,24056.1f,-93491.8f,-81123.9f,24056.1f,-2550.94f,-3019.36f,23222.6f,-2518.03f,-3057.67f,10579.6f,-102089f,-68973.2f,10579f,-102925f,-68042.7f,10482f,-40907.1f,-14694f,10579.6f,-102089f,-68973.2f,10579f,-102925f,-68042.7f,10482f,-41291.8f,-14246f,10579f,-102925f,-68042.7f,10489f,-103571f,-67018.6f,10482f,-41713.9f,-13886.7f,10482f,-41291.8f,-14246f,10489f,-103571f,-67018.6f,8379.01f,-102145f,-69021.7f,10579.6f,-102089f,-68973.2f,10301.8f,-40240.8f,-15469.8f,8379.01f,-68082.6f,-39554.7f,8379.01f,-101057f,-70411.1f,10735.6f,-101057f,-70411.1f,10579.6f,-102089f,-68973.2f,8379.01f,-102145f,-69021.7f,-7490.7f,13527f,1074.93f,-3602.79f,20679.5f,611.547f,-7449.35f,23005.5f,1503.19f,5631.77f,13982.2f,32.0718f,6938.43f,14845.7f,8.81875f,4620.19f,17973.8f,60.0461f,2166.16f,14509.2f,164.113f,1136.48f,15846.6f,223.075f,1621.29f,18549.5f,194.186f,-160.178f,16705.3f,310.215f,-4323.73f,15846.6f,687.576f,-3030.97f,16705.3f,554.435f,-1709.92f,19868.7f,433.258f,-1596.32f,17001.2f,423.539f,2827.51f,9087.62f,131.015f,2166.16f,7402.34f,164.113f,3718.3f,9096.18f,92.3283f,-2352.36f,-8011.43f,490.311f,3946.3f,7228.03f,83.5128f,1136.48f,6064.9f,223.074f,-160.182f,5206.21f,310.215f,-5049.53f,-426.492f,768.658f,5536.51f,13854f,34.3347f,4608.07f,12649.6f,60.4329f,3946.3f,10964.3f,83.513f,3055.44f,10955.8f,120.472f,2827.51f,12823.9f,131.015f,5639.04f,4205.31f,31.902f,4608.07f,5542.76f,60.4327f,1416.3f,-15792.9f,206.155f,6022.45f,-21752.5f,23.5976f,6938.43f,3346.62f,8.81857f,-1596.32f,4910.32f,423.538f,-3030.97f,5206.21f,554.434f,-4323.73f,6064.9f,687.576f,-6578.08f,6399.27f,954.364f,-5348.56f,7402.34f,803.393f,-6006f,9087.62f,882.485f,-6232.44f,10955.8f,910.595f,-6006f,12823.9f,882.485f,-5348.57f,14509.2f,803.393f,-7449.35f,17415.3f,-3297.97f,-7490.7f,8492.36f,-3249.03f,-7449.35f,23005.5f,1503.19f,-7490.7f,13527f,1074.93f,1416.3f,-20827.5f,-4117.81f,4029.77f,-24463.4f,-4243.56f,1416.3f,-15792.9f,206.155f,-5049.53f,-5461.09f,-3555.3f,-2352.36f,-13046f,-3833.65f,-5049.53f,-426.492f,768.658f,-2352.36f,-8011.43f,490.311f,1416.3f,-20827.5f,-4117.81f,1416.3f,-15792.9f,206.155f,6022.45f,-26787.1f,-4300.36f,6022.45f,-21752.5f,23.5976f,-6578.08f,1364.68f,-3369.59f,-6578.08f,6399.27f,954.364f,-8101.47f,16025.8f,-2803.12f,-8125.81f,8123.11f,-2819.08f,-7449.35f,17415.3f,-3297.97f,-7490.7f,8492.36f,-3249.03f,781.19f,-21196.8f,-3687.86f,3394.66f,-24832.7f,-3813.62f,1416.3f,-20827.5f,-4117.81f,4029.77f,-24463.4f,-4243.56f,-5684.64f,-5830.35f,-3125.36f,-2987.47f,-13415.3f,-3403.7f,-5049.53f,-5461.09f,-3555.3f,-2352.36f,-13046f,-3833.65f,5842.26f,-27847.5f,-3863.23f,6022.45f,-26787.1f,-4300.36f,-6464.54f,-2518.03f,-3057.67f,-6578.08f,1364.68f,-3369.59f,6276.06f,-40907.1f,-14694f,6456.25f,-40240.8f,-15469.8f,5842.26f,-27847.5f,-3863.23f,6022.45f,-26787.1f,-4300.36f,-8866.45f,16024.2f,-2801.34f,-8890.79f,8121.58f,-2817.31f,-7298.12f,-2550.94f,-3019.36f,-8920.72f,16560.2f,-2907.29f,-8836.13f,17951.2f,-3237.71f,-8920.72f,-87767f,-92508.6f,-8866.45f,-88046.9f,-92182.7f,-8920.72f,16560.2f,-2907.29f,-8866.45f,16024.2f,-2801.34f,-8920.72f,16560.2f,-2907.29f,-8866.45f,-88046.9f,-92182.7f,-8920.72f,-88133.2f,-92823.1f,-8866.45f,-88413.1f,-92497.2f,-8920.72f,-87767f,-92508.6f,-8866.45f,-88046.9f,-92182.7f,-8061.98f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8866.45f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8061.98f,-89615.9f,-94096.6f,-8007.72f,-89895.8f,-93770.7f,-8061.98f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8920.72f,-89596.5f,-94079.9f,-8061.98f,-88133.2f,-92823.1f,-8061.98f,-89615.9f,-94096.6f,-8061.98f,-88133.2f,-92823.1f,-8920.72f,-89596.5f,-94079.9f,-7298.12f,-93491.8f,-81123.9f,-6464.54f,-93458.9f,-81162.2f,-7298.12f,-2550.94f,-3019.36f,-6464.54f,-2518.03f,-3057.67f,-7298.12f,-2550.94f,-3019.36f,-6464.54f,-93458.9f,-81162.2f,6456.25f,-40240.8f,-15469.8f,6179.01f,-102925f,-68042.7f,6178.41f,-102089f,-68973.2f,6276.06f,-41291.8f,-14246f,6179.01f,-102925f,-68042.7f,6179.01f,-102925f,-68042.7f,6276.06f,-40907.1f,-14694f,6179.01f,-102925f,-68042.7f,6276.06f,-41713.9f,-13886.7f,6269.01f,-103571f,-67018.6f,6022.45f,-21752.5f,23.5976f,6022.45f,-26787.1f,-4300.36f,10735.6f,-26787.1f,-4300.36f,10735.6f,-21752.5f,23.5976f,6178.41f,-102089f,-68973.2f,6178.41f,-102089f,-68973.2f,6022.45f,-101057f,-70411.1f }; public String objectName; public int triangleCount; public int verticeCount; public float[] vertices; public float[] normals; public float[] textures; public short[] indices; public float[] matrices; public float[] pivots; public float[] animations; public void awake() { ByteBuffer vbb = ByteBuffer.allocateDirect(verticeTest.length * 4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asFloatBuffer(); mVertexBuffer.put(verticeTest); mVertexBuffer.position(0); ByteBuffer tbb = ByteBuffer.allocateDirect(textures.length * 4); tbb.order(ByteOrder.nativeOrder()); mTextureBuffer = tbb.asFloatBuffer(); mTextureBuffer.put(textures); mTextureBuffer.position(0); //short has 2 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(indicesTest.length*2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indicesTest); indexBuffer.position(0); verticeCount = (triangleCount*3); } public void draw(GL10 gl) { System.out.println("Draw Method Called in Object"); gl.glEnable(GL10.GL_TEXTURE_2D); //workaround bug 3623 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); System.out.println("Triangle Vertice Count is "+verticeCount); int x = vertices.length; System.out.println("Rendering following number of vertices "+x); int y = indices.length; System.out.println("Rendering following number of indices "+y); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); } } And here is the code where I call the draw method : import java.nio.FloatBuffer; import java.util.ArrayList; import java.util.Iterator; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLSurfaceView; import android.opengl.GLU; class GLRenderer implements GLSurfaceView.Renderer { private static final String TAG = "GLRenderer"; private final Context context; private final GLCube cube = new GLCube(); private long startTime; private long fpsStartTime; private long numFrames; SceneObject drawObject; SceneObject object; //Used for object position and rotation. float zRotation; float xRotation; float yRotation; float kxRotation = 0.0f; float kyRotation = 0.0f; ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); boolean SEE_THRU = false; GLRenderer(Context context) { this.context = context; } public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Setup any OpenGL Options that are required. gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnable(GL10.GL_TEXTURE_2D); if (SEE_THRU) { gl.glDisable(GL10.GL_DEPTH_TEST); gl.glEnable(GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE); } //Optional - disable dither to boost peformance. //gl.glDisable(GL10.GL_DITHER); //Dithering enabled by default. //Turn on the lights. float lightAmbient[] = new float[] { 0.2f, 0.2f, 0.2f, 1}; float lightDiffuse[] = new float[] {1, 1, 1, 1}; float[] lightPos = new float[] {1 ,1 ,1 , 1}; gl.glEnable(GL10.GL_LIGHTING); gl.glEnable(GL10.GL_LIGHT0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0); //Specify which materials we should use. float matAmbient[] = new float[] {1, 1, 1, 1}; float matDiffuse[] = new float[] {1, 1, 1, 1}; gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0); } public void onSurfaceChanged(GL10 gl, int width, int height) { //Define the view frustrum gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); float ratio = (float)width/height; gl.glLoadIdentity(); //gl.glOrthof(0, 480f, 800f, 0, 0, 1); GLU.gluPerspective(gl, 45.0f, ratio, 1.0f, 100f); } public void onDrawFrame (GL10 gl) { //Defs for rotation of object. float kzRotation = 0.0f; kyRotation +=1.0f; kxRotation =280.0f; gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); SceneObject object = sceneObjects.get(13); //Get the object //Position the model. gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -30.0f); gl.glScalef(0.0001f, 0.0001f, 0.0001f); zRotation = kzRotation; xRotation = kxRotation; yRotation = kyRotation; gl.glRotatef(yRotation, 0.0f, 1.0f, 0.0f); gl.glRotatef(xRotation, 1.0f, 0.0f, 0.0f); gl.glRotatef(zRotation, 0.0f, 0.0f, 1.0f); object.draw(gl); } } } The problem is that the object is not displaying as it should, but instead looks warped and squashed. Can anyone spot what might be wrong ? EDIT - Changed the onSufaceChanged method as per Tim's answer below, however no improvement. I've added an image of how the object is rendering on Android and the same object rendering correct on the iPhone. The most noticeable problem is that the "legs" should be straight and not bend and overall the object should be much longer. I'm sure the vertices and indices in the code above are correct (they are exactly the same as the iPhone ones). In case it is relevant here is how I am setting up the surfaceview / view: public class SaxParserActivity extends Activity { /** Called when the activity is first created. */ ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.main); GLView view; view = new GLView(this, sceneObjects); //Pass down our sceneObjects into the view class. //view.sceneObjects = sceneObjects; setContentView(view); } } class GLView extends GLSurfaceView { private final GLRenderer renderer; ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); GLView(Context context, ArrayList<SceneObject> sceneObjects) { super (context); //Uncomment this to turn on error-checking and logging. //setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS); renderer = new GLRenderer(context); //Pass down our sceneObjects. renderer.sceneObjects = sceneObjects; setRenderer(renderer); } }
I'm a bit confused by what you're doing. Why do you wipe on the projection matrix in onDrawFrame, after setting it in onSurfaceChanged? You should set projection in onSurfaceChanged like so: public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); //make sure to reset before glOrthof gl.glOrthof(0, 320f, 480f, 0, 0, 1); } And then change back to modelview and don't disturb the projection matrix during onDrawFrame. You'll probably need to recalibrate your scale and translate in onDrawFrame as well after doing this.