【移动应用开发技术】怎么在Android中利用OpenGLES绘制一个天空盒_第1页
【移动应用开发技术】怎么在Android中利用OpenGLES绘制一个天空盒_第2页
【移动应用开发技术】怎么在Android中利用OpenGLES绘制一个天空盒_第3页
【移动应用开发技术】怎么在Android中利用OpenGLES绘制一个天空盒_第4页
【移动应用开发技术】怎么在Android中利用OpenGLES绘制一个天空盒_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】怎么在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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论