我是 Android 的 OpenGL ES 的新手。我在纹理映射上花了 3 天时间,但没有解决我的问题。现在我写了一些代码,但它只显示背景颜色,而不是我想在表面上显示的图像。这是myRenderer
类构造函数
public myRenderer()
{
imageBitmap=BitmapFactory.decodeResource(MainActivity.context.getResources(),R.drawable.image);
float texture[]={
0.0f, 0.0f, //bottom-left
0.1f, 0.0f, // bottom-right
0.0f, 0.1f, // top-left
0.1f, 0.1f // top-right
};
float vertex[]={
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, //3 Vertex Coords, 3 RGB Vals
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, //3 Vertex Coords, 3 RGB Vals
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, //3 Vertex Coords, 3 RGB Vals
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, //3 Vertex Coords, 3 RGB Vals
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, //3 Vertex Coords, 3 RGB Vals
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, //3 Vertex Coords, 3 RGB Vals
};
float triagnle2[]={
-0.75f,0.5f,0.0f,
0.0f,1.0f,0.0f,1.0f,
0.75f,0.5f,0.0f,
1.0f,1.0f,0.0f,1.0f,
0.0f,0.0f,0.0f,
1.0f,1.0f,1.0f,1.0f
};
byte[] indices={
0,1,2, 3,4,5//Front Face
};
vertexBuffer=ByteBuffer.allocateDirect(vertex.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexBuffer.put(vertex).position(0);
textureBuffer=ByteBuffer.allocateDirect(texture.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureBuffer.put(texture).position(0);
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
}
这是 SurfaceCreated 中的内容:
GLES20.glClearColor(1.7f,1.5f,0.5f,0.5f);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);
//imageBitmap.getPixels(pixels,0,imageBitmap.getWidth(),0,0,imageBitmap.getWidth(),imageBitmap.getHeight());
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, imageBitmap, 0);
imageBitmap.recycle();
GLES20.glDepthFunc(GLES20.GL_LESS);
Matrix.setIdentityM(mModelMatrix,0);
final float eyeX = 0.0f;
final float eyeY = 0.0f;
final float eyeZ = 2.5f;
// We are looking toward the distance
final float lookX = 0.0f;
final float lookY = 0.0f;
final float lookZ = 1f;
// Set our up vector. This is where our head would be pointing were we holding the camera.
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);
final String vertexShader =
"uniform mat4 u_MVPMatrix; \n" // A constant representing the combined model/view/projection matrix.
+ "attribute vec4 a_Position; \n" // Per-vertex position information we will pass in.
+ "attribute vec4 a_Color; \n" // Per-vertex color information we will pass in.
+ "varying vec4 v_Color; \n" // This will be passed into the fragment shader.
+"attribute vec2 TextureCoord;"
+"varying vec2 TextureCoordOut;"
+ "void main() \n" // The entry point for our vertex shader.
+ "{ \n"
// + " v_Color = a_Color; \n" // Pass the color through to the fragment shader.
+"TextureCoordOut = TextureCoord;" // It will be interpolated across the triangle.
+ " gl_Position = u_MVPMatrix \n" // gl_Position is a special variable used to store the final position.
+ " * a_Position; \n" // Multiply the vertex by the matrix to get the final point in
+ "} \n";
final String fragmentShader =
"precision mediump float; \n" // Set the default precision to medium. We don't need as high of a
+"varying mediump vec2 TextureCoordOut;"
+"uniform sampler2D Sampler;// precision in the fragment shader."
//+ "varying vec4 v_Color; \n" // This is the color from the vertex shader interpolated across the
// triangle per fragment.
+ "void main() \n" // The entry point for our fragment shader.
+ "{ \n"
+ " gl_FragColor = vec4(texture2D(Sampler, TextureCoordOut).xyz, 0.5); \n" // Pass the color directly through the pipeline.
+ "} \n";
int vertexShederHandle=GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
if(vertexShederHandle!=0)
{
GLES20.glShaderSource(vertexShederHandle, vertexShader);
GLES20.glCompileShader(vertexShederHandle);
int[] compileStatus=new int[1];
GLES20.glGetShaderiv(vertexShederHandle,GLES20.GL_COMPILE_STATUS,compileStatus,0);
if(compileStatus[0]==0)
{
GLES20.glDeleteShader(vertexShederHandle);
vertexShederHandle=0;
}
}
else
{
throw new RuntimeException("Error creating Sheder");
}
/////////////
int fragmentShederHandle=GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
if(fragmentShederHandle!=0)
{
GLES20.glShaderSource(fragmentShederHandle,fragmentShader);
GLES20.glCompileShader(fragmentShederHandle);
int[] compileStatus=new int[1];
GLES20.glGetShaderiv(fragmentShederHandle,GLES20.GL_COMPILE_STATUS,compileStatus,0);
if(compileStatus[0]==0)
{
GLES20.glDeleteShader(fragmentShederHandle);
fragmentShederHandle=0;
}
}
else
{
throw new RuntimeException("Error creating Sheder");
}
int progameHandle=GLES20.glCreateProgram();
if(progameHandle!=0)
{
GLES20.glAttachShader(progameHandle, vertexShederHandle);
GLES20.glAttachShader(progameHandle, fragmentShederHandle);
GLES20.glBindAttribLocation(progameHandle, 0, "a_Position");
GLES20.glBindAttribLocation(progameHandle, 1, "a_Color");
GLES20.glLinkProgram(progameHandle);
int[] linkStatus=new int[1];
GLES20.glGetProgramiv(progameHandle, GLES20.GL_LINK_STATUS,linkStatus,0);
if(linkStatus[0]==0)
{
GLES20.glDeleteProgram(progameHandle);
progameHandle=0;
}
}
else
{
throw new RuntimeException("Error creating programe");
}
mMVPMatrixHandle=GLES20.glGetUniformLocation(progameHandle, "u_MVPMatrix");
mPositionHandle=GLES20.glGetAttribLocation(progameHandle, "a_Position");
mColorHandle=GLES20.glGetAttribLocation(progameHandle, "a_Color");
GLES20.glUseProgram(progameHandle);
这是 OnSurfaceChanged:
GLES20.glViewport(0, 0, width, height);
// Create a new perspective projection matrix. The height will stay the same
// while the width will vary as per aspect ratio.
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.4f;
final float far = 10.0f;
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
这是onDrawFrame:
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glEnable(GLES20.GL_VERTEX_ATTRIB_ARRAY_ENABLED);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0+textures[0]);
GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP,6,GLES20.GL_UNSIGNED_BYTE,indexBuffer);
如果做了一些愚蠢的事,请原谅我。请告诉我该怎么做。谢谢你。