Note that there are some explanatory texts on larger screens.

plurals
  1. POOpenGL texture not following geometry
    primarykey
    data
    text
    <p>I'm struggling with the jump in complexity from OpenGL ES 1.x to 2.0. I'm trying to apply a texture to a rectangular plane and then be able to scale and translate that plane while keeping the texture properly mapped. </p> <p>My question is: what am I doing wrong and how will I be able to texture my planes while translating and scaling them? </p> <p>I will post my renderer class, the class that objects will use to draw themselves, and my vertex and fragment shaders:</p> <p>GL Renderer:</p> <pre><code>package com.detour.raw; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.graphics.Bitmap; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.Matrix; public class GameRenderer implements GLSurfaceView.Renderer{ private static final String TAG = "GameRenderer"; Context mContext; Bitmap bitmap; private float red = 0.5f; private float green = 0.5f; private float blue = 0.5f; Shader shader; int program; FPSCounter fps; Sprite sprite; Sprite sprite2; int x = 0; private int muMVPMatrixHandle; private float[] mMVPMatrix = new float[16]; private float[] mProjMatrix = new float[16]; private float[] mMVMatrix = new float[16]; //private float[] mVMatrix = new float[16]; //private float[] mMMatrix = new float[16]; //private float[] mVPMatrix = new float[16]; //private float[] mIMatrix = new float[16]; public GameRenderer(Context context){ mContext = context; //create objects/sprites sprite = new Sprite(mContext); sprite2 = new Sprite(mContext); fps = new FPSCounter(); } @Override public void onDrawFrame(GL10 gl) { GLES20.glClearColor(red, green, blue, 1.0f); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); GLES20.glUseProgram(program); //Matrix.setIdentityM(mIMatrix, 0); //Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mMMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVMatrix , 0); GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); sprite.draw(); /*if(x&gt;3){ x=0; } if(x%2==0){ sprite.draw(); }else{ sprite2.draw(); } x++;*/ //fps.calculate(); //fps.draw(gl); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0, 0, width, height); float ratio = ((float)(width))/((float)(height)); Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 0.5f, 10); Matrix.setLookAtM(mMVMatrix, 0, 0, 0, 1.0f, 0.0f, 0f, 0f, 0f, 1.0f, 0.0f); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub /*int error = GLES20.glGetError(); Log.d(LOG_TAG, ""+error);*/ shader = new Shader(R.raw.sprite_vs, R.raw.sprite_fs, mContext); program = shader.getProgram(); muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "u_MVPMatrix"); GLES20.glEnable(GLES20.GL_TEXTURE_2D); GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glClearDepthf(1.0f); GLES20.glDepthFunc(GLES20.GL_LEQUAL); GLES20.glDepthMask(true); GLES20.glEnable(GLES20.GL_CULL_FACE); GLES20.glCullFace(GLES20.GL_BACK); GLES20.glClearColor(red, green, blue, 1.0f); sprite.loadGLTexture(R.drawable.raw1a, program); sprite2.loadGLTexture(R.drawable.raw2, program); System.gc(); } } </code></pre> <p>Drawable class:</p> <pre><code>package com.detour.raw; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES20; import android.opengl.GLUtils; public class RenderVisible implements Renderable{ Context mContext; Bitmap bitmap; private int vertexHandle; private int texCoordHandle; private int textureHandle; private int[] textures = new int[1]; private float textureCoordinates[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }; private float vertices[] = { -1.0f, 1.0f,// 0.0f, -1.0f, -1.0f,// 0.0f, 1.0f, -1.0f,// 0.0f, 1.0f, 1.0f// 0.0f, }; private short[] indices = { 0, 1, 2, 0, 2, 3}; private FloatBuffer vertexBuffer; private FloatBuffer textureBuffer; private ShortBuffer indexBuffer; public RenderVisible(Context context){ mContext = context; ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); vertexBuffer = vbb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCoordinates.length * 4); byteBuf.order(ByteOrder.nativeOrder()); textureBuffer = byteBuf.asFloatBuffer(); textureBuffer.put(textureCoordinates); textureBuffer.position(0); ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indices); indexBuffer.position(0); } @Override public void draw() { GLES20.glEnableVertexAttribArray(vertexHandle); GLES20.glVertexAttribPointer(vertexHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, textureBuffer); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer); } @Override public void loadGLTexture(int id, int program) { vertexHandle = GLES20.glGetAttribLocation(program, "a_position"); texCoordHandle = GLES20.glGetAttribLocation(program, "a_texcoord"); textureHandle = GLES20.glGetUniformLocation(program, "u_texture"); bitmap = BitmapFactory.decodeResource(mContext.getResources(), id); /*InputStream is = mContext.getResources().openRawResource(id); try { bitmap = BitmapFactory.decodeStream(is); } finally { try { is.close(); is = null; } catch (IOException e) { } }*/ GLES20.glGenTextures(1, textures, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); GLES20.glUniform1i(textureHandle, 0); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); //GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, FRAME_WIDTH, FRAME_HEIGHT, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf);//(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); } } </code></pre> <p>Fragment Shader:</p> <pre><code>precision mediump float; uniform sampler2D u_texture; varying vec2 v_texcoord; void main() { gl_FragColor = texture2D(u_texture, v_texcoord); } </code></pre> <p>Vertex Shader:</p> <pre><code>attribute vec2 a_position; attribute vec2 a_texcoord; uniform mat4 u_MVPMatrix; varying vec2 v_texcoord; void main() { gl_Position = vec4(a_position, 0.0, 1.0) * u_MVPMatrix; v_texcoord = a_position * vec2(0.5, -0.5) + vec2(0.5); } </code></pre> <p>When I run the program like this, I get my expected result:</p> <p><img src="https://i.stack.imgur.com/0Gfwr.png" alt="enter image description here"></p> <p>When I change the vertices of my renderable (in this case all divided each value by 2), the shape of my plane changes but the texture doesn't move with it the way I would expect. I'm not sure why (an explanation would be nice).</p> <p><img src="https://i.stack.imgur.com/fOB20.png" alt="enter image description here"></p> <p>When I fix the vertices of my plane and change the vertex shader to accept the texture coordinates I give it (<code>v_texcoord = a_texcoord;</code>), I get the correct size square but the texture isn't visible/the square is completely white.</p> <p>I am also attempting to make methods for the renderable (RenderVisible) class that would make it simple to move and scale my sprites. How might I do that?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload