2 qarmaigarai qarmaigarai 于 2014.08.23 22:55 提问

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>

Csdn user default icon
上传中...
上传图片
插入图片