Android OpenGL | ES 2.0纹理
我正在使用OpenGL | ES 2.0创建一个简单的二维正方形。我正在努力使纹理正常工作。请在这方面帮助我。我已附上以下代码: GFXUtils:Android OpenGL | ES 2.0纹理,android,textures,opengl-es-2.0,Android,Textures,Opengl Es 2.0,我正在使用OpenGL | ES 2.0创建一个简单的二维正方形。我正在努力使纹理正常工作。请在这方面帮助我。我已附上以下代码: GFXUtils: public class GFXUtils { public static final String TAG = "GFXUtils"; public static final int COORDS_PER_VERTEX = 3; public static final int COORDS_PER_TEXTURE
public class GFXUtils {
public static final String TAG = "GFXUtils";
public static final int COORDS_PER_VERTEX = 3;
public static final int COORDS_PER_TEXTURE = 2;
public static int vertexStride = COORDS_PER_VERTEX * 4; // bytes per vertex
public static int textureStride = COORDS_PER_TEXTURE * 4; // bytes per vertex
public static Context Context = null;
public static SparseIntArray textures = new SparseIntArray();
public static int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
public static void checkGlError(String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, glOperation + ": glError " + error);
throw new RuntimeException(glOperation + ": glError " + error);
}
}
public static void loadTexture(final int resourceId)
{
final int[] textureHandle = new int[1];
GLES20.glGenTextures(1, textureHandle, 0);
if (textureHandle[0] != 0)
{
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false; // No pre-scaling
// Read in the resource
final Bitmap bitmap = BitmapFactory.decodeResource(Context.getResources(), resourceId, options);
// Bind to the texture in OpenGL
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Recycle the bitmap, since its data has been loaded into OpenGL.
bitmap.recycle();
}
if (textureHandle[0] == 0)
{
throw new RuntimeException("Error loading texture.");
}
textures.append(resourceId, textureHandle[0]);
}
}
顶点:
public class Vertex
{
public FloatBuffer floatBuffer; // buffer holding the vertices
public ShortBuffer indexBuffer;
public int numVertices;
public int numIndeces;
//public float vertex[];
public Vertex (float[] vertex, int coordsPerVertex)
{
//this.vertex = vertex;
this.setVertices(vertex, coordsPerVertex);
}
public Vertex (float[] vertex, short[] indices, int coordsPerVertex)
{
//this.vertex = vertex;
this.setVertices(vertex, coordsPerVertex);
this.setIndices(indices);
}
private void setVertices(float vertex[], int coordsPerVertex)
{
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer factory = ByteBuffer.allocateDirect (vertex.length * 4);
factory.order (ByteOrder.nativeOrder ());
// allocates the memory from the byte buffer
floatBuffer = factory.asFloatBuffer ();
// fill the vertexBuffer with the vertices
floatBuffer.put (vertex);
// set the cursor position to the beginning of the buffer
floatBuffer.position (0);
numVertices = vertex.length / coordsPerVertex;
}
protected void setIndices(short[] indices) {
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
numIndeces = indices.length;
}
}
更新方形:
public class Square{
private static final String TAG = "Square";
public float[] rotation = {0.0f,0.0f,45.0f};
public float[] scale = {100.0f,100f,100f};
public float[] position = {0.0f,0.0f,100f};
public float[] color = { 0.0f, 0.0f, 1.0f, 1.0f };
private int textureRef = -1;
private int mMVPMatrixHandle;
protected int DRAW_MODE = GLES20.GL_TRIANGLES;
protected int mProgram;
protected int mPositionHandle;
protected Vertex vertices;
protected Vertex texture;
private int mColorHandle;
private int vsTextureCoord;
private int fsTexture;
protected float[] result_matrix = new float[16];
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"attribute vec2 TexCoordIn;" +
"varying vec2 TexCoordOut;" +
"void main() {" +
//the matrix must be included as a modifier of gl_Position
" gl_Position = uMVPMatrix * vPosition;" +
" TexCoordOut = TexCoordIn;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"uniform sampler2D Texture;" +
"varying lowp vec2 TexCoordOut;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
//I am fully aware that I am not using the texture by assigning the colour, but until I can actually SEND the texture through, there would be no point.
static float squareCoords[] = { -0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f }; // top right
private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
public Square(int textureResourceId) {
int vertexShader = GFXUtils.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = GFXUtils.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // creates OpenGL ES program executables
textureRef = GFXUtils.textures.get(textureResourceId);
// initialize vertex byte buffer for shape coordinates
vertices = new Vertex(squareCoords, drawOrder, GFXUtils.COORDS_PER_VERTEX);
texture = new Vertex (new float[]
{
1.0f, 0.0f,
0.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
}, GFXUtils.COORDS_PER_TEXTURE);
DRAW_MODE = GLES20.GL_TRIANGLE_FAN;
}
private void getHandles()
{
//get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
if (mPositionHandle == -1) Log.e(TAG, "vPosition not found");
//get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
if (mColorHandle == -1) Log.e(TAG, "vColor not found");
//get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
if (mMVPMatrixHandle == -1) Log.e(TAG, "uMVPMatrix not found");
//get handle to texture coordinate variable
vsTextureCoord = GLES20.glGetAttribLocation(mProgram, "TexCoordIn");
if (vsTextureCoord == -1) Log.e(TAG, "TexCoordIn not found");
//get handle to shape's texture reference
fsTexture = GLES20.glGetUniformLocation(mProgram, "Texture");
if (fsTexture == -1) Log.e(TAG, "Texture not found");
}
private void translateRotateScale(float[] matrix, float[] perspectiveMatrix)
{
for (int i= 0; i < perspectiveMatrix.length;i++)
matrix[i] = perspectiveMatrix[i];
Matrix.translateM(matrix, 0, position[0], position[1], position[2]);
Matrix.rotateM(matrix, 0, rotation[0], 1.0f, 0.0f, 0.0f);
Matrix.rotateM(matrix, 0, rotation[1], 0.0f, 1.0f, 0.0f);
Matrix.rotateM(matrix, 0, rotation[2], 0.0f, 0.0f, 1.0f);
Matrix.scaleM(matrix, 0, scale[0], scale[1], scale[2]);
}
public void draw(float[] mvpMatrix) {
rotation[2]+=0.5;
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram);
GFXUtils.checkGlError("using program");
//Housekeeping
getHandles();
translateRotateScale(result_matrix, mvpMatrix);
//end housekeeping
// Set color for drawing the shape
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, result_matrix, 0);
GFXUtils.checkGlError("glUniformMatrix4fv");
// Prepare the shape coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, GFXUtils.COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
GFXUtils.vertexStride, vertices.floatBuffer);
GFXUtils.checkGlError("load vertex buffer");
GLES20.glVertexAttribPointer(vsTextureCoord, GFXUtils.COORDS_PER_TEXTURE,
GLES20.GL_FLOAT, false,
GFXUtils.textureStride, texture.floatBuffer);
GFXUtils.checkGlError("load texture buffer - " + vsTextureCoord);
// Enable a handle to the shape vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
GFXUtils.checkGlError("enable position handle");
GLES20.glEnableVertexAttribArray(vsTextureCoord);
GFXUtils.checkGlError("enable texture handle");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GFXUtils.checkGlError("activtexture");
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureRef);
GFXUtils.checkGlError("bindtexture");
GLES20.glUniform1i(fsTexture, 0);
GFXUtils.checkGlError("uniformi");
//Draw the shape
GLES20.glDrawElements(DRAW_MODE, vertices.numIndeces, GLES20.GL_UNSIGNED_SHORT, vertices.indexBuffer);
GFXUtils.checkGlError("glDrawArrays with " + vertices.numVertices + " vertices");
//Disable vertex array
GLES20.glDisableVertexAttribArray(vsTextureCoord);
GLES20.glDisableVertexAttribArray(mPositionHandle);
GFXUtils.checkGlError("glDisableVertexAttribArray for position");
}
}
公共类广场{
私有静态最终字符串TAG=“Square”;
公共浮点[]旋转={0.0f,0.0f,45.0f};
公共浮动[]比例={100.0f,100f,100f};
公共浮动[]位置={0.0f,0.0f,100f};
公共浮动[]颜色={0.0f,0.0f,1.0f,1.0f};
私有int-textureRef=-1;
私有int mMVPMatrixHandle;
受保护的int-DRAW_模式=GLES20.GL_三角形;
受保护的int程序;
受保护的int-mPositionHandle;
保护顶点;
保护顶点纹理;
米科洛汉德尔私人酒店;
私有int VSTextureCord;
私有纹理;
受保护浮点[]结果_矩阵=新浮点[16];
私有最终字符串vertexShaderCode=
“统一mat4 UMVP矩阵;”+
“属性向量4位置;”+
“属性vec2 TexCoordIn;”+
“可变矢量2 TexCoordOut;”+
“void main(){”+
//矩阵必须包含为gl_位置的修改器
“gl_Position=uMVPMatrix*vpposition;”+
“TexCoordOut=TexCoordIn;”+
"}";
私有最终字符串碎片ShaderCode=
“精密中泵浮动;”+
“统一vec4彩色;”+
“均匀的二维纹理;”+
“可变低矢量2 TexCoordOut;”
“void main(){”+
“gl_FragColor=vColor;”+
"}";
//我完全知道,我不是通过指定颜色来使用纹理,但在我能够实际发送纹理之前,没有任何意义。
静态浮点方坐标[]={-0.5f,0.5f,0.0f,//左上角
-0.5f,-0.5f,0.0f,//左下角
0.5f,-0.5f,0.0f,//右下角
0.5f,0.5f,0.0f};//右上角
private short drawOrder[]={0,1,2,0,2,3};//绘制顶点的顺序
公共广场(int-textureResourceId){
int vertexShader=GFXUtils.loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
int fragmentShader=GFXUtils.loadShader(GLES20.GL_FRAGMENT_着色器,fragmentShaderCode);
mProgram=GLES20.glCreateProgram();//创建空的OpenGL ES程序
GLES20.glAttachShader(mProgram,vertexShader);//将顶点着色器添加到程序中
GLES20.glAttachShader(mProgram,fragmentShader);//将片段着色器添加到程序中
GLES20.glLinkProgram(mProgram);//创建OpenGL ES程序可执行文件
textureRef=GFXUtils.textures.get(textureResourceId);
//初始化形状坐标的顶点字节缓冲区
顶点=新顶点(正方形坐标、绘图顺序、GFXUtils.COORDS每顶点);
纹理=新顶点(新浮点[]
{
1.0f,0.0f,
0.0f,0.0f,
1.0f,1.0f,
0.0f,1.0f,
},GFXUtils.COORDS_PER_纹理);
DRAW_MODE=GLES20.GL_三角形_风扇;
}
私有void getHandles()
{
//获取顶点着色器的vPosition成员的句柄
mPositionHandle=GLES20.glGetAttriblLocation(mProgram,“vPosition”);
if(mPositionHandle==-1)Log.e(标记“vpositionnotfound”);
//获取片段着色器的vColor成员的句柄
mColorHandle=GLES20.glGetUniformLocation(mProgram,“vColor”);
if(mColorHandle==-1)Log.e(标记“vColor not found”);
//获取形状变换矩阵的句柄
mMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram,“uMVPMatrix”);
if(mMVPMatrixHandle==-1)Log.e(标记“umvpmatrixnotfound”);
//获取纹理坐标变量的句柄
vsTextureCoord=GLES20.glGetAttribLocation(mProgram,“TexCoordIn”);
if(vsTextureCoord==-1)Log.e(标记“TexCoordIn not found”);
//获取形状的纹理引用的句柄
fsTexture=GLES20.glGetUniformLocation(mProgram,“纹理”);
if(fsTexture==-1)Log.e(标记“未找到纹理”);
}
私有void translaterState量表(float[]矩阵,float[]透视矩阵)
{
对于(int i=0;i