upside-down texture? | OpenGL-ES 2.0 (android) - android

I tried to map my texture to a square made in opengl es 2.0, and when i do, the texture appears upside down, is my mapping wrong? or the way im drawing it? here is a picture of what it looks like:
here is my code for the onDrawFrame()
public void onDrawFrame(GL10 glUnused) {
GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT,
false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
GLES20.glEnableVertexAttribArray(maTextureHandle);
Matrix.orthoM(mProjMatrix, 0, 0, 200, 0, 100, -5, 5);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mProjMatrix, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}
the coordination for the square and mapping UV are:
private final float[] mTriangleVerticesData = {
// X, Y, Z, U, V
0f, 0f, 0, 0.0f, 0.0f,
50f, 0f, 0, 1.0f, 0.0f,
50f, 50f, 0, 1.0f, 1.0f,
0f, 50f, 0.0f, 0.0f, 1.0f };
private short drawOrder[] = { 0, 1, 2, 0, 2, 3 };
how could i achieve a right-side up view?

This looks like a common mistake. You need to account for the fact that OpenGL's origin for textures is in the lower left corner (and not the upper-left corner).
There's a couple of things you can do to compensate:
read the pixels lines from bottom to top;
swap the pixel lines;
or swap the texture Y coordinates;
You could try swapping the texture coordinates in a shader (source: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_06)
void main(void) {
vec2 flipped_texcoord = vec2(f_texcoord.x, 1.0 - f_texcoord.y);
gl_FragColor = texture2D(mytexture, flipped_texcoord);
}

Related

OpenGL ES 1.0 to OpenGL ES 2.0, I cant draw a square

I am learning open GL ES 2.0 and I just made 1 easy game for 1.0
I am following tutorials but I cant understand this thing
In OpenGL ES 1.0 if I define a square that way:
private float[] vertices = { // Vertices for a face
0.0f, 0.0f, 0.2f, // 0. left-bottom-front
1.0f, 0.0f, 0.2f, // 1. right-bottom-front
0.0f, 1.0f, 0.2f, // 2. left-top-front
1.0f, 1.0f, 0.2f // 3. right-top-front
};
and draw it that way it Works
public void draw(GL10 gl)
{
gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise
// orientation
gl.glEnable(GL10.GL_CULL_FACE); // Enable cull face
gl.glCullFace(GL10.GL_BACK); // Cull the back face (don't display)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Enable
// texture-coords-array
// (NEW)
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0, texBuffer); // Define
// texture-coords
// buffer (NEW)
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// front
gl.glBindTexture(GL10.GL_TEXTURE_2D,TextureLoader.TeclaBlancatextureIDs[0]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Disable
// texture-coords-array
// (NEW)
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
gl.glDisable(GL10.GL_BLEND);
}
but in OpenGL ES 2.0 if I do this that way( with the same vertex) it only write a triangle:
private void drawSuelo(Suelo suelo)
{
// Pass in the position information
suelo.mPositions.position(0);
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
0, suelo.mPositions);
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Pass in the color information
suelo.mColors.position(0);
GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
0, suelo.mColors);
GLES20.glEnableVertexAttribArray(mColorHandle);
// Pass in the normal information
cubo.mCubeNormals.position(0);
GLES20.glVertexAttribPointer(mNormalHandle, mNormalDataSize, GLES20.GL_FLOAT, false,
0, cubo.mCubeNormals);
GLES20.glEnableVertexAttribArray(mNormalHandle);
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
// Pass in the modelview matrix.
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
// Pass in the combined matrix.
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Pass in the light position in eye space.
GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
// Draw the cube.
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
}
It seems to need all of this vertex in order to draw a square
final float[] PositionData = {
// Top face
-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 };
Why is happening this? Why I am missing? Is there any way in Open GL ES 2.0 to write a square with 4 vertex?
You're using different primitive types. In the working ES 1.0 code, you have this:
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
and in the ES 2.0 code that renders only a triangle when you give it 4 vertices:
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
So in the ES 1.0 code, you're specifying that you want to draw a triangle strip (primitive type GL_TRIANGLE_STRIP) with 4 vertices. This corresponds to 2 triangles. While in the ES 2.0 code, you specify that you want to draw 2 separate triangles (primitive type GL_TRIANGLES), which indeed needs 6 vertices.
If you want to use the original 4 vertices for the ES 2.0 code, you simply have to use the equivalent draw call with the same primitive type you used in the ES 1.0 version:
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

OpenGL ES 2.0 setLookAtM

I have, a problem with the setLookAtM function. My goal is to create a cube within a cube something like this (yep, it's paint :P ):
So basically everything works... almoust... I have the smaller cube and I have the bigger one.
However, there is a problem. I created the bigger one with coords from -1 to 1 and now I want to upscale it. With scale 1.0f i have something like this (the inner cube is rotating):
And thats good, but now... when I try to scale the bigger cube (so that it looks like in the paint drawing) the image goes black or white (i guess it's because the "camera" looks at the white cube but still i dont know why does my inner cube disappear :/ I don't understand what I'm doing wrong. Here is my code:
public void onDrawFrame(GL10 unused) {
float[] scratch = new float[16];
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5.0f, 0f, 0f, -1.0f, 0f, 1.0f, 0.0f);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
mRoom.mScale = 1.0f;
Matrix.setIdentityM(mScaleMatrix, 0);
Matrix.scaleM(mScaleMatrix, 0, mRoom.mScale, mRoom.mScale, mRoom.mScale);
float[] scaleTempMatrix = new float[16];
Matrix.multiplyMM(scaleTempMatrix, 0, mMVPMatrix, 0, mScaleMatrix, 0);
mRoom.draw(scaleTempMatrix);
When I set for example:
mRoom.mScale = 3.0f;
And
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -2.0f, 0f, 0f, 0.0f, 1.0f, 1.0f, 0.0f);
My camera should be at (0, 0, -2) looking at (0,0, -1) and it should be inside the white cube (since scale is 3.0 so the coords should be from -3 to 3 right?) But all I get is a white screen without the smaller cube rotating inside :/
If your scale is 3x in this code, then your visible coordinate range is actually going to be [-1/3,1/3].
You are thinking about things backwards, it might help if you considered the order in which the scale operation is applied. Right now you are scaling the object-space coordinates, then applying the view matrix and then projection. It may not look that way, but that is how matrix multiplication in GL works; GL effectively flips the operands when it does matrix multiplication and matrix multiplication is not commutative.
I believe this is what you actually want:
public void onDrawFrame(GL10 unused) {
float[] scratch = new float[16];
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5.0f, 0f, 0f, -1.0f, 0f, 1.0f, 0.0f);
mRoom.mScale = 3.0f;
Matrix.setIdentityM(mScaleMatrix, 0);
Matrix.scaleM(mScaleMatrix, 0, mRoom.mScale, mRoom.mScale, mRoom.mScale);
Matrix.multiplyMM(mMVPMatrix, 0, mScaleMatrix, 0, mProjectionMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mMVPMatrix, 0, mViewMatrix, 0);
mRoom.draw(mMVPMatrix);

Edges of an object move about while rotating

I have a project featuring a 3d object. The user can rotate and zoom it in/out with finger gestures. The problem I have is while rotating a cube (other solids also cause the same error, but I'll set an example on cube), the edges of it kind of disintegrate (as shown in screenshots). The faster the rotation is the more substantial the problem becomes.
I tried to mask it by disable face culling, so that the user sees the inside of the cube, which basically has the same colour. However the project manager isn't pleased with that solution (I admitt it doesn't work that well).
The cube has 6 faces, each containing about 242 polygons.
Here are the code snippets relevant to rendering the 3d sceene (I'm using VBO):
public void onDrawFrame(GL10 glUnused)
{
GLES20.glDisable(GLES20.GL_BLEND);
isBlendingEnabled = false;
Matrix.setLookAtM(mViewMatrix, 0, mEyeX, mEyeY, mEyeZ, mLookX, mLookY, mLookZ, mUpX, mUpY, mUpZ);
if(!mSolid.equals(((ActivityMain) mContext).getSolid())){
refreshSolid();
refreshTextureData();
}
if(mSolid.hasChanged){
refreshSolid();
}
if(mSolid.hasTexturesChanged){
refreshTextureData();
mSolid.hasTexturesChanged = false;
}
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Set per-vertex lighting program.
GLES20.glUseProgram(mProgramHandle);
// Set program handles for solid drawing.
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
mLightPosHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_LightPos");
mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color");
mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Texture");
mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
mNormalHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Normal");
mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");
// Calculate position of the light. Handle it's rotation
Matrix.setIdentityM(mLightModelMatrix, 0);
Matrix.translateM(mLightModelMatrix, 0, 0.0f, 0.0f, -2.0f);
Matrix.rotateM(mLightModelMatrix, 0, mAngleInDegrees, 0.0f, 1.0f, 0.0f);
Matrix.translateM(mLightModelMatrix, 0, 0.0f, 0.0f, 3.5f);
Matrix.multiplyMV(mLightPosInWorldSpace, 0, mLightModelMatrix, 0, mLightPosInModelSpace, 0);
Matrix.multiplyMV(mLightPosInEyeSpace, 0, mViewMatrix, 0, mLightPosInWorldSpace, 0);
//Doing that step for each of the faces
for(int i = 0; i < mSolid.get3dMesh().size(); i++){
// Draw a solid.
// Translate the solid into the screen.
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -3.5f);
// Set a matrix that contains the current rotation.
Matrix.setIdentityM(mCurrentRotation, 0);
Matrix.rotateM(mCurrentRotation, 0, mDeltaX, 0.0f, 1.0f, 0.0f);
Matrix.rotateM(mCurrentRotation, 0, mDeltaY, 1.0f, 0.0f, 0.0f);
//handle inertia
if(Math.abs(mDeltaX) > 2f){
mDeltaX = Math.signum(mDeltaX);
mDeltaX = 0.5f*mDeltaX;
}else if(Math.abs(mDeltaX) > 0.05f){
mDeltaX = 0.99f*mDeltaX;
}else
mDeltaX = 0.0f;
if(Math.abs(mDeltaY) > 2f){
mDeltaY = Math.signum(mDeltaY);
mDeltaY = 0.5f*mDeltaY;
}else if(Math.abs(mDeltaY) > 0.05f){
mDeltaY = 0.99f*mDeltaY;
}else
mDeltaY = 0.0f;
// Multiply the current rotation by the accumulated rotation, and then set the accumulated rotation to the result.
Matrix.multiplyMM(mTemporaryMatrix, 0, mCurrentRotation, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, mAccumulatedRotation, 0, 16);
// Rotate the cube taking the overall rotation into account.
Matrix.multiplyMM(mTemporaryMatrix, 0, mModelMatrix, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, mModelMatrix, 0, 16);
// Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle[i]);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
drawCube(i);
}
if(ModelCorePrefs.getDrawMesh())
drawVertices();
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc (GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
isBlendingEnabled = true;
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, 0.0f, -3.5f, -3.5f);
Matrix.scaleM(mModelMatrix, 0, 2f, 1.0f, 2f);
// Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle[mSolid.get3dMesh().size()]);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
drawShadow();
}
The drawCube() method used above:
private void drawCube(int i)
{
// Pass in the position information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mCubePositionsBufferIdx[i]);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, 0, 0);
// Pass in the color information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mCubeColorsBufferIdx[i]);
GLES20.glEnableVertexAttribArray(mColorHandle);
GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false, 0, 0);
// Pass in the normal information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mCubeNormalsBufferIdx[i]);
GLES20.glEnableVertexAttribArray(mNormalHandle);
GLES20.glVertexAttribPointer(mNormalHandle, mNormalDataSize, GLES20.GL_FLOAT, false, 0, 0);
// Pass in the texture coordinate information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mCubeTexCoordsBufferIdx[i]);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0, 0);
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
// Pass in the modelview matrix.
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mTemporaryMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
System.arraycopy(mTemporaryMatrix, 0, mMVPMatrix, 0, 16);
// Pass in the combined matrix.
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Pass in the light position in eye space.
GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
// Draw the cube.
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mSolid.get3dMesh().get(i).length/3);
}
And the screenshot of the problem:
I would strongly suggest you remove the glGet*Location (...) calls from your onDrawFrame (...) method. Those things do not change after you link your program initially, and searching for those locations by string name each frame is going to hinder your performance. Likewise, you only have to set the sampler uniform once per-program since it is always using texture image unit 0.
As for your real issue:
I see no evidence that each face in your loop has its own unique model matrix, so you should move the logic that incrementally transforms the matrix out of the loop. Otherwise you are going to rotate each face in the cube individually, which is what your diagram is showing. To be honest, I do not know why you even have to draw the faces one at a time.
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
// ^^^^^ ONLY DO THAT ONCE!
// Translate the solid into the screen.
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -3.5f);
// Set a matrix that contains the current rotation.
Matrix.setIdentityM(mCurrentRotation, 0);
Matrix.rotateM(mCurrentRotation, 0, mDeltaX, 0.0f, 1.0f, 0.0f);
Matrix.rotateM(mCurrentRotation, 0, mDeltaY, 1.0f, 0.0f, 0.0f);
//handle inertia
if(Math.abs(mDeltaX) > 2f){
mDeltaX = Math.signum(mDeltaX);
mDeltaX = 0.5f*mDeltaX;
}else if(Math.abs(mDeltaX) > 0.05f){
mDeltaX = 0.99f*mDeltaX;
}else
mDeltaX = 0.0f;
if(Math.abs(mDeltaY) > 2f){
mDeltaY = Math.signum(mDeltaY);
mDeltaY = 0.5f*mDeltaY;
}else if(Math.abs(mDeltaY) > 0.05f){
mDeltaY = 0.99f*mDeltaY;
}else
mDeltaY = 0.0f;
// Multiply the current rotation by the accumulated rotation, and then set the accumulated rotation to the result.
Matrix.multiplyMM(mTemporaryMatrix, 0, mCurrentRotation, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, mAccumulatedRotation, 0, 16);
// Rotate the cube taking the overall rotation into account.
Matrix.multiplyMM(mTemporaryMatrix, 0, mModelMatrix, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, mModelMatrix, 0, 16);
//Doing that step for each of the faces
for(int i = 0; i < mSolid.get3dMesh().size(); i++){
// Draw a solid.
// Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle[i]);
drawCube(i);
}

Fatal signal on glDrawArrays within onDrawFrame (GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener)

I am getting a Fatal Signal 11 after quite a few
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
calls within my OnDrawFrame function. The textures are been drawn correctly before the crash, which I believe it means that my vertex and fragment shaders work fine.
What I am trying to do, is to blend two textures together using GLSurfaceView.Renderer and SurfaceTexture.OnFrameAvailableListener.
The first texture is a live camera preview SurfaceTexture which works fine by its own. The second tetxure is just a bitmap image, which also works fine by its own. but combining them gives the crash.
My OnDrawFrame is as follows:
public void onDrawFrame(GL10 glUnused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
synchronized(this) {
if (updateSurface) {
mSurface.updateTexImage();
mSurface.getTransformMatrix(mSTMatrix);
updateSurface = false;
}
}
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio");
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
int t1h = GLES20.glGetUniformLocation ( mProgram, "sTexture1" );
// GLES20.glUniform1i(t1h, textures[0]);
GLES20.glUniform1i(t1h, 1);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
int t2h = GLES20.glGetUniformLocation ( mProgram, "sTexture2" );
GLES20.glUniform1i(t2h, 2);
GLES20.glUseProgram(mProgram);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
mTriangleVertices.position(0);
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
4*5, mTriangleVertices);
mTriangleVertices.position(3);
GLES20.glEnableVertexAttribArray(maTextureHandle);
GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
4*5, mTriangleVertices);
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
GLES20.glUniform1f(muCRatioHandle, mCameraRatio);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDisableVertexAttribArray(maPositionHandle);
GLES20.glDisableVertexAttribArray(maTextureHandle);
// GLES20.glFlush();
}
where mTriangleVertices is:
mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length
* FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
mTriangleVertices.put(mTriangleVerticesData).position(0);
and mTriangleVerticesData is:
private final float[] mTriangleVerticesData = {
// X, Y, Z, U, V
-1.0f, -1.0f, 0, 0.f, 0.f,
1.0f, -1.0f, 0, 1.f, 0.f,
-1.0f, 1.0f, 0, 0.f, 1.f,
1.0f, 1.0f, 0, 1.f, 1.f,
};
Any tips, links or even code snippets would be much appreciated!
Thank you in advance
Don't know if this is the cause for the crash but you're assigning one too high texture ids for shader at least. For example;
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
int t1h = GLES20.glGetUniformLocation ( mProgram, "sTexture1" );
GLES20.glUniform1i(t1h, 1);
Should read
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
int t1h = GLES20.glGetUniformLocation ( mProgram, "sTexture1" );
GLES20.glUniform1i(t1h, 0);
Edit: Ah, this might be the cause for the crash:
GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
4*5, mTriangleVertices);
It should be
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
4*5, mTriangleVertices);
More likely since you have two texture values per vertex.

How to display sky sphere?

I need to position sky sphere in 3D space right where camera is.
I set up camera as follows:
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
// Ignore the passed-in GL10 interface, and use the GLES20
// class's static methods instead.
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2, 1000);
}
...
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
...
Sphere has a diameter of 100 units and it's center is in (0;0;0).
The method to draw a sphere:
private void drawSphere() {
//Matrix.setLookAtM(mVMatrix, 0, 0, 0, 0, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
mTriangleVerticesSphere.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVerticesSphere);
mTriangleVerticesSphere.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVerticesSphere);
GLES20.glEnableVertexAttribArray(maTextureHandle);
Matrix.setRotateM(mMMatrix, 0, jitterX, 1.0f, 0, 0);
Matrix.rotateM(mMMatrix, 0, angleYaw + jitterY, 0, 1.0f, 0);
Matrix.scaleM(mMMatrix, 0, 0.01f, 0.01f, 0.01f);
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, numPolysSphere);
}
This code displays a sphere. Backface culling is disabled, and I can see both sides of sphere (texture has transparent parts).
In order to display sphere right in the camera position I try to move camera. But if I uncomment Matrix.setLookAtM(mVMatrix, 0, 0, 0, 0, 0f, 0f, 0f, 0f, 1.0f, 0.0f) in the beginning of drawSphere() it doesn't display anything. May be it has something to do with clipping planes?
Please give an example how to position the sphere correctly.
I think your more looking to do something like
Matrix.setLookAtM(mvMatrix, 0, 0, 0, 10, 0, 0, 0, 0, 1, 0);
if I'm not wrong opengl doesn't know which way its looking at
your asking too look for (0,0,0) towards (0,0,0) while oriented towards (0,1.0,0)
OK, so I figured out how to do it.
1. Look at correct angle.
3. Draw sky sphere.
2. Clear Z-buffer.
3. Reposition camera.
4. Draw the rest.

Categories

Resources