I am trying to switch to VBOs, without indices for now. But all I get is just a blank screen. Can someone point out why it is blank? The same code works fine if I comment out the vbo-specific code and replace 0(offset) in glVertexAttribPointer by mFVertexBuffer, i.e without using VBOs.
This is my onDraw method
GLES20.glClearColor(0.50f, 0.50f, 0.50f, 1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
// Bind default FBO
// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id);
int vertexCount = mCarVerticesData.length / 3;
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
checkGlError("1");
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT,false, 0, 0);
checkGlError("2");
GLES20.glEnableVertexAttribArray(positionHandle);
checkGlError("3 ");
transferTexturePoints(getTextureHandle());
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
checkGlError("glDrawArrays");
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glDisableVertexAttribArray(positionHandle);
GLES20.glDisable(GLES20.GL_BLEND);
This is my vbo setup:
// Allocate and handle vertex buffer
ByteBuffer vbb2 = ByteBuffer.allocateDirect(mCarVerticesData.length
* FLOAT_SIZE_BYTES);
vbb2.order(ByteOrder.nativeOrder());
mFVertexBuffer = vbb2.asFloatBuffer();
mFVertexBuffer.put(mCarVerticesData);
mFVertexBuffer.position(0);
// Allocate and handle vertex buffer
this.buffers = new int[1];
GLES20.glGenBuffers(1, buffers, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, mFVertexBuffer.capacity()
* FLOAT_SIZE_BYTES, mFVertexBuffer, GLES20.GL_STATIC_DRAW);
Before linking my program:
GLES20.glBindAttribLocation(program, 0, "aPosition");
checkGlError("bindAttribLoc");
And my vertex shader is :
uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
attribute vec2 aTextureCoordinate;
varying vec2 v_TextureCoordinate;
void main()
{
gl_Position = uMVPMatrix * aPosition;
v_TextureCoordinate = aTextureCoordinate;
gl_PointSize= 10.0;
}
You need to also generate an elements array and call something like this in order to render your "object":
// Bind the vertex buffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, _bufferIds.get(2));
GLES20.glVertexAttribPointer(4, 4, GLES20.GL_FLOAT, false, 4*4, 0);
// Bind the elements buffer and draw it
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, _bufferIds.get(1));
GLES20.glDrawElements(GLES20.GL_TRIANGLES, _numElements, GLES20.GL_UNSIGNED_SHORT, 0);
Hope that helps.
I solved the problem by rewriting the way I was uploading vertices data. I was modifying it and so, I needed to call glBindBufferData again for it to be uploaded. And I was able to use VBOs without using glDrawElements and indices, and it works well.
Related
I have been stuck all day yesterday with this problem and cant figure it out. The code is below but generally i am trying to give a mesh Vertex Attributes for 1.Postions 2.Indices 3.Normals and 4.a single float value.
The values are all stored in different VBOs and after binding each vbo i declare the vertexAttribPointer. I cant get both normals and float value working. What im seeing seems like the position of the float value is either the x y or z part of the normals vec3 in the previous vbo.
GL4 gl = GLContext.getCurrentGL().getGL4();
int[] vaoids = new int[1];
gl.glGenVertexArrays(1,vaoids,0);
int[] vboids = new int[4];
gl.glGenBuffers(4,vboids,0);
gl.glBindVertexArray(vaoids[0]);
FloatBuffer verticesBuffer = FloatBuffer.allocate(mesh.vertices.length);
verticesBuffer.put(mesh.vertices);
verticesBuffer.flip();
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[0]);
gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * 4 ,verticesBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, false, 0, 0);
verticesBuffer.clear();
verticesBuffer = null;
//normal buffer
FloatBuffer normalBuffer = FloatBuffer.allocate(mesh.normals.length);
normalBuffer.put(mesh.normals);
normalBuffer.flip();
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[2]);
gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * 4 ,normalBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(2);
gl.glVertexAttribPointer(2, 3, gl.GL_FLOAT, false, 0, 0);
normalBuffer.clear();
normalBuffer = null;
//color buffer
float[] colors = new float[mesh.vertices.length/3];
Arrays.fill(colors,255.0f);
FloatBuffer colorBuffer = FloatBuffer.allocate(colors.length);
colorBuffer.put(colors);
colorBuffer.flip();
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[3]);
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors.length * 4 ,colorBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(3);
gl.glVertexAttribPointer(3, 1, gl.GL_FLOAT,false, 0, 0);
colorBuffer.clear();
colorBuffer = null;
IntBuffer indicesBuffer = IntBuffer.allocate(mesh.indices.length);
indicesBuffer.put(mesh.indices);
indicesBuffer.flip();
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, vboids[1]);
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * 4 ,indicesBuffer,gl.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(1);
gl.glVertexAttribPointer(1, mesh.type.equals(MeshType.TRIANGLE) ? 3 : mesh.type.equals(MeshType.LINE) ? 2 : mesh.type.equals(MeshType.POINT) ? 1:0, gl.GL_UNSIGNED_INT, false, 0, 0);
indicesBuffer.clear();
indicesBuffer = null;
//gl.glBindBuffer(gl.GL_ARRAY_BUFFER,0);
gl.glBindVertexArray(0);
This the code that declares the vao and vbos. I render with glDrawElements and enable the needed VertexAttributeArray Indices before that. In my Shader I access the value as following:
layout (location=0) in vec3 position;
layout (location=2) in vec3 normal;
layout (location=3) in float color;
out vec3 normals;
out vec4 positionWorldSpace;
out flat float vertexColor;
And the fragment shader
in flat float color;
I can get both of them working separate but if i declare both they float values are not correct anymore. The normals seems to be right however. As i said the values in the float seem the be values from the normals. Can there be some sort of overflow from the normal vbo to the float vbo? After hours of looking at the code i just cant spot the error.
The indices are not attributes. The [Index buffer](Index buffers) (GL_ELEMENT_ARRAY_BUFFER) is stated in the VAO directly. See Vertex Specification.
When you use glDrawArrays then the order vertex coordinates of the vertex coordinates in the array defines the primitives. If you want to use a different order or you want to use vertices for different primitives, then you have to use glDrawElements. When you use glDrawElements, then the primitives are defined by the vertex indices in the GL_ELEMENT_ARRAY_BUFFER buffer:
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, vboids[1]);
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * 4 ,indicesBuffer,gl.GL_STATIC_DRAW);
// DELETE
//gl.glEnableVertexAttribArray(1);
//gl.glVertexAttribPointer(1, mesh.type.equals(MeshType.TRIANGLE) ? 3 : mesh.type.equals(MeshType.LINE) ? 2 : mesh.type.equals(MeshType.POINT) ? 1:0, gl.GL_UNSIGNED_INT, false, 0, 0);
indicesBuffer.clear();
indicesBuffer = null;
gl.glBindVertexArray(0);
gl.glDrawElements(gl.GL_TRIANGLES, mesh.indices.length, gl.GL_UNSIGNED_INT, null);
I am attempting implementing shadows in my OpenGL scene. However, in my shader, whenever I try to access the texture value in the shadow map (that I rendered previously), I always get 1, or a value close to 1, for the x, y, z, and w values.
The problem is that I thought these values are supposed to represent the z coords of the respective fragment in the shadow map/texture (from the sun's perspective).
The relevant initiation code (in JOGL):
gl.glEnable(GL2.GL_TEXTURE_2D);
// generate stuff
IntBuffer ib = IntBuffer.allocate(1);
gl.glGenFramebuffers(1, ib);
depthMapFBO = ib.get(0);
ib = IntBuffer.allocate(1);
gl.glGenTextures(1, ib);
depthMap = ib.get(0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, depthMapFBO);
gl.glBindTexture(GL2.GL_TEXTURE_2D, depthMap);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT16, 1024, 1024, 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, null);
// prevents 'shadow acne'
gl.glPolygonOffset(2.5f, 0);
// prevents multiple shadows
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
// prevents (or expects!!!) pixel-y textures
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
// store one value in all four components of pixel
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY);
The relevant draw/per-frame code:
// render shadows
gl.glUseProgram(shadowProgram);
gl.glUniformMatrix4fv(lightMatrixLocShadow, 1, false, lightMatrix.getMatrix(), 0); // yep (haha change viewMatrix -> lightMatrix)
gl.glUniformMatrix4fv(projMatrixLocShadow, 1, false, projMatrix.getMatrix(), 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, depthMapFBO);
gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, GL2.GL_TEXTURE_2D, sha.depthMap, 0);
gl.glDrawBuffer(GL2.GL_NONE);
gl.glReadBuffer(GL2.GL_NONE);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
gl.glViewport(0, 0, 1024, 1024);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, depthMapFBO);
gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
renderScene(gl, sunMatrix);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
// render display (regular)
gl.glUseProgram(displayProgram);
gl.glDrawBuffer(GL2.GL_FRONT);
gl.glReadBuffer(GL2.GL_FRONT);
gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(projMatrixLocDisplay, 1, false, projMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(lightMatrixLocDisplay, 1, false, lightMatrix.getMatrix(), 0);
gl.glUniform4fv(sunPositionLoc, 1, sunWorldPosition, 0); // send sun's position to shader
gl.glUniform1f(sunBrightnessLoc, sunBrightness);
gl.glUniform1i(shadowMapLoc, 0);
gl.glViewport(0, 0, screenWidth, screenHeight);
//gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, depthMapFBO);
// day-night cycle
float[] color = SkyManager.getSkyColor(time);
gl.glClearColor(color[0], color[1], color[2], 1);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glActiveTexture(GL2.GL_TEXTURE0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, sha.depthMap);
//gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
renderScene(gl, sunMatrix);
The relevant fragment shader code (used to debug the values; in glsl 1.3)
gl_FragColor = vec4(vec3(texture2D(shadowMap, lightProjPosition.xy).z), 1.0);
The expected values from the texture() call are, of course, the different distances of the fragments to the light source.
If anyone can find out why I am getting 1 I would appreciate the help.
EDIT
Here is the shadow shader code:
Vertex:
#version 130
uniform mat4 light;
uniform mat4 proj;
out vec4 position;
void main() {
position = proj * light * gl_Vertex;
gl_Position = position;
}
Fragment:
#version 130
in vec4 position;
void main() {
gl_FragColor.z = position.z; // still doesn't work with this line commented
}
I'm trying to render a scene using OpenGL ES 2.0 in an Android App, however, the screen keeps being drawn with the defined clear color.
I had success rendering simpler examples, but I'm failing when using packed vertex buffer.
The idea is to render a scene with a camera inside a Sphere, here are some code snippets which should give some context and also is where I think the bug is.
Fragment Shader:
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTextureCoord;
uniform inputImageTexture;
void main()
{
vec4 color = texture2D(inputImageTexture, vTextureCoord);
gl_FragColor = vec4(1.0);
}
Vertex Shader:
uniform mat4 uMVPMatrix;
uniform mat4 uTransform;
attribute vec4 aPosition;
attribute vec4 aTextureCoord;
varying vec2 vTextureCoord;
void main()
{
gl_Position = uMVPMatrix * aPosition * vec4(1, -1, 1, 1);
vec4 coord = (aTextureCoord / 2.0) + 0.5;
vTextureCoord = (uTransform * coord).xy;
}
The GL program initialization:
mProgram = new ProgramObject();
if(mProgram.init(vsh, fshResult)) {
GLES20.glClearColor(1.0f, 0.f, 0.f, 1.f);
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glDisable(GLES20.GL_CULL_FACE);
uMVPMatrixLocation = mProgram.getUniformLoc("uMVPMatrix");
aPositionLocation = mProgram.attributeLocation("aPosition");
aTextureCoordLocation = mProgram.attributeLocation("aTextureCoord");
mTransformLoc = mProgram.getUniformLoc("uTransform");
}
Vertex loading:
sphere = new Sphere(SPHERE_SLICES, 0.f, 0.f, 0.f, SPHERE_RADIUS, SPHERE_INDICES_PER_VERTEX);
mProgram.bind();
final int buffers[] = new int[1];
GLES20.glGenBuffers(1, buffers, 0);
mVertexBuffer = buffers[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, sphere.getVerticesSize(), sphere.getVertices(), GLES20.GL_STATIC_DRAW);
Render:
GLES20.glViewport(viewport.x, viewport.y, viewport.width, viewport.height);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(TEXTURE_2D_BINDABLE, texID);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glVertexAttribPointer(aPositionLocation, 3,
GLES20.GL_FLOAT, false, sphere.getVerticesStride(), sphere.getVertices());
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
GLES20.glEnableVertexAttribArray(aTextureCoordLocation);
GLES20.glVertexAttribPointer(aTextureCoordLocation, 2,
GLES20.GL_FLOAT, false, sphere.getVerticesStride(),
sphere.getVertices().duplicate().position(3));
Matrix.multiplyMM(pvMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
Matrix.multiplyMM(mvpMatrix, 0, pvMatrix, 0, modelMatrix , 0);
GLES20.glUniformMatrix4fv(uMVPMatrixLocation, 1, false, mvpMatrix, 0);
for (int j = 0; j < sphere.getNumIndices().length; ++j) {
GLES20.glDrawElements(GLES20.GL_TRIANGLES, sphere.getNumIndices()[j], GLES20.GL_UNSIGNED_SHORT, sphere.getIndices()[j]);
}
Any insights are welcome, thank you very much.
Update
The could was running without any errors on a Galaxy S6, but, now running on a One Plus X I'm getting the following error:
<gl_draw_error_checks:598>: GL_INVALID_OPERATION
glDrawElements: glError 0x502
After running:
for (int j = 0; j < sphere.getNumIndices().length; ++j) {
GLES20.glDrawElements(GLES20.GL_TRIANGLES, sphere.getNumIndices()[j], GLES20.GL_UNSIGNED_SHORT, sphere.getIndices()[j]);
}
You're mixing up two ways of using vertex arrays:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
...
GLES20.glVertexAttribPointer(aPositionLocation, 3,
GLES20.GL_FLOAT, false, sphere.getVerticesStride(), sphere.getVertices());
In ES 2.0, there are two ways of using vertex arrays:
Client-side vertex arrays.
Vertex-buffer objects (VBOs).
With client-side vertex arrays, you don't store your vertex data in VBOs, but pass the vertex data directly as the last argument to the glVertexAttribPointer() call. In C/C++ bindings, this is a pointer to the data, in the Java bindings it's a Java Buffer object.
When using VBOs, you store your vertex data in a VBO, using glBufferData(). Then you bind the VBO before the glVertexAttribPointer() call, and pass the offset of the data relative to the start of the VBO as the last argument.
In your example:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glVertexAttribPointer(aPositionLocation, 3,
GLES20.GL_FLOAT, false, sphere.getVerticesStride(), 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
GLES20.glEnableVertexAttribArray(aTextureCoordLocation);
GLES20.glVertexAttribPointer(aTextureCoordLocation, 2,
GLES20.GL_FLOAT, false, sphere.getVerticesStride(), 12);
Note that the offset is in bytes, so it's 12 bytes if your colors are offset by 3 floats relative to the positions.
Client-side vertex arrays are deprecated, and partly unavailable, in newer versions of OpenGL. So storing the data in VBOs, as you already are, is the right way to go.
I have just tried switching to use Interleaved VBOs. I have stepped through the process of creating the Interleaved VBO and it appears that it has the correct information init.
VVV NNN TT etc.
Here is the code for initialising the buffer
VertexBuffer = Loader.vertexBuffer;
final int buffers[] = new int[1];
GLES20.glGenBuffers(1, buffers, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, VertexBuffer.capacity(), VertexBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
mBufferIdx = buffers[0];
VertexBuffer.limit(0);
VertexBuffer = null;
and here is my code for drawing the model
final int stride = (mPositionDataSize + mNormalDataSize + mTextureCoordinateDataSize) * mBytesPerFloat;
// Pass in the position information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBufferIdx);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, stride, 0);
// Pass in the normal information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBufferIdx);
GLES20.glEnableVertexAttribArray(mNormalHandle);
GLES20.glVertexAttribPointer(mNormalHandle, mNormalDataSize, GLES20.GL_FLOAT, false, stride, mPositionDataSize * mBytesPerFloat);
// Pass in the texture information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBufferIdx);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false,
stride, (mPositionDataSize + mNormalDataSize) * mBytesPerFloat);
// Clear the currently bound buffer (so future OpenGL calls do not use this buffer).
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
// Draw .
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, NumVertices);
I left the matrices work out as this worked before using VBOs and i am seeting all the handles correctly.
My app appears to run as if the models are there but just invisible. for example i am moving a model and being told when it gets to a certain position, i just cant see it like i did before i moved to VBOs.
Let me know if i need to upload anything else. Any advice would be appreciated.
UPDATE!
I think the issue maybe in the way i create the interleaved VBO here is the code
private void createVertexBuffer(float[] VertexList, float[] NormalList, float[] TextureList)
{
final int vertexDataSize = VertexList.length + NormalList.length + TextureList.length;
this.vertexBuffer = ByteBuffer.allocateDirect(vertexDataSize * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
int PositionOffset = 0;
int NormalOffset = 0;
int TextureOffset = 0;
for(int i = 0; i < NumVerts; i++)
{
this.vertexBuffer.put(VertexList, PositionOffset, mPositionDataSize);
PositionOffset += mPositionDataSize;
this.vertexBuffer.put(NormalList, NormalOffset, mNormalDataSize);
NormalOffset += mNormalDataSize;
this.vertexBuffer.put(TextureList, TextureOffset, mTextureCoordinateDataSize);
TextureOffset += mTextureCoordinateDataSize;
}
this.vertexBuffer.position(0);
}
What could i be doing wrong?
UPDATE CODE
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
mLightPosHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_LightPos");
//mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color");
Cube1.mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Texture");
Cube1.mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
Cube1.mNormalHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Normal");
Cube1.mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");
Cube1.SetTexture();
Cube1.SetIdentity();
Cube1.SetPosition();
Cube1.SetScale(10.0f, 10.0f, 10.0f);
Cube1.SetRotation(RotationAngle, 0.0f, 0.0f, 1.0f);
Cube1.DrawModel(mProjectionMatrix, mViewMatrix, mMVPMatrix, mMVPMatrixHandle, mMVMatrixHandle, mLightPosHandle, mLightPosInEyeSpace);
public void SetTexture()
{
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
}
I am not sure what my issue was in the above code how ever i re wrote my code to use an index buffer and have submitted in another question. Found here
Along with the answer i gave in the other question it should give a clear way of introducing VBO's and IBO's for any one who is struggling
Currently I have a working system of VBO's where I have two buffers - one for position and one for color. However, I want to draw textures instead of colors. How can I draw textures over my VBO position buffer? This is in Java and LWJGL, but an example in any language helps.
I want to add textures to my VBO. How would I go about doing that?
You don't. At least you're not adding texture images to the VBO. What you add is a new attribute, called the texture coordinate, that assigns each vertex the location of an texture image.
The texture itself is an independent object, created using glGenTextures, glBindTexture and glTexImage….
Here is a simple code snippet to initialize and render a cube with a texture. Uses Slick2D library.
int vertexHandle;
int textureHandle;
private void init() throws IOException {
Camera.init();
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("test.png"));
this.initialize3D();
vertexHandle = GL15.glGenBuffers();
FloatBuffer positionData = BufferUtils.createFloatBuffer(72);
// Initalize position data.
positionData.flip();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vertexHandle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,positionData,GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
FloatBuffer textureData = BufferUtils.createFloatBuffer(72);
// Initialize texture data.
textureBuffer.flip();
textureHandle = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, textureHandle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, textureData, GL15.GL_STATIC_DRAW);
GL11.glTexCoordPointer(3, GL11.GL_FLOAT, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
public void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glLoadIdentity();
texture.bind();
GL11.glPushMatrix();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexHandle);
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0L);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, textureHandle);
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0L);
GL11.glDrawArrays(GL11.GL_QUADS, 0, 24);
GL11.glPopMatrix();
}
In addition you may need to integrate parts of this method to initialize 3D rendering:
public void initialize3D() {
GL11.glEnable(GL11.GL_TEXTURE_2D); // Allows 2D textures.
GL11.glShadeModel(GL11.GL_SMOOTH); // Smoother textures.
//GL11.glClearColor(0.4f,0.6f,1.0f,0.0f); // BG color. 6698FF
GL11.glClearDepth(1.0); // Buffer depth, allows objects to draw over things behind them.
GL11.glEnable(GL11.GL_DEPTH_TEST); // Depth testing (see above).
GL11.glDepthFunc(GL11.GL_LEQUAL); // Type of depth testing.
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
//GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL11.glMatrixMode(GL11.GL_PROJECTION); // Sets matrix mode to displaying pixels.
GL11.glLoadIdentity(); // Loads the above matrix mode.
// Sets default perspective location. Render Distances: Min Max
GLU.gluPerspective(45.0f,(float)Display.getWidth()/(float)Display.getHeight(),0.1f,300.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Sets the matrix to displaying objects.
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT,GL11.GL_NICEST); // Something unimportant for quality.
}