Android之GLES2.0显示立方体各面不同图片测试代码

本文介绍了如何在Android应用中使用OpenGL ES绘制立方体,并详细解释了相关代码实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class MainActivity extends Activity {

	private GLSurfaceView mGLSurfaceView;
	DemoRenderer mRender;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mGLSurfaceView = new GLSurfaceView(this);
		// Check if the system supports OpenGL ES 2.0.
		final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
		final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
		if (configurationInfo.reqGlEsVersion >= 0x20000) {
			// Request an OpenGL ES 2.0 compatible context.
			mGLSurfaceView.setEGLContextClientVersion(2);
			mRender = new DemoRenderer(this);
			// Set the renderer to our demo renderer, defined below.
			mGLSurfaceView.setRenderer(mRender);
		} else {
			// This is where you could create an OpenGL ES 1.x compatible
			// renderer if you wanted to support both ES 1 and ES 2.
			return;
		}

		setContentView(mGLSurfaceView);
		handler.postDelayed(runnable, 1000);
	}

	Handler handler = new Handler();
	Runnable runnable = new Runnable() {
		public void run() {
			handler.postDelayed(this, 1000);
			showFPS(mRender.fps);
		}
	};

	private void showFPS(int fps) {
		this.setTitle("fps:" + fps);
	}

	@Override
	protected void onResume() {
		super.onResume();
		mGLSurfaceView.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
		mGLSurfaceView.onPause();
	}
}

class DemoRenderer implements GLSurfaceView.Renderer {
	private Context mContext;
	private final FloatBuffer[] mCubePositions;
	private final FloatBuffer[] mCubeColors;
	private final FloatBuffer[] mCubeTextureCoordinates;
	private float[] mMVPMatrix = new float[16];
	private float[] mViewMatrix = new float[16];
	private float[] mModelMatrix = new float[16];
	private float[] mProjectionMatrix = new float[16];
	private int mMVPMatrixHandle;
	private int mPositionHandle;
	private int mColorHandle;
	private int mTextureUniformHandle;
	private int mTextureCoordinateHandle;
	private int[] mTextureDataHandle = new int[6];
	private final int POSITION_DATA_SIZE = 3;
	private final int COLOR_DATA_SIZE = 4;
	private final int TEXTURE_COORDINATE_DATA_SIZE = 2;

	int fps;
	FPSCounter fpsCounter;
	float angleInDegrees = 0;

	public DemoRenderer(final Context context) {
		mContext = context;
		final float cubePosition[][] =   
	        {   
	            // Front face    
	            {-1.0f, 1.0f, 1.0f,   
	            -1.0f, -1.0f, 1.0f,   
	            1.0f, 1.0f, 1.0f,   
	            -1.0f, -1.0f, 1.0f,   
	            1.0f, -1.0f, 1.0f,   
	            1.0f, 1.0f, 1.0f,  
	            },  
	            {  
	            // Right face   
	            1.0f, 1.0f, 1.0f,   
	            1.0f, -1.0f, 1.0f,  
	            1.0f, 1.0f, -1.0f,   
	            1.0f, -1.0f, 1.0f,   
	            1.0f, -1.0f, -1.0f,   
	            1.0f, 1.0f, -1.0f,  
	            },  
	            {  
	            // Back face   
	            1.0f, 1.0f, -1.0f,   
	            1.0f, -1.0f, -1.0f,   
	            -1.0f, 1.0f, -1.0f,   
	            1.0f, -1.0f, -1.0f,   
	            -1.0f, -1.0f, -1.0f,   
	            -1.0f, 1.0f, -1.0f,  
	            },  
	            // Left face   
	            {  
	            -1.0f, 1.0f, -1.0f,   
	            -1.0f, -1.0f, -1.0f,  
	            -1.0f, 1.0f, 1.0f,   
	            -1.0f, -1.0f, -1.0f,  
	            -1.0f, -1.0f, 1.0f,   
	            -1.0f, 1.0f, 1.0f,   
	            },  
	            // Top face  
	            {  
	            -1.0f, 1.0f, -1.0f,   
	            -1.0f, 1.0f, 1.0f,   
	            1.0f, 1.0f, -1.0f,   
	            -1.0f, 1.0f, 1.0f,   
	            1.0f, 1.0f, 1.0f,   
	            1.0f, 1.0f, -1.0f,  
	            },  
	            // Bottom face  
	            {  
	            1.0f, -1.0f, -1.0f,   
	            1.0f, -1.0f, 1.0f,   
	            -1.0f, -1.0f, -1.0f,   
	            1.0f, -1.0f, 1.0f,   
	            -1.0f, -1.0f, 1.0f,   
	            -1.0f, -1.0f, -1.0f,  
	            }  
	        };   
	        final float cubeColor[][] =   
	        {   
	            // Front face (red)   
	            {     
	            1.0f, 0.0f, 0.0f, 1.0f,  
	            1.0f, 0.0f, 0.0f, 1.0f,   
	            1.0f, 0.0f, 0.0f, 1.0f,    
	            1.0f, 0.0f, 0.0f, 1.0f,  
	            1.0f, 0.0f, 0.0f, 1.0f,   
	            1.0f, 0.0f, 0.0f, 1.0f,   
	            },  
	            // Right face (green)   
	            {     
	            0.0f, 1.0f, 0.0f, 1.0f,    
	            0.0f, 1.0f, 0.0f, 1.0f,   
	            0.0f, 1.0f, 0.0f, 1.0f,   
	            0.0f, 1.0f, 0.0f, 1.0f,   
	            0.0f, 1.0f, 0.0f, 1.0f,   
	            0.0f, 1.0f, 0.0f, 1.0f,    
	            },  
	            {     
	            // Back face (blue)   
	            0.0f, 0.0f, 1.0f, 1.0f,   
	            0.0f, 0.0f, 1.0f, 1.0f,   
	            0.0f, 0.0f, 1.0f, 1.0f,   
	            0.0f, 0.0f, 1.0f, 1.0f,   
	            0.0f, 0.0f, 1.0f, 1.0f,   
	            0.0f, 0.0f, 1.0f, 1.0f,    
	            },  
	            {     
	            // Left face (yellow)   
	            1.0f, 1.0f, 0.0f, 1.0f,   
	            1.0f, 1.0f, 0.0f, 1.0f,   
	            1.0f, 1.0f, 0.0f, 1.0f,   
	            1.0f, 1.0f, 0.0f, 1.0f,   
	            1.0f, 1.0f, 0.0f, 1.0f,   
	            1.0f, 1.0f, 0.0f, 1.0f,   
	            },  
	            {     
	            // Top face (cyan)   
	            0.0f, 1.0f, 1.0f, 1.0f,   
	            0.0f, 1.0f, 1.0f, 1.0f,   
	            0.0f, 1.0f, 1.0f, 1.0f,   
	            0.0f, 1.0f, 1.0f, 1.0f,   
	            0.0f, 1.0f, 1.0f, 1.0f,   
	            0.0f, 1.0f, 1.0f, 1.0f,   
	            },  
	            {     
	            // Bottom face (magenta)   
	            1.0f, 0.0f, 1.0f, 1.0f,   
	            1.0f, 0.0f, 1.0f, 1.0f,   
	            1.0f, 0.0f, 1.0f, 1.0f,   
	            1.0f, 0.0f, 1.0f, 1.0f,   
	            1.0f, 0.0f, 1.0f, 1.0f,   
	            1.0f, 0.0f, 1.0f, 1.0f   
	            }  
	        };    
	        final float cubeTextureCoordinate[][] =    
	        {   // Front face   
	            {  
	            0.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 1.0f,   
	            1.0f, 0.0f,    
	            },  
	            {  
	            // Right face    
	            0.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 1.0f,   
	            1.0f, 0.0f,    
	            },  
	            {  
	            // Back face    
	            0.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 1.0f,   
	            1.0f, 0.0f,   
	            },  
	            {  
	            // Left face    
	            0.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 1.0f,   
	            1.0f, 0.0f,    
	            },  
	            {  
	            // Top face    
	            0.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 1.0f,   
	            1.0f, 0.0f,    
	            },  
	            {  
	            // Bottom face    
	            0.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 0.0f,   
	            0.0f, 1.0f,   
	            1.0f, 1.0f,   
	            1.0f, 0.0f   
	            }  
	        };  
		mCubePositions = new FloatBuffer[6];
		for (int i = 0; i < cubePosition.length; i++) {
			mCubePositions[i] = ByteBuffer.allocateDirect(cubePosition[i].length * 4)
					.order(ByteOrder.nativeOrder()).asFloatBuffer();
			mCubePositions[i].put(cubePosition[i]).position(0);
		}

		mCubeColors = new FloatBuffer[6];
		for (int i = 0; i < cubeColor.length; i++) {
			mCubeColors[i] = ByteBuffer.allocateDirect(cubeColor[i].length * 4)
					.order(ByteOrder.nativeOrder()).asFloatBuffer();
			mCubeColors[i].put(cubeColor[i]).position(0);
		}

		mCubeTextureCoordinates = new FloatBuffer[6];
		for (int i = 0; i < cubeTextureCoordinate.length; i++) {
			mCubeTextureCoordinates[i] = ByteBuffer.allocateDirect(cubeTextureCoordinate[i].length * 4)
					.order(ByteOrder.nativeOrder()).asFloatBuffer();
			mCubeTextureCoordinates[i].put(cubeTextureCoordinate[i]).position(0);
		}
		fpsCounter = new FPSCounter();
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		GLES20.glEnable(GLES20.GL_CULL_FACE);
		GLES20.glEnable(GLES20.GL_DEPTH_TEST);
		String vertexShaderCode = 
			"uniform mat4 u_MVPMatrix; \n"
			+ "attribute vec4 a_Position; \n"
			+ "attribute vec4 a_Color; \n"
			+ "attribute vec2 a_TexCoordinate;\n"
			+ "varying vec4 v_Color; \n"
			+ "varying vec2 v_TexCoordinate; \n" 
			+ "void main(){ \n"
			+ "  v_Color = a_Color; \n"
			+ "  v_TexCoordinate = a_TexCoordinate;\n"
			+ "  gl_Position = u_MVPMatrix * a_Position; \n" 
			+ "} \n";
		String fragmentShaderCode = 
			"precision mediump float; \n"
			+ "uniform sampler2D u_Texture; \n"
			+ "varying vec4 v_Color; \n"
			+ "varying vec2 v_TexCoordinate; \n" 
			+ "void main(){ \n"
			// " gl_FragColor = v_Color * texture2D(u_Texture, v_TexCoordinate); \n"
			+ "  gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n"
			+ "} \n";
		int mProgramHandle = createAndLinkProgram(vertexShaderCode,fragmentShaderCode);
		GLES20.glUseProgram(mProgramHandle);
		//获得参数1-5
		mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle,"u_MVPMatrix");
		mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle,"a_Position");
		mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color");
		mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle,"a_TexCoordinate");
		mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle,"u_Texture");
		//加载纹理贴图
		mTextureDataHandle[0] = ToolsUtil.loadTexture(mContext, R.drawable.aa);
		mTextureDataHandle[1] = ToolsUtil.loadTexture(mContext, R.drawable.bb);
		mTextureDataHandle[2] = ToolsUtil.loadTexture(mContext, R.drawable.aa);
		mTextureDataHandle[3] = ToolsUtil.loadTexture(mContext, R.drawable.bb);
		mTextureDataHandle[4] = ToolsUtil.loadTexture(mContext, R.drawable.aa);
		mTextureDataHandle[5] = ToolsUtil.loadTexture(mContext, R.drawable.bb);
		//激活纹理
		GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
	}
	
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		//竖屏:width=1080,height=1581
		GLES20.glViewport(0, 0, width, height);
		final float ratio = (float) width / height;
		Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 1, 10);
		Matrix.setLookAtM(mViewMatrix, 0, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, -5, 0.0f, 1.0f, 0.0f);
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
		//矩阵乘法的一个乘数
		Matrix.setIdentityM(mModelMatrix, 0);
		Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -5.0f);
		Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.3f, 0.6f, 0.8f);
		//绑定纹理,传递参数,绘制图形
		for (int i = 0; i < mCubePositions.length; i++) {
			GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle[i]);
			drawCube(mCubePositions[i], mCubeColors[i],mCubeTextureCoordinates[i]);
		}
		fps = fpsCounter.getFPS();
		angleInDegrees += 0.5f;
	}

	private void drawCube(final FloatBuffer cubePositions,
			final FloatBuffer cubeColors,final FloatBuffer cubeTextureCoord) {
		//参数1传递
		Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
		Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
		GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
		//参数2传递
		GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE,
				GLES20.GL_FLOAT, false, 0, cubePositions);
		GLES20.glEnableVertexAttribArray(mPositionHandle);
		//参数3传递
		GLES20.glVertexAttribPointer(mColorHandle, COLOR_DATA_SIZE,
				GLES20.GL_FLOAT, false, 0, cubeColors);
		GLES20.glEnableVertexAttribArray(mColorHandle);
		//参数4传递
		GLES20.glVertexAttribPointer(mTextureCoordinateHandle,TEXTURE_COORDINATE_DATA_SIZE, 
				GLES20.GL_FLOAT, false, 0,cubeTextureCoord);
		GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
		//参数5传递
		GLES20.glUniform1i(mTextureUniformHandle, 0);
		//绘制
		GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
	}

	private int compileShader(final int shaderType, final String shaderSource) {
		int shaderHandle = GLES20.glCreateShader(shaderType);
		if (shaderHandle != 0) {
			GLES20.glShaderSource(shaderHandle, shaderSource);
			GLES20.glCompileShader(shaderHandle);
			final int[] compileStatus = new int[1];
			GLES20.glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS,compileStatus, 0);
			if (compileStatus[0] == 0) {
				Log.e("ERR","compiling: " + GLES20.glGetShaderInfoLog(shaderHandle));
				GLES20.glDeleteShader(shaderHandle);
				shaderHandle = 0;
			}
		}
		if (shaderHandle == 0) {
			throw new RuntimeException("Error creating shader.");
		}
		return shaderHandle;
	}
	private int createAndLinkProgram(final String vertexShaderCode,final String fragmentShaderCode) {
		int vertexShaderHandle = compileShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
		int fragmentShaderHandle = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
		int programHandle = GLES20.glCreateProgram();
		if (programHandle != 0) {
			GLES20.glAttachShader(programHandle, vertexShaderHandle);
			GLES20.glAttachShader(programHandle, fragmentShaderHandle);
			GLES20.glLinkProgram(programHandle);
			final int[] linkStatus = new int[1];
			GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS,linkStatus, 0);
			if (linkStatus[0] == 0) {
				Log.e("ERR","linking: "+ GLES20.glGetProgramInfoLog(programHandle));
				GLES20.glDeleteProgram(programHandle);
				programHandle = 0;
			}
		}
		if (programHandle == 0) {
			throw new RuntimeException("Error creating program.");
		}
		return programHandle;
	}

	static class ToolsUtil {
		public static int loadTexture(final Context context,final int resourceId) {
			final int[] textureHandle = new int[1];
			GLES20.glGenTextures(1, textureHandle, 0);
			if (textureHandle[0] != 0) {
				final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);
				GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
				GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
				GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
				GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
			}
			if (textureHandle[0] == 0) {
				throw new RuntimeException("failed to load texture");
			}
			return textureHandle[0];
		}
	}

	class FPSCounter {
		int FPS;
		int lastFPS;
		long tempFPStime;

		public FPSCounter() {
			FPS = 0;
			lastFPS = 0;
			tempFPStime = 0;
		}
		int getFPS() {
			long nowtime = SystemClock.uptimeMillis();
			FPS++;
			if (nowtime - tempFPStime >= 1000) {
				lastFPS = FPS;
				tempFPStime = nowtime;
				FPS = 0;
			}
			return lastFPS;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值