高通ar android,vuforia android 教程(3) 替换vofuria模型 替换成自己的模型

在上一篇文章中,我们了解了如何替换识别图片

那么接下来,我们来替换 vuforia 模型

1. 准备工作

.obj格式的模型

将model.obj 和obj2opengl文件放到C\Perl\bin目录下

然后在命令行中执行perl obj2opengl.p1 model.obj

ff33aa2ffde5

image.png

执行以后会生成model.h

ff33aa2ffde5

image.png

2. 替换方式

其实替换两种方式,一个是像demo一样直接把数据放进去,另一个是通过.h文件来加载出来

2.1直接放的方式,可以参考teapot

/*===============================================================================

Copyright (c) 2016 PTC Inc. All Rights Reserved.

Copyright (c) 2012-2014 Qualcomm Connected Experiences, Inc. All Rights Reserved.

Vuforia is a trademark of PTC Inc., registered in the United States and other

countries.

===============================================================================*/

package com.vuforia.samples.SampleApplication.utils;

import java.nio.Buffer;

public class Teapot extends MeshObject

{

private Buffer mVertBuff;

private Buffer mTexCoordBuff;

private Buffer mNormBuff;

private Buffer mIndBuff;

private int indicesNumber = 0;

private int verticesNumber = 0;

public Teapot()

{

setVerts();

setTexCoords();

setNorms();

setIndices();

}

private void setVerts()

{

double[] TEAPOT_VERTS = { 11.222200, 0.110300, .......};

mVertBuff = fillBuffer(TEAPOT_VERTS);

verticesNumber = TEAPOT_VERTS.length / 3;

}

private void setTexCoords()

{

double[] TEAPOT_TEX_COORDS = { 0.608828, 0.354913,.... };

mTexCoordBuff = fillBuffer(TEAPOT_TEX_COORDS);

}

private void setNorms()

{

double[] TEAPOT_NORMS = { -0.964496, 0.067011,.....};

mNormBuff = fillBuffer(TEAPOT_NORMS);

}

private void setIndices()

{

short[] TEAPOT_INDICES = { 0, 1, 2, 2, 3.....};

mIndBuff = fillBuffer(TEAPOT_INDICES);

indicesNumber = TEAPOT_INDICES.length;

}

public int getNumObjectIndex()

{

return indicesNumber;

}

@Override

public int getNumObjectVertex()

{

return verticesNumber;

}

@Override

public Buffer getBuffer(BUFFER_TYPE bufferType)

{

Buffer result = null;

switch (bufferType)

{

case BUFFER_TYPE_VERTEX:

result = mVertBuff;

break;

case BUFFER_TYPE_TEXTURE_COORD:

result = mTexCoordBuff;

break;

case BUFFER_TYPE_NORMALS:

result = mNormBuff;

break;

case BUFFER_TYPE_INDICES:

result = mIndBuff;

default:

break;

}

return result;

}

}

2.2文件读取

先把model.h文件中modelVerts , modelNormals , modelTexCoords,单独提取出来,放入三个.txt文件中

ff33aa2ffde5

image.png

每个文件的结构都是复制出来的数据

ff33aa2ffde5

image.png

然后放入assets文件里

ff33aa2ffde5

image.png

最后就是写文件读取,我这里写了一个,大家可以参考一下

package com.vuforia.samples.SampleApplication.utils;

import android.content.res.AssetManager;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.nio.Buffer;

/**

* Created by Admin on 2017/11/21.

*/

public class TestModel extends MeshObject {

private static final String TAG="modelTest";

private Buffer mVertBuff;//顶点

private Buffer mTexCoordBuff;//纹理坐标

private Buffer mNormBuff;//normal

private int verticesNumber = 0;

private AssetManager assetManager;

public TestModel(AssetManager inputassetManager){

this.assetManager = inputassetManager;

setVerts();

setTexCoords();

setNorms();

}

double[] model_VERTS;

double[] model_TEX_COORDS;

double[] model_NORMS;

InputStream inputFile = null;

private int loadVertsFromModel(String fileName) throws IOException {

try{

inputFile = assetManager.open(fileName);

BufferedReader reader = new BufferedReader(new InputStreamReader(inputFile));

String line = reader.readLine();

int floatsToRead = 99519;

model_VERTS = new double[3*floatsToRead];

for(int i=0;i

String curline = reader.readLine();

if(curline.indexOf('/')>=0){

i--;

continue;

}

// 将一行分成3个数据

String floatStrs[] = curline.split(",");

model_VERTS[3 * i] = Float.parseFloat(floatStrs[0]);

model_VERTS[3 * i + 1] = Float.parseFloat(floatStrs[1]);

model_VERTS[3 * i + 2] = Float.parseFloat(floatStrs[2]);

}

return floatsToRead;

} finally {

if(inputFile !=null){

inputFile.close();

}

}

}

private int loadTexCoordsFromModel(String fileName)

throws IOException

{

try

{

inputFile = assetManager.open(fileName);

BufferedReader reader = new BufferedReader(

new InputStreamReader(inputFile));

String line = reader.readLine();

int floatsToRead = 99519;

model_TEX_COORDS = new double[2*floatsToRead];

for (int i = 0; i < floatsToRead; i++)

{

String curline = reader.readLine();

if( curline.indexOf('/') >= 0 ){

i--;

continue;

}

//将一行分成两个数据

String floatStrs[] = curline.split(",");

model_TEX_COORDS[2*i] = Float.parseFloat("".equals(floatStrs[0].replaceAll(" ","")) ? "0" : floatStrs[0]);

model_TEX_COORDS[2*i+1] = Float.parseFloat("".equals(floatStrs[1].replaceAll(" ","")) ? "0" : floatStrs[1]);

}

return floatsToRead;

} finally

{

if (inputFile != null)

inputFile.close();

}

}

private int loadNormsFromModel(String fileName)

throws IOException

{

try

{

inputFile = assetManager.open(fileName);

BufferedReader reader = new BufferedReader(

new InputStreamReader(inputFile));

String line = reader.readLine();

int floatsToRead = 99519;

model_NORMS = new double[3*floatsToRead];

for (int i = 0; i < floatsToRead; i++)

{

String curline = reader.readLine();

if( curline.indexOf('/') >= 0 ){

i--;

continue;

}

//将一行分成三个数据

String floatStrs[] = curline.split(",");

model_NORMS[3*i] = Float.parseFloat(floatStrs[0]);

model_NORMS[3*i+1] = Float.parseFloat(floatStrs[1]);

model_NORMS[3*i+2] = Float.parseFloat(floatStrs[2]);

}

return floatsToRead;

} finally

{

if (inputFile != null)

inputFile.close();

}

}

private void setVerts(){

int num = 0;

try{

num = loadVertsFromModel("ImageTargets/model/verts.txt");

} catch(IOException e){

e.printStackTrace();

}

mVertBuff = fillBuffer(model_VERTS);

verticesNumber = num;

}

private void setTexCoords()

{

int num = 0;

try {

num = loadTexCoordsFromModel("ImageTargets/model/texcoords.txt");

} catch (IOException e) {

e.printStackTrace();

}

mTexCoordBuff = fillBuffer(model_TEX_COORDS);

}

private void setNorms()

{

int num = 0;

try {

num = loadNormsFromModel("ImageTargets/model/norms.txt");

} catch (IOException e) {

e.printStackTrace();

}

mNormBuff = fillBuffer(model_NORMS);

}

public int getNumObjectIndex()

{

return 0;

}

@Override

public int getNumObjectVertex()

{

return verticesNumber;

}

@Override

public Buffer getBuffer(BUFFER_TYPE bufferType)

{

Buffer result = null;

switch (bufferType)

{

case BUFFER_TYPE_VERTEX:

result = mVertBuff;

break;

case BUFFER_TYPE_TEXTURE_COORD:

result = mTexCoordBuff;

break;

case BUFFER_TYPE_NORMALS:

result = mNormBuff;

break;

default:

break;

}

return result;

}

}

注意 : int floatsToRead = 99519; 这个值是model.h里面的值

ff33aa2ffde5

image.png

3. 开始替换

3.1 修改ImageTargetRenderer.java的文件

首先新建一个TestModel 变量

private TestModel testModel;

然后在initRendering方法给testmodel初始化

// Function for initializing the renderer.

private void initRendering()

{

testModel = new TestModel(mActivity.getResources().getAssets());

GLES20.glClearColor(0.0f, 0.0f, 0.0f, Vuforia.requiresAlpha() ? 0.0f

: 1.0f);

for (Texture t : mTextures)

{

GLES20.glGenTextures(1, t.mTextureID, 0);

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, t.mTextureID[0]);

GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,

GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);

GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,

GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,

t.mWidth, t.mHeight, 0, GLES20.GL_RGBA,

GLES20.GL_UNSIGNED_BYTE, t.mData);

}

shaderProgramID = SampleUtils.createProgramFromShaderSrc(

CubeShaders.CUBE_MESH_VERTEX_SHADER,

CubeShaders.CUBE_MESH_FRAGMENT_SHADER);

vertexHandle = GLES20.glGetAttribLocation(shaderProgramID,

"vertexPosition");

textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramID,

"vertexTexCoord");

mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramID,

"modelViewProjectionMatrix");

texSampler2DHandle = GLES20.glGetUniformLocation(shaderProgramID,

"texSampler2D");

if(!mModelIsLoaded) {

mTeapot = new Teapot();

try {

mBuildingsModel = new SampleApplication3DModel();

mBuildingsModel.loadModel(mActivity.getResources().getAssets(),

"ImageTargets/Buildings.txt");

mModelIsLoaded = true;

} catch (IOException e) {

Log.e(LOGTAG, "Unable to load buildings");

}

// Hide the Loading Dialog

mActivity.loadingDialogHandler

.sendEmptyMessage(LoadingDialogHandler.HIDE_LOADING_DIALOG);

}

}

接着是在renderFrame方法加载进来

// The render function called from SampleAppRendering by using RenderingPrimitives views.

// The state is owned by SampleAppRenderer which is controlling it's lifecycle.

// State should not be cached outside this method.

public void renderFrame(State state, float[] projectionMatrix)

{

.....

.....

if (!mActivity.isExtendedTrackingActive()) {

GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT,

false, 0, testModel.getVertices());

//false, 0, mTeapot.getVertices());

GLES20.glVertexAttribPointer(textureCoordHandle, 2,

GLES20.GL_FLOAT, false, 0, testModel.getTexCoords());

//GLES20.GL_FLOAT, false, 0, mTeapot.getTexCoords());

GLES20.glEnableVertexAttribArray(vertexHandle);

GLES20.glEnableVertexAttribArray(textureCoordHandle);

// activate texture 0, bind it, and pass to shader

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,

mTextures.get(textureIndex).mTextureID[0]);

GLES20.glUniform1i(texSampler2DHandle, 0);

// pass the model view matrix to the shader

GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false,

modelViewProjection, 0);

// finally draw the teapot

GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0,

testModel.getNumObjectVertex());

//GLES20.glDrawElements(GLES20.GL_TRIANGLES,

//mTeapot.getNumObjectIndex(), GLES20.GL_UNSIGNED_SHORT,

//mTeapot.getIndices());

// disable the enabled arrays

GLES20.glDisableVertexAttribArray(vertexHandle);

GLES20.glDisableVertexAttribArray(textureCoordHandle);

} else {

GLES20.glDisable(GLES20.GL_CULL_FACE);

GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT,

false, 0, testModel.getVertices());

//false, 0, mBuildingsModel.getVertices());

GLES20.glVertexAttribPointer(textureCoordHandle, 2,

GLES20.GL_FLOAT, false, 0, testModel.getTexCoords());

//GLES20.GL_FLOAT, false, 0, mBuildingsModel.getTexCoords());

GLES20.glEnableVertexAttribArray(vertexHandle);

GLES20.glEnableVertexAttribArray(textureCoordHandle);

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,

mTextures.get(3).mTextureID[0]);

GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false,

modelViewProjection, 0);

GLES20.glUniform1i(texSampler2DHandle, 0);

GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0,

testModel.getNumObjectVertex());

//mBuildingsModel.getNumObjectVertex());

SampleUtils.checkGLError("Renderer DrawBuildings");

}

SampleUtils.checkGLError("Render Frame");

}

GLES20.glDisable(GLES20.GL_DEPTH_TEST);

}

3.2替换贴图 , 修改ImageTargets.java的代码

修改贴图loadTextures方法

// We want to load specific textures from the APK, which we will later use

// for rendering.

private void loadTextures()

{

mTextures.add(Texture.loadTextureFromApk("testmodel.jpg",

getAssets()));

// mTextures.add(Texture.loadTextureFromApk("TextureTeapotBrass.png",

// getAssets()));;

/* mTextures.add(Texture.loadTextureFromApk("001.jpg",

getAssets()));;*/

// mTextures.add(Texture.loadTextureFromApk("TextureTeapotBrass.png",

// getAssets()));;

//

// mTextures.add(Texture.loadTextureFromApk("TextureTeapotBlue.png",

// getAssets()));

// mTextures.add(Texture.loadTextureFromApk("TextureTeapotRed.png",

// getAssets()));

mTextures.add(Texture.loadTextureFromApk("ImageTargets/Buildings.jpeg",

getAssets()));

}

大功告成

ff33aa2ffde5

Screenshot_2017-12-27-20-26-33-939.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值