我想在OpenGL2.0中的四邊形繪製紋理。到目前爲止,我已經得到了四邊形顯示和一切,但紋理不存在 - 四邊形都是黑色的。Android OpenGL2.0顯示黑色紋理
我的主要懷疑的是,我不是正確映射貼圖 - 我的紋理是2不國,也不是方 - 它們的寬度是在該領域mWidth及其mRowHeight高度。
四邊形繪製在一個垂直列表中,用一個平移矩陣完成。
我會非常感謝,如果任何人都可以過去這個事業,我絕望!
下面是相關的代碼:
初始化緩衝區:
void initBuffers() {
float r = (float) mRowHeight/(mHeight/2f);
ByteBuffer bb;
float[] bounds = { // X Y Z
/* 0 - TL */-1f, 1f, 0f,
/* 1 - BL */-1f, 1 - r, 0f,
/* 2 - BR */ 1f, 1 - r, 0f,
/* 3 - TR */ 1f, 1f, 0f };
bb = ByteBuffer.allocateDirect(bounds.length * 4);
bb.order(ByteOrder.nativeOrder());
mVertBuffer = bb.asFloatBuffer();
mVertBuffer.put(bounds).position(0);
short[] indices = { 0, 1, 2, 0, 2, 3 };
bb = ByteBuffer.allocateDirect(indices.length * 2);
bb.order(ByteOrder.nativeOrder());
mIndBuffer = bb.asShortBuffer();
mIndBuffer.put(indices).position(0);
float[] texture = {
/* 0 - BL */-1f, 1f,
/* 1 - TL */-1f, 1 - r,
/* 2 - BR */1f, 1 - r,
/* 3 - TR */1f, 1f };
bb = ByteBuffer.allocateDirect(texture.length * 4);
bb.order(ByteOrder.nativeOrder());
mTexBuffer = bb.asFloatBuffer();
mTexBuffer.put(texture).position(0);
}
繪製框架:
@Override
public void drawFrame() {
long startTime = System.currentTimeMillis();
if (!mLayoutComplete) {
return;
}
final float halfw = mHeight/2f;
final int rowHeight = mRowHeight;
final float r = (float) rowHeight/halfw;
int i = mFirstRow;
final float initial = (float) ((i * rowHeight) - mScroll)/halfw;
Matrix.setIdentityM(mTMatrix, 0);
Matrix.translateM(mTMatrix, 0, 0, -initial, 0);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
false, 0, mVertBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle);
final int l = mLastRow;
for (; i <= l; i++) {
ThumbRow thr = mCache.get(i);
if (thr != null) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
if (thr.mDirty) {
thr.loadTexture(null, null);
thr.mDirty = false;
} else {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, thr.mRow + 1);
}
GLES20.glUniform1i(msTextureHandle, 0);
GLES20.glVertexAttribPointer(maTextureHandle, 2,
GLES20.GL_FLOAT, false, 0, mTexBuffer);
GLES20.glEnableVertexAttribArray(maTextureHandle);
GLES20.glUniformMatrix4fv(muTMatrixHandle, 1, false,
mTMatrix, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6,
GLES20.GL_UNSIGNED_SHORT, mIndBuffer);
Log.i(TAG, GLES20.glGetProgramInfoLog(mProgram));
}
Matrix.translateM(mTMatrix, 0, 0, -r, 0); // Shift drawing
// window to next
// row.
}
GLES20.glDisableVertexAttribArray(maPositionHandle);
GLES20.glDisableVertexAttribArray(maTextureHandle);
Log.d(TAG, "onDrawFrame(): "
+ (System.currentTimeMillis() - startTime));
}
載入紋理:
public void loadTexture(GL10 gl, Context c) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mRow + 1);
// Create Nearest Filtered Texture
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);
// Different possible texture parameters, e.g.
// GLES20.GL_CLAMP_TO_EDGE
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);
Bitmap bitmap = mBitmap;
if (bitmap == null) {
bitmap = mEmptyBitmap;
}
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
}
頂點着色器:
uniform mat4 uTMatrix;
uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
attribute vec2 aTextureCoord;
varying vec2 vTextureCoord;
void main() {
gl_Position = uMVPMatrix * uTMatrix * aPosition;
vTextureCoord = aTextureCoord;
}
片段着色器:
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D sTexture;
void main() {
gl_FragColor = texture2D(sTexture, vTextureCoord);
}
任何幫助將非常感激。
一旦調用''glBindTexture(..)''''mRow + 1'是什麼例如?如果它是一些內部變量,則應將其更改爲從''glGenTextures(..)''得到的紋理名稱。基本上,如果您僅使用一個紋理(並僅更新其內容),請始終使用該紋理名稱。 – harism 2011-12-31 15:52:24
mRow是正在繪製的當前四邊形的索引 - 四邊形的紋理由它的mRow確定。編輯:從我的理解可以使用我自己的紋理名稱,只要他們是獨特的,我記得他們 – saarraz1 2011-12-31 15:54:41
沒有。你必須使用glGenTextures(..)分配紋理名稱,你不能只是想出自己的。在你的情況下,你應該分配ROW_COUNT紋理名稱並使用glBindTexture(..,TEXTURE_NAMES [mRowIdx])。但是,如果ROW_COUNT非常高,最好將位圖重新加載到每個行的一個紋理中,以避免不必要的內存使用。 – harism 2011-12-31 16:11:14