LWJGL crashes on glDrawElements - java

I have run into this error and i have no Idea what it could be.
So iam initalizing GLFW, creating the Capability for OpenGL, loading the Shader and the VAO into VRAM.
I really have no Idea what it could be at this point.
public static void main(String[] args){
GLFWErrorCallback.createPrint(System.err).set();
if(!glfwInit()) {
assert false : "failed to inialize GLFW";
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
long windowID = glfwCreateWindow(800, 600, "title", NULL, NULL);
if(windowID == NULL) {
assert false : "Failed to create GLFW-Window";
}
glfwMakeContextCurrent(windowID);
glfwSwapInterval(0);
glfwShowWindow(windowID);
GL.createCapabilities();
Shader shader = new Shader(
FileReader.readRaw("assets/shaders/basicMesh.vs"),
FileReader.readRaw("assets/shaders/basicMesh.fs"));
int vaoID = glGenVertexArrays();
glBindVertexArray(vaoID);
int vbo = glGenBuffers();
glBindBuffer(GL_VERTEX_ARRAY, vbo);
glBufferData(GL_VERTEX_ARRAY, new float[] {
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f
}, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_VERTEX_ARRAY, 0);
int ebo = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, new int[] {
0,1,2,
2,3,0
}, GL_STATIC_DRAW);
glBindVertexArray(0);
while(!glfwWindowShouldClose(windowID)) {
glfwPollEvents();
glUseProgram(shader.getID());
glBindVertexArray(vaoID);
//crahes here!!!
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(windowID);
}
}
Shader code is pretty simple for the Moment. Just to answer any questions here is the Code.
basicMesh.vs
#version 420 core
layout(location=0) in vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}
basicMesh.fs
#version 420 core
out vec4 color;
void main(){
color = vec4(1.0f, 1.0f, 0.0f, 1.0f);
}

GL_VERTEX_ARRAY is not a valid buffer binding point for e.g. glBindBuffer. The reason why it crashes is because you enabled generic vertex attribute 0 without having specified any vertex data for that, since you bind to an illegal binding point. glVertexAttribPointer looks for a buffer bound to GL_ARRAY_BUFFER, not GL_VERTEX_ARRAY.
What you meant to bind to is not GL_VERTEX_ARRAY but GL_ARRAY_BUFFER.

Related

glVertexAttribPointer doesn't seem to work, but no errors

I have been using LWJGL 3 and a tutorial at LearnOpenGL.com in order to create a game engine. However, after following the tutorial, I have discovered that the use of glVertexAttribPointer is not working. It works when uploading vertex positions and indices, but when I try to upload color and texture coordinates, nothing's happening, and I'm just getting a white box. I have attached the source code of the render engine, main class, and shaders:
public class Mesh {
public float[] vertices;
public float[] colors;
public float[] textureCoords;
public int[] indices;
public Mesh(float[] vertices, float[] colors, float[] textureCoords, int[] indices) {
this.vertices = vertices;
this.colors = colors;
this.textureCoords = textureCoords;
this.indices = indices;
}
}
public class MasterRenderer {
private int vbo;
private int vao;
private int ebo;
private Mesh mesh;
private ShaderProgram program;
public void Init(Mesh mesh) {
this.mesh = mesh;
program = new ShaderProgram();
vao = GL30.glGenVertexArrays();
vbo = GL20.glGenBuffers();
ebo = GL20.glGenBuffers();
}
public void Render(Color clearColor) {
// Clear Screen
GL11.glClearColor(clearColor.getRed(), clearColor.getGreen(), clearColor.getBlue(), clearColor.getAlpha());
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// Bind vao
GL30.glBindVertexArray(vao);
// Bind Buffers
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.vertices, GL20.GL_STATIC_DRAW);
GL20.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, ebo);
GL20.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, mesh.indices, GL20.GL_STATIC_DRAW);
// Enable vertex attribPointers
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL20.glEnableVertexAttribArray(0);
// Handle Textures
Texture texture = Utils.LoadTexture("resources//textures//test.png");
// Uniforms
// Use Program
program.UseProgram();
// Draw the shape
GL20.glActiveTexture(GL20.GL_TEXTURE0);
GL20.glBindTexture(GL20.GL_TEXTURE_2D, texture.getId());
GL30.glBindVertexArray(vao);
GL20.glDrawElements(GL20.GL_TRIANGLES, 6, GL20.GL_UNSIGNED_INT, 0);
}
}
public class ShaderProgram {
public int programID;
public int vertexShaderID;
public int fragmentShaderID;
public ShaderProgram() {
programID = GL20.glCreateProgram();
try {
CompileVertexShader(Utils.LoadResource("resources/shaders/default/defaultShader.vs"));
CompileFragmentShader(Utils.LoadResource("resources/shaders/default/defaultShader.fs"));
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
if(GL20.glGetShaderi(vertexShaderID, GL20.GL_COMPILE_STATUS) == 0) {
Logger.LogErrorClose("Error compiling vertex shader code: " + GL20.glGetShaderInfoLog(vertexShaderID, 1024));
}
if(GL20.glGetShaderi(fragmentShaderID, GL20.GL_COMPILE_STATUS) == 0) {
Logger.LogErrorClose("Error compiling fragment shader code: " + GL20.glGetShaderInfoLog(fragmentShaderID, 1024));
}
GL20.glLinkProgram(programID);
} catch (Exception e) {
e.printStackTrace();
}
}
public void UseProgram() {
GL20.glUseProgram(programID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
}
public void CompileVertexShader(String shaderCode) {
vertexShaderID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexShaderID, shaderCode);
GL20.glCompileShader(vertexShaderID);
}
public void CompileFragmentShader(String shaderCode) {
fragmentShaderID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentShaderID, shaderCode);
GL20.glCompileShader(fragmentShaderID);
}
}
public class Texture {
private int id;
public Texture(int id){
this.id = id;
}
public int getId(){
return id;
}
}
public class FoodFight {
public static void main(String[] args) {
Logger.LogMessage("Running on LWJGL Version: " + Version.getVersion());
Window w = new Window();
long window = w.CreateWindow(640, 360, "Food Fight");
MasterRenderer renderer = new MasterRenderer();
float[] vertices = {
0.5f, 0.5f, 0f,
0.5f, -0.5f, 0f,
-0.5f, -0.5f, 0f,
-0.5f, 0.5f, 0f
};
float[] colors = {
1f, 0f, 0f,
0f, 1f, 0f,
0f, 0f, 1f,
1f, 1f, 0f
};
float[] textureCoords = {
1f, 1f,
1f, 0f,
0f, 0f,
0f, 1f
};
int[] indices = {
0, 1, 3,
1, 2, 3
};
Mesh m = new Mesh(vertices, colors, textureCoords, indices);
renderer.Init(m);
while(!w.ShouldClose(window)) {
Input.ProcessInput(window);
renderer.Render(Color.black);
w.HandleWindow(window);
}
w.DestroyWindow(window);
}
}
Fragment:
#version 330 core
in vec3 color;
in vec2 texCoords;
out vec4 fragColor;
uniform sampler2D inputTexture;
void main() {
fragColor = texture(inputTexture, texCoords) * vec4(color, 1.0);
}
Vertex:
#version 330 core
in vec3 aPos;
in vec3 aColor;
in vec2 aTexCoord;
out vec3 color;
out vec2 texCoord;
void main() {
gl_Position = vec4(aPos, 1.0);
color = aColor;
texCoord = aTexCoord;
}
Since you have separate arrays for the vertex coordinates, colors and texture coordinates, you have specify separat buffers for the attributes:
vbo_ver = GL20.glGenBuffers();
vbo_col = GL20.glGenBuffers();
vbo_tex = GL20.glGenBuffers();
Creates and initializes the buffer object's data store
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_ver);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.vertices, GL20.GL_STATIC_DRAW);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_col);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.colors, GL20.GL_STATIC_DRAW);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_tex);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.textureCoords, GL20.GL_STATIC_DRAW);
Specify the attribute indices, in the vertex shader by layout qualifiers:
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCoord;
glVertexAttribPointer associates the buffer which is currently bound to the ARRAY_BUFFER target, to the specified attribute (index), in the state vector of the currently bound Vertex Array Object. (See Vertex Specification).
Hence, the proper buffer and the VAO has to be bound before glVertexAttribPointer.
(The ELEMENT_ARRAY_BUFFER) is stated in the VAO, thus the VAO has to be bound before specifying the index buffer):
GL30.glBindVertexArray(vao);
GL20.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, ebo);
GL20.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, mesh.indices, GL20.GL_STATIC_DRAW);
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_ver);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_col);
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 0, 0);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_tex);
GL20.glVertexAttribPointer(2, 2, GL11.GL_FLOAT, false, 0, 0);
Alternatively you can put the vertices and attributes to 1 array:
float[] attributes = {
// x y z r g b u v
0.5f, 0.5f, 0f, 1f, 0f, 0f, 1f, 1f,
0.5f, -0.5f, 0f, 0f, 1f, 0f, 1f, 0f,
-0.5f, -0.5f, 0f, 0f, 0f, 1f, 0f, 0f,
-0.5f, 0.5f, 0f, 1f, 1f, 0f 0f, 1f
};
vbo = GL20.glGenBuffers();
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.attributes, GL20.GL_STATIC_DRAW);
The stride and the offset have to be specified in bates:
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo);
int stride = 8 * 4; // the tuple size is 8 (x y z r g b u v), sizeof float is 4
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, stride, 0);
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, stride, 3*4);
GL20.glVertexAttribPointer(2, 2, GL11.GL_FLOAT, false, stride, 6*4);

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?

JOGL draw VBO black screen

I began to try to draw VBO using JOGL. Prior to that, I drew with the help of glBegin and glEnd, and everything worked. And then I see only a black screen. What could be the problem? I read somewhere that using VBO for drawing requires shaders. Is it so?
Code:
public class Main implements GLEventListener {
public static DisplayMode dm, dm_old;
private GLU glu = new GLU();
private float xrot,yrot,zrot;
private int texture;
Texture t;
#Override
public void display(GLAutoDrawable drawable) {
final GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity(); // Reset The View
gl.glTranslatef(0f, 0f, -5.0f);
gl.glBindTexture(GL2.GL_TEXTURE_2D, texture);
final float[] coordData = {
0, 0, //
1, 0, //
0, 1, //
};
final float[] vertices = {
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
};
// Setup the vertices into the buffer
FloatBuffer verts = Buffers.newDirectFloatBuffer(vertices.length);
verts.put(vertices).position(0);
// Setup the texture coordinates
FloatBuffer coords = Buffers.newDirectFloatBuffer(coordData.length);
coords.put(coordData).position(0);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, verts);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, coords);
gl.glDrawArrays(GL2.GL_TRIANGLES, 0, 3);
//change the speeds here
xrot += 5f;
}
#Override
public void init(GLAutoDrawable drawable) {
final GL2 gl = drawable.getGL().getGL2();
gl.glShadeModel(GL2.GL_SMOOTH);
gl.glClearColor(0f, 0f, 0f, 0f);
gl.glClearDepth(1.0f);
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glDepthFunc(GL2.GL_LEQUAL);
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
gl.glEnable(GL2.GL_TEXTURE_2D);
try {
File im = new File("/home/congard/pic/t.jpeg");
t = TextureIO.newTexture(im, true);
texture= t.getTextureObject(gl);
}catch(IOException e){
e.printStackTrace();
}
}
#Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
// some code
}
}
You didn't enable the client-side capabilities for vertex and texture coordinates. See Client-Side Vertex Arrays
and glEnableClientState.
Add the following to your code:
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, verts);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, coords);

Android - 3D Cube with OPENGL + Textures

I've done a 3d cube with OPENGL library on Android, the cube works pretty but the image on to print on the cube is not displaying...
Here's the code of my Render (java class):
public class GLRenderEx implements Renderer {
private GLCube cube;
Context c;
public GLRenderEx(Context c) {
cube = new GLCube();
this.c = c;
}
#Override
public void onDrawFrame(GL10 gl) {
gl.glDisable(GL10.GL_DITHER);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -3, 0, 0, 0, 0, 2, 0);
long time = SystemClock.uptimeMillis() % 4000L;
float angle = .090f * ((int) time);
gl.glRotatef(angle, 2, 4, 3);
cube.draw(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 25);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig egl) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0f, 0f, 0f, 1);
gl.glClearDepthf(1f);
}
}
Here's the code of my cube:
public class GLCube {
/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The buffer holding the texture coordinates */
private FloatBuffer textureBuffer;
/** The buffer holding the indices */
private ByteBuffer indexBuffer;
/** Our texture pointer */
private int[] textures = new int[1];
/**
* The initial vertex definition
*
* Note that each face is defined, even if indices are available, because of
* the texturing we want to achieve
*/
private float vertices[] = {
// Vertices according to faces
-1.0f,
-1.0f,
1.0f, // Vertex 0
1.0f,
-1.0f,
1.0f, // v1
-1.0f,
1.0f,
1.0f, // v2
1.0f,
1.0f,
1.0f, // v3
1.0f,
-1.0f,
1.0f, // ...
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f,
1.0f, -1.0f, };
/** The initial texture coordinates (u, v) */
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
};
/** The initial indices definition */
private byte indices[] = {
// Faces definition
0, 1, 3, 0, 3,
2, // Face front
4, 5, 7, 4, 7,
6, // Face right
8, 9, 11, 8, 11,
10, // ...
12, 13, 15, 12, 15, 14, 16, 17, 19, 16, 19, 18, 20, 21, 23, 20, 23,
22, };
/**
* The Cube constructor.
*
* Initiate the buffers.
*/
public GLCube() {
//
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
//
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
//
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
}
/**
* The object own drawing function. Called from the renderer to redraw this
* instance with possible changes in values.
*
* #param gl
* - The GL Context
*/
public void draw(GL10 gl) {
// Bind our only previously generated texture in this case
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glEnable(GL10.GL_TEXTURE_2D);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CCW);
// Enable the vertex and texture state
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangles, based on the Index Buffer information
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
GL10.GL_UNSIGNED_BYTE, indexBuffer);
// Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
/**
* Load the textures
*
* #param gl
* - The GL Context
* #param context
* - The Activity context
*/
public void loadGLTexture(GL10 gl, Context context) {
// Get the texture from the Android resource directory
InputStream is = context.getResources().openRawResource(
R.drawable.ic_launcher);
Bitmap bitmap = null;
try {
// BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);
} finally {
// Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {
}
}
// Generate one texture pointer...
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Create Nearest Filtered Texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
// Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
GL10.GL_CLAMP_TO_EDGE);
// Use the Android GLUtils to specify a two-dimensional texture image
// from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
}
Why is the bitmap on my code not displaying in the cube??!!
Thanks.
I have looked through your code and haven't found a place, where you call loadGLTexture(). When I implemented your code to make textures, I just added cube.loadGLTexture(gl, c); above cube.draw(gl); in onDrawFrame() method. Hope that helps.
If you want to texture your objects, you must enable texturing with glEnable(GL_TEXTURE_2D);
I don't see this anywhere in your code.
I've had the some problem as you.
What caused my problem was the texture not matching exactly with the cube.
Check your code carefully, you might notice some mismatching.

Why won't this OpenGL ES code create a texture?

I am workiong on the Android platform. I have just started with OpenGL and am trying to put an image on a rectangle. This is my code:
public class IntroActivity extends Activity {
private GLSurfaceView glsv = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glsv = new GLSurfaceView(this);
glsv.setRenderer(new IntroRenderer());
setContentView(glsv);
}
#Override
protected void onResume() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onResume();
glsv.onResume();
}
#Override
protected void onPause() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onPause();
glsv.onPause();
}
Here IntroRenderer is an inner class.
class IntroRenderer implements GLSurfaceView.Renderer{
#Override
public void onDrawFrame(GL10 gl) {
gl.glClearColor(0,1.0f,1.0f,1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
float positions[] = {
0.0f,1.0f,0.0f,
0.0f, 0.0f, 0.0f,
1.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,
1.0f,1.0f, 0.0f,
1.0f,0.0f,0.0f
};
ByteBuffer bb = ByteBuffer.allocateDirect(positions.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(positions);
fb.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3,GL10.GL_FLOAT, 0, fb);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3*2);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.rect2985);
Bitmap bmp256 = Bitmap.createScaledBitmap(bmp, 256,256,false);
gl.glEnable(GL10.GL_TEXTURE_2D);
int[] buffers = new int[1];
gl.glGenTextures(1,buffers,0);
int texture = buffers[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp256,0);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
bmp.recycle();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
}
}
}
On running this activity, the background rectangle is rendered but ther eis no image. What am I doing wrong?
I modified your renderer a bit:
class IntroRenderer implements GLSurfaceView.Renderer {
private boolean textureReady = false;
public void onDrawFrame(GL10 gl) {
if (!this.textureReady) {
this.prepareTexture(gl); // only initialize once
}
gl.glClearColor(0, 0.4f, 0.4f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
float positions[] = {
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f };
float texCoords[] = { // define texture coordinates
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f };
ByteBuffer bb = ByteBuffer.allocateDirect(positions.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(positions);
fb.position(0);
// create buffer for texture coordinates
ByteBuffer texCoordByteBuffer = ByteBuffer.allocateDirect(texCoords.length * 4);
texCoordByteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer texCoordBuffer = texCoordByteBuffer.asFloatBuffer();
texCoordBuffer.put(texCoords);
texCoordBuffer.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb);
// enable texture buffer
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoordBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3 * 2);
}
private void prepareTexture(GL10 gl) {
int[] buffers = new int[1];
gl.glGenTextures(1, buffers, 0);
int texture = buffers[0];
// enable texturing and bind texture
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
Bitmap bmp = BitmapFactory.decodeResource(IntroActivity.this.getResources(), R.drawable.rect2985);
Bitmap bmp256 = Bitmap.createScaledBitmap(bmp, 256, 256, false);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp256, 0);
// setup filters
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
bmp.recycle();
this.textureReady = true;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
}
}
I added comments at the modified parts:
You have to define texture coordinates and create a buffer (like you did for vertex positions)
Enable texturing with gl.glEnable(GL10.GL_TEXTURE_2D);
You need min/mag filters
As oren suggested you should do the initialization only once.
The texture coordinates define how the texture is mapped to your triangles. You can think of a coordinate system from 0.0 to 1.0 in x and y axis where the corners (0,0; 1,0; 1,1; 0,1) define the corners of your texture. You have to assign a texture coordinate to each vertex you define.
Maybe this can help you to understand how texture coordinates work: http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node52.html
I'm not sure why is doesn't render, but your code is inefficient.
You are loading the bitmap and binding it on EVERY frame.
You should do it only once.
Also, this link can help you with great examples with this Nehe port for Android:
Nehe Port for Android
Good luck :)

Categories