【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
创始人
2024-02-28 23:04:47
0

需要源码请点赞关注收藏后评论区留言私信~~~

一、OpenGL ES简介

虽然OpenGL的三维制图功能非常强大,但是它主要为计算机设计的,对于嵌入式设备和移动端设备来说显得比较臃肿,所以业界又设计了专供嵌入式设备的OpenGL ES 它相当于OpenGL的精简版,因为嵌入式设备追求性价比,所以能不做的渲染操作尽量不做,以便优化整体的系统性能

OpenGL ES将所有的渲染过程划分为若干着色器,每个着色器只负责自己这块的渲染操作。

 

 着色器的小程序保存在扩展名为glsl的配置文件中,它采用GLSL语言编写,语法框架类似于C语言

OpenGL ES 2.0与3.0之间的GLSL语法差异如下:

(1)对于ES 3.0来说,glsl文件开头多了一行“#version 300 es”,表示当前小程序使用ES 3.0; (2)取消了ES 2.0的限定符attribute和varying,取而代之的是in和out;

(3)删除了ES 2.0的内置变量gl_FragColor和gl_FragData,改为通过out声明相关输出参数; (4)ES 2.0内置的纹理方法texture2D和texture3D都被新方法texture所取代;

(5)ES 3.0新增修饰符layout,它允许指定变量的位置序号;

二、着色器实战效果

如下图所示 可以在下拉框中选择不同颜色填充

 

 

 代码如下

Java类

package com.example.threed;import androidx.appcompat.app.AppCompatActivity;import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;import com.example.threed.util.GlUtil;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;public class EsShaderActivity extends AppCompatActivity {private final static String TAG = "EsShaderActivity";private GLSurfaceView glsv_content; // 声明一个图形库表面视图对象private int mProgramId; // 声明glsl小程序的编号private int mStyle; // 三角形样式// 三角形的顶点坐标数组private float mCoordArray[] = { // 默认按逆时针方向顺序绘制0.0f, 0.622008459f, 0.0f,   // 顶-0.5f, -0.311004243f, 0.0f,   // 左底0.5f, -0.311004243f, 0.0f    // 右底};// 三角形的顶点颜色数组(纯色)private float[] mColorPureArray = {1.0f, 0.0f, 0.0f, 1.0f,1.0f, 0.0f, 0.0f, 1.0f,1.0f, 0.0f, 0.0f, 1.0f};// 三角形的顶点颜色数组(彩色)private float[] mColorFullArray = {0.0f, 1.0f, 0.0f, 1.0f,1.0f, 0.0f, 0.0f, 1.0f,0.0f, 0.0f, 1.0f, 1.0f};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_es_shader);showEsVersion(); // 显示OpenGL ES的版本号initStyleSpinner(); // 初始化样式下拉框glsv_content = findViewById(R.id.glsv_content);// 声明使用OpenGL ES的版本号为3.0。使用ES30方法之前务必指定版本号glsv_content.setEGLContextClientVersion(3);// 给OpenGL的表面视图注册三维图形的渲染器glsv_content.setRenderer(new ShaderRender());// 设置渲染模式(关闭自动刷新)glsv_content.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);}// 显示OpenGL ES的版本号private void showEsVersion() {ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);ConfigurationInfo info = am.getDeviceConfigurationInfo();String versionDesc = String.format("%08X", info.reqGlEsVersion);String versionCode = String.format("%d.%d", Integer.parseInt(versionDesc)/10000,Integer.parseInt(versionDesc)%10000);Toast.makeText(this, "系统的OpenGL ES版本号为"+versionCode, Toast.LENGTH_SHORT).show();}// 初始化样式下拉框private void initStyleSpinner() {ArrayAdapter styleAdapter = new ArrayAdapter<>(this,R.layout.item_select, styleArray);Spinner sp_style = findViewById(R.id.sp_style);sp_style.setPrompt("请选择三角形样式");sp_style.setAdapter(styleAdapter);sp_style.setOnItemSelectedListener(new StyleSelectedListener());sp_style.setSelection(0);}private String[] styleArray = { "只画线条", "绘制纯色表面", "绘制彩色表面" };class StyleSelectedListener implements AdapterView.OnItemSelectedListener {public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) {mStyle = arg2;glsv_content.requestRender(); // 主动请求渲染操作}public void onNothingSelected(AdapterView arg0) {}}// 定义一个三维图形的渲染器private class ShaderRender implements GLSurfaceView.Renderer {// 在表面创建时触发@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// 设置白色背景。0.0f相当于00,1.0f相当于FFGLES30.glClearColor(1f, 1f, 1f, 1);// 初始化着色器mProgramId = GlUtil.initShaderProgram(EsShaderActivity.this, "shader_vertex.glsl", "shader_fragment.glsl");}// 在表面变更时触发@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {GLES30.glViewport(0, 0, width, height); // 设置输出屏幕大小// 开启剔除操作。开启之后才能调用glCullFace方法禁止光照、阴影和颜色等效果,以消除不必要的渲染计算。GLES30.glEnable(GLES30.GL_CULL_FACE);}// 执行框架绘制动作@Overridepublic void onDrawFrame(GL10 gl) {// 清除屏幕和深度缓存GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_DEPTH_BUFFER_BIT);GLES30.glLineWidth(3); // 指定线宽drawTriangle(); // 绘制三角形}}// 绘制三角形private void drawTriangle() {FloatBuffer vertexBuffer = GlUtil.getFloatBuffer(mCoordArray);FloatBuffer colorBuffer;if (mStyle == 2) { // 绘制彩色表面colorBuffer = GlUtil.getFloatBuffer(mColorFullArray);} else { // 绘制纯色表面colorBuffer = GlUtil.getFloatBuffer(mColorPureArray);}// 获取顶点着色器的vPosition位置(来自shader_vertex.glsl)int positionLoc = GLES30.glGetAttribLocation(mProgramId, "vPosition");// 获取片段着色器的vColor位置(来自shader_vertex.glsl)int colorLoc = GLES30.glGetAttribLocation(mProgramId, "inColor");GLES30.glEnableVertexAttribArray(positionLoc); // 启用顶点属性数组GLES30.glEnableVertexAttribArray(colorLoc); // 启用顶点属性数组// 指定顶点属性数组的位置信息GLES30.glVertexAttribPointer(positionLoc, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);// 指定顶点属性数组的颜色信息GLES30.glVertexAttribPointer(colorLoc, 4, GLES30.GL_FLOAT, false, 0, colorBuffer);if (mStyle == 0) { // 只绘制线条// 绘制物体的轮廓线条GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, mCoordArray.length/3);} else { // 也绘制表面// 绘制物体的轮廓表面GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, mCoordArray.length/3);}GLES30.glDisableVertexAttribArray(colorLoc); // 禁用顶点属性数组GLES30.glDisableVertexAttribArray(positionLoc); // 禁用顶点属性数组}}

XML文件

 创作不易 觉得有帮助请点赞关注收藏~~~

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...