Хочу в OpenGL ES отрисовать текстуру.
Текстура размером 256х256 png с альфа-каналом.
Извините, что в наглую кидаю код, просто два дня уже не могу с этим разобраться(
Шейдеры работают правильно, но в строчке:
texture2D(tex, texCoordOut);
всегда возвращается черный цвет. В общем, тут и проблема.
Шейдеры
<string name="vertexShader">
uniform mat4 MVPMatrix;
attribute vec4 vPos;
attribute vec2 texCoordIn;
varying vec2 texCoordOut;
void main()
{
gl_Position = MVPMatrix * vPos ;
texCoordOut = texCoordIn;
}
</string>
<string name="fragmentShader">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoordOut;
void main()
{
gl_FragColor = texture2D(tex, texCoordOut);
}
</string>
Код рендерера
package hakito.opengltest;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20.*;
/**
* Created by Oleg on 22-Jan-16.
*/
public class SimpleRenderer implements GLSurfaceView.Renderer {
float[] verticesData =new float[]
{
1, 1, 0, 1, 1,
1, -1, 0, 1, 0,
-1, -1, 0, 0, 0,
-1, 1, 0, 0, 1
};
byte[] indicesData = new byte[]{
0, 2, 1,
0, 3, 2
};
int[] textures = new int[1];
private float[] mViewMatrix = new float[16];
private float[] mProjectionMatrix = new float[16];
private float[] mModelMatrix = new float[16];
private float[] mMVPMatrix = new float[16];
FloatBuffer vBuffer;
ByteBuffer iBuffer;
Bitmap ballBitmap;
int bytesPerFloat=4;
int positionHandle, MVPMatrixHandle;
int coordsPerVertex=3, coordsPerTexture=2;
int vSize=bytesPerFloat*coordsPerVertex, tSize=bytesPerFloat*coordsPerTexture;
int vertexStride = vSize+tSize;
String vShader, pShader;
int vShaderHandle, pShaderHandle, programmHandle;
public SimpleRenderer(Context context) {
vShader=context.getString(R.string.vertexShader);
pShader = context.getString(R.string.fragmentShader);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
ballBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ball, options);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
final float eyeX = 0.0f;
final float eyeY = 0.0f;
final float eyeZ = 1.5f;
final float lookX = 0.0f;
final float lookY = 0.0f;
final float lookZ = 0f;
final float upX = 0.0f;
final float upY = 1.0f;
final float upZ = 0.0f;
Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
vBuffer = ByteBuffer.allocateDirect(bytesPerFloat * verticesData.length).order(ByteOrder.nativeOrder()).asFloatBuffer().put(verticesData);
vBuffer.position(0);
iBuffer = ByteBuffer.allocateDirect(bytesPerFloat * indicesData.length).order(ByteOrder.nativeOrder()).put(indicesData);
iBuffer.position(0);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
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.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLUtils.getInternalFormat(ballBitmap), ballBitmap, 0);
vShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vShaderHandle, vShader);
GLES20.glCompileShader(vShaderHandle);
pShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(pShaderHandle, pShader);
GLES20.glCompileShader(pShaderHandle);
programmHandle = GLES20.glCreateProgram();
GLES20.glAttachShader(programmHandle, vShaderHandle);
GLES20.glAttachShader(programmHandle, pShaderHandle);
GLES20.glLinkProgram(programmHandle);
GLES20.glReleaseShaderCompiler();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, width);
GLES20.glClearColor(0.99f, 0.01f, 0, 1);
final float ratio = (float) width / height;
final float left = -ratio;
final float right = ratio;
final float bottom = -1.0f;
final float top = 1.0f;
final float near = 0.3f;
final float far = 10.0f;
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
}
@Override
public void onDrawFrame(GL10 gl) {
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(programmHandle);
positionHandle = GLES20.glGetAttribLocation(programmHandle, "vPos");
GLES20.glEnableVertexAttribArray(positionHandle);
int textureCoordHandle = GLES20.glGetAttribLocation(programmHandle, "texCoordIn");
GLES20.glEnableVertexAttribArray(textureCoordHandle);
vBuffer.position(0);
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, vertexStride, vBuffer);
vBuffer.position(3);
GLES20.glVertexAttribPointer(textureCoordHandle, 2, GLES20.GL_FLOAT, false, vertexStride, vBuffer);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
int textureHandle = GLES20.glGetUniformLocation(programmHandle, "tex");
GLES20.glUniform1i(textureHandle,0);
MVPMatrixHandle = GLES20.glGetUniformLocation(programmHandle, "MVPMatrix");
GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indicesData.length, GLES20.GL_UNSIGNED_BYTE, iBuffer);
GLES20.glDisableVertexAttribArray(positionHandle);
GLES20.glDisableVertexAttribArray(textureCoordHandle);
}
}