OpenGL-es projection doesn't seem to work - android

I've tried following the lessons about drawing shapes and applying projections to them as found here, but the projection just doesn't seem to work. As far as I know I've copy-pasted all the pieces of code in my project, here are the important code parts:
In my Renderer class:
#Override
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// Set the camera position (View matrix)
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
// Draw shape
mTriangle.draw(mMVPMatrix);
}
#Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}
The draw method of my Triangle class:
public void draw(float[] mvpMatrix) {
GLES20.glUseProgram(mProgram);
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); // get handle to vertex shader's vPosition member
GLES20.glEnableVertexAttribArray(mPositionHandle); // Enable a handle to the triangle vertices
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer); // Prepare the triangle coordinate data
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); // get handle to fragment shader's vColor member
GLES20.glUniform4fv(mColorHandle, 1, color, 0); // Set color for drawing the triangle
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); // get handle to shape's transformation matrix
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); // Apply the projection and view transformation
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); // Draw the triangle
GLES20.glDisableVertexAttribArray(mPositionHandle); // Disable vertex array
}
The triangle still is being stretched. What am I doing wrong?

Did you try to debug in onSurfaceChanged? What happens in those lines? Especially:
what are the passed values width and height?
which value does float ratio = (float) width / height; calculate?
do you see any changes to the values of mProjMatrix after the call Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);?
how does your private final String fragmentShaderCode in class Triangle look like? As the order of the multiplication in the line " gl_Position = uMVPMatrix * vPosition;" + is important.
Your provided code looks quiet good, difficult issue here.

Related

How do I apply projection and camera views in OpenGL ES?

I tried applying projection and camera views according to the official documentation (https://developer.android.com/training/graphics/opengl/projection#kotlin). Unfortunately I got an empty screen instead of regular triangle. Below are my onSurfaceCreated and onDrawFrame functions. I populate a projection transformation matrix not in the onSurfaceChanged function (as it is shown in the docs) because I have it never called in my app (in that case the result was the same).
override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
mTriangle = Triangle()
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
}
override fun onDrawFrame(unused: GL10) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
// Set the camera position (View matrix)
Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
// Calculate the projection and view transformation
Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
// Draw shape
mTriangle.draw(vPMatrix)
}
Then I came up with rewriting my draw function. Firstly I set vertexShaderCode as it was said in the docs.
private val vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" gl_Position = uMVPMatrix * vPosition;" +
"}"
Secondly I changed the function itself:
fun draw(mvpMatrix: FloatArray) { // pass in the calculated transformation matrix
// get handle to shape's transformation matrix
vPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix")
// Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0)
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount)
// Disable vertex array
GLES20.glDisableVertexAttribArray(positionHandle)
}
I got an empty screen... Then I tried to combine code above and working version of it. I got:
fun draw(mvpMatrix: FloatArray) {
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram)
// get handle to vertex shader's vPosition member
positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition").also {
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(it)
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(
it,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
vertexStride,
vertexBuffer
)
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor").also { colorHandle ->
// Set color for drawing the triangle
GLES20.glUniform4fv(colorHandle, 1, color, 0)
}
// get handle to shape's transformation matrix
vPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
// Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0)
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount)
// Disable vertex array
GLES20.glDisableVertexAttribArray(it)
}
}
This didn't work too. How can I get my triangle drawn?
P.S.
Changing 3f->2f->1f for "near" value at Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f) does nothing
Using gl_Position = vPosition; instead of gl_Position = uMVPMatrix * vPosition; in the vertexShaderCode with second (big) version of draw function gives the triangle. Problem seems to be with matrices.
Okay, finally it works!
Used Matrix.frustumM(projectionMatrix, 0, -1.5f, 1.5f, -1f, 1f, 1f, 7f) and maybe everything the same as above is.

Drawn shape on SurfaceView is not getting translucent

I used GL10 SurfaceView and drawn squares on it. But i want squares to be translucent to view the background. I used
// set color
gl.glColor4f(color[0], color[1], color[2], color[3]/*alpha*/);
but decreasing alpha results the square darker, not translucent.
I've also applied Blending options
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glAlphaFunc(GL10.GL_GREATER, 0);
gl.glEnable(GL10.GL_ALPHA_TEST);
but nothing works.
EDIT / ADDED
used GL configuration for translucent
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
// this.getHolder().setFormat( PixelFormat.RGBA_8888 );
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
mRenderer = new MyGLRenderer();
mRenderer.context = context;
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
for plane Construct
float squareCoords[] = { x, 0f, lenght, // top left
x, 0f, 0.0f, // bottom left
x - 6, 0f, 0.0f, // bottom right
x - 6, 0f, lenght }; // top right
ByteBuffer bb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
squareCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareCoords);
vertexBuffer.position(0);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
forAddingPlaneShape onDraw()
public void draw(GL10 gl) {
//color = colorP;
// Since this shape uses vertex arrays, enable them
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// draw the shape
gl.glColor4f( // set color
color[0], color[1], color[2], color[3]);
// gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
gl.glVertexPointer( // point to vertex data:
COORDS_PER_VERTEX, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(
// draw shape:
GL10.GL_TRIANGLES, drawOrder.length, GL10.GL_UNSIGNED_SHORT,
drawListBuffer);
// Disable vertex array drawing to avoid
// conflicts with shapes that don't use it
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
In My Renderer
onDrawFrame(gl)
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Set GL_MODELVIEW transformation mod
gl.glMatrixMode(GL10.GL_MODELVIEW);
//
gl.glLoadIdentity(); // reset the matrix to its default state
gl.glEnable(GL10.GL_NORMALIZE);
// draw plane
for (SimplePlane plane : simplePlanes) {
plane.draw(gl);
}
in onSurfaceChanged(gl,height,width)
gl.glViewport(0, 0, width, height);
// make adjustments for screen ratio
gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
gl.glLoadIdentity(); // reset the matrix to its default state
GLU.gluPerspective(gl, 75, ratio, 3, 10000);
// if (ratio >= 1.0f)
// gl.glFrustumf(0, 0, 0, 0, 0, -100.0f); //Landscape
// else
// gl.glFrustumf(-1, 1, -1 / ratio, 1 / ratio, 1, 300); //Portrait
// gl.glFrustumf(-ratio, ratio, -1, 1, 0.1f, 1000); // apply the
// projection matrix
gl.glDisable(GL10.GL_DITHER);
// gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0, 0, 0, 0);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
// gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glAlphaFunc(GL10.GL_GREATER, 0);
gl.glEnable(GL10.GL_ALPHA_TEST);
The exact demonstration given in picture.
Advanced help would be appreciated !!

Does not translate well - Android - OpenGL ES 2

I have this code that should move my circle( square):
float[] scratch = new float[16];
float[] move = new float[16];
Matrix.setIdentityM(move, 0);
Matrix.translateM(move, 0, 100, 100, 0);
Matrix.multiplyMM(scratch, 0, projectionMatrix, 0, move, 0);
mCircle.draw(scratch);
projectionMatrix is the camera:
Matrix.orthoM(projectionMatrix, 0, 0, width, height, 0, -1f, 1f);
But when I execute the code I get this:
Image
I followed the code from Android Developer.
precision highp float;
uniform float uRadius;
vec2 center = vec2(uRadius, uRadius);
vec2 coord = vec2(gl_FragCoord.x, 1080. - gl_FragCoord.y);
vec2 position = coord - center;
uniform vec4 uColor;
void main()
{
if (length(position) > uRadius) {
discard;
}
gl_FragColor = uColor;
}
--------------------------------
uniform mat4 uMatrix;
attribute vec4 aPosition;
void main()
{
gl_Position = uMatrix * aPosition;
}
My main loop:
public void onDrawFrame(GL10 unused) {
// Draw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
float[] scratch = new float[16];
float[] move = new float[16];
Matrix.setIdentityM(move, 0);
Matrix.translateM(move, 0, 50, 50, 0);
Matrix.multiplyMM(scratch, 0, projectionMatrix, 0, move, 0);
mCircle.draw(scratch);
}
And circle draw functions is:
public void draw(float[] projectionMatrix) {
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
int mColorHandle = GLES20.glGetUniformLocation(mProgram, "uColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, mColor, 0);
int radiusHandle = GLES20.glGetUniformLocation(mProgram, "uRadius");
MyGLRenderer.checkGlError("glGetUniformLocation");
GLES20.glUniform1f(radiusHandle, mRadius);
// get handle to shape's transformation matrix
int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMatrix");
MyGLRenderer.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, projectionMatrix, 0);
MyGLRenderer.checkGlError("glUniformMatrix4fv");
// Draw the square
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
After some hours I finally found the logical error in the fragment shader: the center of the circle was remaining the same, now I added 2 more uniforms for the offsets/position and it's working.

Projection and Camera View doesn't work on OpenGL

I'm trying to apply projection and camera views, but I am not getting the wanted result. The drawn triangle still gets deformed when I rotate my device from portrait to landscape mode. This is the draw() method from my Triangle class:
public void draw(float[] mvpMatrix) {
int vertexCount = 3;
int vertexStride = 3 * COORDS_PER_VERTEX;
int mMVPMatrixHandle;
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
I don't know why it doesn't work, there is also my onDrawFrame() and onSurfaceChanged() methods from the Renderer class:
private float[] mProjectionMatrix = new float[16]
private float[] mViewMatrix = new float[16];
private float[] mMVPMatrix = new float[16];
public void onDrawFrame(GL10 unused) {
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Set the camera position (View matrix)
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
// Draw shape
mTriangle.draw(mMVPMatrix);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}
Some code is missing, here is what should be added :
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition * uMVPMatrix;" +
"}";

Strange beahviours with texture drawing in opengl android

I am drawing texture in opengl using Triangles and vertices
when it is drawn it is something like this
Problem is it is drawing same triangle on both sides?
what's the solution to this?
here is my code?
public float m_cameraX=26.036f;
public float m_cameraY=45.126f;
public float m_cameraZ=5f;
private final float[][] vertData = {
{
25.457f, 45.534f, 3.0f,
26.595f, 45.534f, 3.0f,
25.457f, 44.718f, 3.0f,
26.595f, 44.718f, 3.0f
};
vertBuffer = ByteBuffer.allocateDirect(12 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertBuffer.put(vertData[i]).position(0);
loadtexture();
vertBuffer.position(0);
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, vertBuffer);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, imgHandle);
GLES20.glUniform1i(mColorHandle, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
You need to set texture coordinates. Check out these tutorials:
http://obviam.net/index.php/texture-mapping-opengl-android-displaying-images-using-opengl-and-squares/
http://insanitydesign.com/wp/projects/nehe-android-ports/
http://www.learnopengles.com/android-lesson-four-introducing-basic-texturing/

Categories

Resources