最简单的三角形

本文介绍了使用OpenGL ES原理及代码实现绘制三角形的过程,包括初始化顶点颜色数据、设置shader、绘制三角形等关键步骤。

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

    opengles主要是看的<android游戏开发技术宝典>,还有opengles1.0的视频 https://yunpan.cn/OcxubipBdNZdX3  访问密码 fc4c   视频是1.0的,已经过时了,不用在意细节 但是很多思想在2.0同样适用 如果有不懂的地方 不妨看看视频吧,虽然书是游戏开发,但是绘制复杂的特效,绝对高大上,先从最简单的开始,绘制一个三角形,目录结构很简单,就一个java文件,两个glsl文件

package com.example.es1;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
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.app.Activity;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.os.Bundle;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// TODO 1 new GLSurfaceView
		setContentView(new MSur(this));
	}
}

class MSur extends GLSurfaceView {
	Render render;

	public MSur(Context context) {
		super(context);
		// TODO 2 设置GLES版本
		this.setEGLContextClientVersion(2);
		render = new Render(context);
		// TODO 3 设置GLSurfaceView回掉
		setRenderer(render);
		this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
	}
}

class Render implements GLSurfaceView.Renderer {
	private int vCount;
	private Context ctx;
	private FloatBuffer fbv;
	private FloatBuffer fbc;
	static float[] mMMatrix = new float[16];
	int mProgram;// 自定义渲染管线程序id
	int muMVPMatrixHandle;// 总变换矩阵引用id
	int maPositionHandle; // 顶点位置属性引用id
	int maColorHandle; // 顶点颜色属性引用id
	public static float[] mProjMatrix = new float[16];// 4x4矩阵 投影用
	public static float[] mVMatrix = new float[16];// 摄像机位置朝向9参数矩阵
	public static float[] mMVPMatrix;// 最后起作用的总变换矩阵

	public Render(Context ctx) {
		super();
		this.ctx = ctx;
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		GLES20.glClearColor(0, 0, 0, 1.0f);
		// TODO 4 初始化顶点 颜色数据
		initVertex();
		// TODO 5 初始化shader
		initShader();
		GLES20.glEnable(GLES20.GL_DEPTH_TEST);
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// TODO 6 设置视口
		GLES20.glViewport(0, 0, width, height);
		float ratio = (float) width / height;
		// TODO 7 设置投影
		Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 1, 10);
		// TODO 8 设置摄像机
		Matrix.setLookAtM(mVMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
		// TODO 9 绘制
		draw();
	}

	private void initVertex() {
		// TODO 4_1 初始化顶点数据
		float v[] = { 1f, -1f, 0, 0, 1f, 0, -1f, -1f, 0 };
		vCount = v.length / 3;
		ByteBuffer bb = ByteBuffer.allocateDirect(v.length * 4);
		bb.order(ByteOrder.nativeOrder());
		fbv = bb.asFloatBuffer();
		fbv.put(v);
		fbv.position(0);
		// TODO 4_2 初始化颜色数据
		float vc[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
		ByteBuffer cbb = ByteBuffer.allocateDirect(vc.length * 4);
		cbb.order(ByteOrder.nativeOrder());
		fbc = cbb.asFloatBuffer();
		fbc.put(vc);
		fbc.position(0);
	}

	public void draw() {
		GLES20.glUseProgram(mProgram);
		Matrix.setRotateM(mMMatrix, 0, 0, 0, 1, 0);
		// TODO 9_1 设置总变换矩阵
		mMVPMatrix = new float[16];
		Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
		Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
		GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

		// TODO 9_2 设置顶点
		GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
				false, 3 * 4, fbv);
		// TODO 9_3 设置颜色
		GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT, false,
				3 * 4, fbc);

		GLES20.glEnableVertexAttribArray(maPositionHandle);
		GLES20.glEnableVertexAttribArray(maColorHandle);
		// TODO 9_4 绘制三角形
		GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
	}

	private void initShader() {
		String vertex = loadSH("vertex.sh");
		String shader = loadSH("frag.sh");
		// TODO 5_1 创建顶点
		int verS = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
		if (verS != 0) {
			GLES20.glShaderSource(verS, vertex);
			GLES20.glCompileShader(verS);
		}
		// TODO 5_2 创建颜色
		int fragS = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
		if (fragS != 0) {
			GLES20.glShaderSource(fragS, shader);
			GLES20.glCompileShader(fragS);
		}
		mProgram = GLES20.glCreateProgram();
		if (mProgram != 0) {
			GLES20.glAttachShader(mProgram, verS);
			GLES20.glAttachShader(mProgram, fragS);
			GLES20.glLinkProgram(mProgram);
		}
		// TODO 5_3 关联glsl变量
		maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
		maColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
		muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
	}
	//将sh文件加载进来
	private String loadSH(String fname) {
		String result = null;
		try {
			InputStream in = ctx.getAssets().open(fname);
			int ch = 0;
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			while ((ch = in.read()) != -1) {
				baos.write(ch);
			}
			byte[] buff = baos.toByteArray();
			baos.close();
			in.close();
			result = new String(buff, "UTF-8");
			result = result.replaceAll("\\r\\n", "\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}
frag.sh文件   片元文件

precision mediump float; 
varying  vec4 vColor; //接收从顶点着色器过来的参数

void main()                        
{                      
   gl_FragColor = vColor;//给此片元颜色值
}

vertex.sh    顶点文件

uniform mat4 uMVPMatrix; //总变换矩阵
attribute vec3 aPosition;  //顶点位置
attribute vec4 aColor;    //顶点颜色
varying  vec4 vColor;  //用于传递给片元着色器的变量

void main()    
{                            
   gl_Position = uMVPMatrix * vec4(aPosition,1); //根据总变换矩阵计算此次绘制此顶点位置
   vColor = aColor;//将接收的颜色传递给片元着色器
} 
效果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值