【发布时间】:2016-08-01 14:20:48
【问题描述】:
我需要在 Android 设备上渲染大小为 1000x800 的图像。如果我创建 2x2 图像的宽度和高度,则可以正确渲染。如果任何超过此尺寸(即 2x2)的图像无法正确显示,则纹理似乎被抓取。我正在使用 Opengl ES 2.0。我尝试以各种方式设置 orthoM 矩阵,但在 2x2 宽度和高度之上,一切都显得很糟糕。如何将图像像素映射到设备像素。我为从 (0,0) 开始并向上延伸到宽度和高度的图像创建了网格网格。这意味着我的坐标不是从左上角开始的中心开始的。
我已经创建了这样的顶点缓冲区、短索引(绘制三角形的顺序列表)和纹理坐标。
public MeshGrid(int width, int height) {
vertices = new float[(width) * (height) * 2];
indices = new short[(width-1) * (height-1) * 6];
textu = new float[(width-1) * (height-1) * 8];
float xOffset = width / -2;
float yOffset = height / -2;
int currentVertex = 0;
int currentIndex = 0;
int currentTexIndex = 0;
short w = (short) (width );
for (int y = 0; y < height ; y++) {
for (int x = 0; x < width ; x++) {
vertices[currentVertex] = x;
vertices[currentVertex + 1] = y ;
currentVertex += 2;
int n = y * (width ) + x;
if (y < width-1 && x < height-1) {
// Face one
indices[currentIndex] = (short) n;
indices[currentIndex + 1] = (short) (n + 1);
indices[currentIndex + 2] = (short) (n + w);
// Face two
indices[currentIndex + 3] = (short) (n + 1);
indices[currentIndex + 4] = (short)(n + 1 + w);
indices[currentIndex + 5] = (short) (n + 1 + w - 1);
currentIndex += 6;
textu[currentTexIndex] = x;
textu[currentTexIndex+1] = y+1;
textu[currentTexIndex+2] = x+1;
textu[currentTexIndex+3] = y+1;
textu[currentTexIndex+4] = x;
textu[currentTexIndex+5] = y;
textu[currentTexIndex+6] = x+1;
textu[currentTexIndex+7] = y;
currentTexIndex+= 8;
}
}
}
}
我已经这样设置了
ByteBuffer bb = ByteBuffer.allocateDirect( // (#个坐标值 * 每个浮点数 4 字节) imgVertices.length * 4); bb.order(ByteOrder.nativeOrder()); 顶点缓冲区 = bb.asFloatBuffer(); vertexBuffer.put(imgVertices); vertexBuffer.position(0);
ByteBuffer vbb = ByteBuffer.allocateDirect(imgIndices.length * 2);
vbb.order(ByteOrder.nativeOrder());
indicesBuffer = vbb.asShortBuffer();
indicesBuffer.put(imgIndices);
indicesBuffer.position(0);
mNumOfIndices = imgIndices.length;
ByteBuffer byteBuf = ByteBuffer
.allocateDirect(imgTexture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(imgTexture);
mTextureSize = imgTexture.length;
textureBuffer.position(0);
这是我的顶点着色器代码
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec2 a_TexCoordinate;" +
"attribute vec2 a_Position;" +
"varying vec2 v_TexCoordinate;" +
"varying vec3 v_Position;" +
"void main() {" +
" v_TexCoordinate = a_TexCoordinate;" +
"gl_Position = uMVPMatrix*vec4(a_Position.x,a_Position.y,1.0,1.0);"+
"}";
这是我的片段着色器代码
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"uniform sampler2D u_Texture;" +
"varying vec2 v_TexCoordinate;" +
"void main() {" +
" gl_FragColor = texture2D(u_Texture, v_TexCoordinate);" +
"}";
这就是我设置投影和视图矩阵的方式
Matrix.setIdentityM(mProjectionMatrix, 0);
float ratio = (float)mwidth/mheight;
Matrix.orthoM(mProjectionMatrix,0,0f,ratio,0f,1,1,-1);
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
这是我的绘图功能
void drawImg() {
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_Position");
GLES20.glVertexAttrib2fv(mPositionHandle, vertexBuffer);
// 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
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
checkGlError("glUniformMatrix4fv");
mTxetureaformHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");
// Pass in the texture coordinate information
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
textureBuffer.position(0);
GLES20.glVertexAttribPointer(mTxetureaformHandle, 2, GLES20.GL_FLOAT, false,
0, textureBuffer);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTxetureHandle);
GLES20.glEnableVertexAttribArray(mTxetureaformHandle);
GLES20.glUniform1i(mTextureUniformHandle, 0);
// Point out the where the color buffer is.
GLES20.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
GL10.GL_UNSIGNED_SHORT, indicesBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
【问题讨论】: