版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在Android中利用OpenGLES绘制一个天空盒
怎么在Android中利用OpenGLES绘制一个天空盒?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。第一步SkyBoxView继承了GLSurfaceView,为什么要继承GLSurfaceView,因为在使用OpenGLES需要建立一个窗口和一个上下文,GLSurfaceView帮我们做了这些工作。下面是SkyBoxView的主要代码:class
SkyBoxView(context:
Context,
attributeSet:
AttributeSet?)
:
GLSurfaceView(context,
attributeSet)
{
private
lateinit
var
skyBoxRender:
SkyBoxRender
private
var
lastX=0F
private
var
lastY=0F
private
var
yaw=0f
private
var
pitch=0f
private
var
screenWidth=0
private
var
screenHeight=0
private
var
horSensity=0.03f
private
var
verSensity=0.03f
constructor(context:
Context)
:
this(context,
null)
init
{
//
initSensor()
initSensity()
initConfig()
}
private
fun
initSensity()
{
screenWidth=resources.displayMetrics.widthPixels
screenHeight=resources.displayMetrics.heightPixels
horSensity=
360.0f/screenWidth
verSensity=180.0f/screenHeight
}
private
fun
rotate(pitch:Float,yaw:Float)
{
queueEvent
{
skyBoxRender.rotate(pitch,yaw)
}
}
private
fun
initConfig()
{
setEGLContextClientVersion(3)
skyBoxRender=SkyBoxRender(context)
setRenderer(skyBoxRender)
renderMode
=
GLSurfaceView.RENDERMODE_CONTINUOUSLY
}
override
fun
onTouchEvent(event:
MotionEvent?):
Boolean
{
when(event?.action)
{
MotionEvent.ACTION_DOWN->
{
lastX=event.x
lastY=event.y
return
true
}
MotionEvent.ACTION_MOVE->
{
val
offsetX=event.x-lastX
val
offsetY=lastY-event.y
yaw+=offsetX*horSensity
pitch+=offsetY*verSensity
lastX=event.x
lastY=event.y
skyBoxRender.rotate(pitch,yaw)
}
}
return
true
}
}在initConfig方法里,设置了render为SkyBoxRender,真正的绘制是在这里进行的。在initSensity方法里设置了旋转精度,horSensity和verSensity,水平和数值旋转时的精度,就像你玩fps游戏设置的鼠标灵敏度一样。在onTouchEvent则根据手指滑动的距离设置俯仰角pitch和偏移脚yaw,调用skyBoxRender进行相机的旋转。另外如果你看github可能发现我注释掉了很多代码,那是用传感器旋转的尝试,但是觉得麻烦,也没继续做,有兴趣的读者可以自己搞一下。第二步SkyboxRender的主要工作就是加载贴在正方体表面的6个图片纹理,从文件读取着色器语言,而真正创建openglesprogram和绘制是用C++代码来写的,所以主要看一下这里。#include
<jni.h>
#include
<string>
#include
<GLUtils/GLUtils.h>
#include
<glm/glm.hpp>
#include
<glm/gtc/type_ptr.hpp>
#include
<glm/gtc/matrix_transform.hpp>
extern
"C"
{
JNIEXPORT
jint
JNICALL
Java_com_skateboard_skybox_SkyBoxRender_genProgram(JNIEnv
*env,
jobject
thiz,
jstring
vertexPath,
jstring
fragmentPath)
{
//load
program
const
char
*cVertexPath
=
env->GetStringUTFChars(vertexPath,
nullptr);
const
char
*cFragmentPath
=
env->GetStringUTFChars(fragmentPath,
nullptr);
int
program
=
glutils::loadProgram(cVertexPath,
cFragmentPath);
return
program;
}
JNIEXPORT
jint
JNICALL
Java_com_skateboard_skybox_SkyBoxRender_preparePos(JNIEnv
*env,
jobject
thiz,
jfloatArray
pos)
{
//gen
vao
vbo
unsigned
int
VAO,
VBO;
glGenVertexArrays(1,
&VAO);
glBindVertexArray(VAO);
glGenBuffers(1,
&VBO);
glBindBuffer(GL_ARRAY_BUFFER,
VBO);
int
posSize
=
env->GetArrayLength(pos);
float*
p=env->GetFloatArrayElements(pos,
nullptr);
glBufferData(GL_ARRAY_BUFFER,
posSize*
sizeof(float),
p,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,
3,
GL_FLOAT,
GL_FALSE,
3
*
sizeof(float),
0);
glBindVertexArray(0);
return
VAO;
}
JNIEXPORT
jint
JNICALL
Java_com_skateboard_skybox_SkyBoxRender_prepareTexture(JNIEnv
*env,
jobject
thiz)
{
//gen
texture
unsigned
int
TEXTURE;
glGenTextures(1,
&TEXTURE);
glBindTexture(GL_TEXTURE_CUBE_MAP,
TEXTURE);
glTexParameteri(GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_WRAP_R,
GL_CLAMP_TO_EDGE);
return
1;
}
glm::vec3
cameraPos
=
glm::vec3(0.0f,
0.0f,
0.0f);
glm::vec3
cameraFront
=
glm::vec3(0.0f,
0.0f,
-1.0f);
JNIEXPORT
void
JNICALL
Java_com_skateboard_skybox_SkyBoxRender_draw(JNIEnv
*env,
jobject
thiz,
jint
program,
jint
VAO,
jint
texture,jfloat
width,jfloat
height)
{
glClear(GL_COLOR_BUFFER_BIT
|
GL_DEPTH_BUFFER_BIT);
glClearColor(0.0,
1.0,
0.0,
1.0);
glUseProgram(program);
glEnable(GL_DEPTH_TEST);
glm::mat4
viewMatrix
=
glm::mat4(1.0f);
glm::mat4
projectionMatrix
=
glm::mat4(1.0f);
glm::vec3
v
=
glm::vec3(cameraFront.x
-
cameraPos.x,
cameraFront.y
-
cameraPos.y,
cameraFront.z
-
cameraPos.z);
viewMatrix
=
glm::lookAt(cameraPos,
v,
glm::vec3(0.0f,
1.0f,
0.0f));
projectionMatrix
=
glm::perspective(glm::radians(45.0f),
width
/
height,
0.1f,
100.0f);
int
viewMatrixLocation
=
glGetUniformLocation(program,
"view");
int
projectMatrixLocation
=
glGetUniformLocation(program,
"projection");
glUniformMatrix4fv(viewMatrixLocation,
1,
GL_FALSE,
&viewMatrix[0][0]);
glUniformMatrix4fv(projectMatrixLocation,
1,
GL_FALSE,
&projectionMatrix[0][0]);
glBindVertexArray(VAO);
glBindTexture(GL_TEXTURE_CUBE_MAP,
texture);
glDrawArrays(GL_TRIANGLES,
0,
36);
}JNIEXPORT
void
JNICALL
Java_com_skateboard_skybox_SkyBoxRender_rotate(JNIEnv
*env,
jobject
thiz,jfloat
pitch,jfloat
yaw)
{
if(pitch>89)
{
pitch=89.0;
}
if(pitch<-89)
{
pitch=-89.0;
}
cameraFront.x=glm::cos(glm::radians(pitch))*glm::cos(glm::radians(yaw));
cameraFront.y=glm::sin(glm::radians(pitch));
cameraFro
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 年产5000吨高纯砂项目可行性研究报告
- XX洗浴中心建设项目可行性研究报告
- 年产一万吨激光裁剪薄膜和感光干膜项目可行性研究报告
- 江苏省新沂市~度第二期期2024届初中数学毕业考试模拟冲刺卷含解析
- 2023-2024年中国石化和西布尔公司签署合作合同样本
- 2024年电解液行业商业计划书
- 2024年桃子项目规划设计方案
- 江苏省无锡外国语校2024年中考适应性考试物理试题含解析
- 二年级数学100以内加减法竖式计算题水平作业题
- 2023-2024年《ktv的装修施工合同样本范本模板 》
- 2022-2023学年部编版语文九年级下册第五单元整体教学设计
- 《创新创业》教材特色创新
- 家乡介绍-浙江嘉兴
- 体育俱乐部管理知到章节答案智慧树2023年成都文理学院
- 2023年05月四川省水电集团金阳电力有限公司员工公开招聘笔试高频考点题库附答案解析
- 小学语文口语交际教学案例
- 直销人必备的八大心态知识培训课程
- 重力式码头工程完整施工组织设计方案
- 2023年河北省普通高等学校对口招生考试英语试题
- 高校虚拟仿真实验室的建设浅析
- 把未来点亮歌词打印版
评论
0/150
提交评论