问题描述
- OpenGL 纹理映射无法显示纹理
-
初学者,希望大侠们能做个解答,小弟在此先行谢过,问题很简单,但我琢磨好久都没搞出来,也找不出问题所在。想要实现的的功能也很简单,就是纹理。
问题所在:运行之后只有背景,没有纹理
开发环境:Eclipse ADT
源代码:
一、SRC/ SFGame.java
package com.gamewenli;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;public class SFGame extends Activity {
Renderer render = new SFBameRenderer(this);
GLSurfaceView gameView;
Button start;@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
GLImage.load(this.getResources());
gameView = new GLSurfaceView(this);
gameView.setRenderer(render);
setContentView(R.layout.pageone);
start = (Button) findViewById(R.id.button1);start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setContentView(gameView);
}
});二、
SRC/SFBameRenderer.java
package com.gamewenli;
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.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;public class SFBameRenderer implements Renderer {
public Context context;
private int[] textureids;
private FloatBuffer vertexBuffer;
private FloatBuffer textureBuffer;
//private ByteBuffer indexBuffer;//vertices[]数组会列出一系列的点,其中每一行代表正方形一角的X,Y,Z的值.
private float vertices[] ={
0f, 0f, 0f,
1f, 0f, 0f,
1f, 1f, 0f,
0f, 1f, 0f,
};
//texture[]数组表示纹理的四角在何处能与所创建的正方形四角排成一条直线
private float texture[] = {
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
//indices[]数组表示正方形表面的定义,正方形的表面被划分为两个三角形,该数组就是逆时针方向上这些三角形的角度数。
//private byte indices[] = {
//0, 1, 2,
//0, 2, 3
//};public SFBameRenderer(Context context) {
this.context = context;
textureids = new int[1];ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);ByteBuffer tbb = ByteBuffer.allocateDirect(texture.length * 4);
tbb.order(ByteOrder.nativeOrder());
textureBuffer = tbb.asFloatBuffer();//indexBuffer = ByteBuffer.allocateDirect(indices.length);
//indexBuffer.put(indices);
//indexBuffer.position(0);//为正方形贴上纹理
//for (int i = 0; i < 1; i++) {
textureBuffer.put(texture);
//}
textureBuffer.position(0);
}@Override
public void onDrawFrame(GL10 gl) {
// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
// 开启顶点和纹理功能(开启顶点和纹理缓冲)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// 设置顶点和纹理
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer);
gl.glTexCoordPointer(3, GL10.GL_FIXED, 0, textureBuffer);
// 绘制正方形
//int i = 1;
//switch (i) {
//case 0:
// 生成纹理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0);
// 关闭顶点和纹理功能
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
//}@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
float ratio = (float) (width) / height;
// 设置OpenGL场景的大小
gl.glViewport(0, 0, width, height);
// 设置投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
// 重置投影矩阵
gl.glLoadIdentity();
// 设置视口的大小
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
// 选择模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置模型观察矩阵
gl.glLoadIdentity();
}@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
// 绿色背景gl.glClearColor(0, 1, 0, 0);
gl.glEnable(GL10.GL_CULL_FACE);
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
//启用纹理映射gl.glClearDepthf(1.0f);
//深度测试的类型gl.glDepthFunc(GL10.GL_LEQUAL);
// 允许2D贴图,纹理gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE);
// 创建纹理gl.glGenTextures(1, textureids, 0);
// 绑定要使用的纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureids[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0);
// 线性滤波gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
}}
}
}class GLImage {
public static Bitmap iBitmap;
public static Bitmap close_Bitmap;
public static void load(Resources resources) {
iBitmap = BitmapFactory.decodeResource(resources, R.drawable.wall);
}}
三、
RES/Androidmanifest.xml
package="com.gamewenli"
android:versionCode="1"
android:versionName="1.0" ><uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="SFGame"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>