在对象识别中使用 Teapot 而不是 CubeObject
use Teapot instead of CubeObject in object recognition
我试图在对象识别示例应用程序中使用茶壶而不是立方体对象,但茶壶离我的目标太远了。
非常感谢任何帮助。
这是我的 ObjectTargetRenderer:
public class ObjectTargetRenderer implements GLSurfaceView.Renderer, SampleAppRendererControl
{
private static final String LOGTAG = "ObjectTargetRenderer";
private SampleApplicationSession vuforiaAppSession;
private ObjectTargets mActivity;
private SampleAppRenderer mSampleAppRenderer;
private Vector<Texture> mTextures;
private int shaderProgramID;
private int vertexHandle;
private int textureCoordHandle;
private int texSampler2DHandle;
private int mvpMatrixHandle;
private int opacityHandle;
private int colorHandle;
private CubeObject mCubeObject;
private Teapot mTeapot;
private Renderer mRenderer;
private boolean mIsActive = false;
public ObjectTargetRenderer(ObjectTargets activity,
SampleApplicationSession session)
{
mActivity = activity;
vuforiaAppSession = session;
// SampleAppRenderer used to encapsulate the use of RenderingPrimitives setting
// the device mode AR/VR and stereo mode
mSampleAppRenderer = new SampleAppRenderer(this, mActivity, Device.MODE.MODE_AR, false, 10f, 5000f);
}
// Called to draw the current frame.
@Override
public void onDrawFrame(GL10 gl)
{
if (!mIsActive)
return;
// Call our function to render content from SampleAppRenderer class
mSampleAppRenderer.render();
}
// Called when the surface is created or recreated.
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
Log.d(LOGTAG, "GLRenderer.onSurfaceCreated");
// Call Vuforia function to (re)initialize rendering after first use
// or after OpenGL ES context was lost (e.g. after onPause/onResume):
vuforiaAppSession.onSurfaceCreated();
mSampleAppRenderer.onSurfaceCreated();
}
// Called when the surface changed size.
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
Log.d(LOGTAG, "GLRenderer.onSurfaceChanged");
// Call Vuforia function to handle render surface size changes:
vuforiaAppSession.onSurfaceChanged(width, height);
// RenderingPrimitives to be updated when some rendering change is done
mSampleAppRenderer.onConfigurationChanged(mIsActive);
// Init rendering
initRendering();
}
public void setActive(boolean active)
{
mIsActive = active;
if(mIsActive)
mSampleAppRenderer.configureVideoBackground();
}
// Function for initializing the renderer.
private void initRendering()
{
// mCubeObject = new CubeObject();
mTeapot = new Teapot();
mRenderer = Renderer.getInstance();
// Now generate the OpenGL texture objects and add settings
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);
}
SampleUtils.checkGLError("ObjectTarget GLInitRendering");
GLES20.glClearColor(0.0f, 0.0f, 0.0f, Vuforia.requiresAlpha() ? 0.0f
: 1.0f);
shaderProgramID = SampleUtils.createProgramFromShaderSrc(
CubeShaders.CUBE_MESH_VERTEX_SHADER,
CubeShaders.CUBE_MESH_FRAGMENT_SHADER);
vertexHandle = GLES20.glGetAttribLocation(shaderProgramID,
"vertexPosition");
textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramID,
"vertexTexCoord");
texSampler2DHandle = GLES20.glGetUniformLocation(shaderProgramID,
"texSampler2D");
mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramID,
"modelViewProjectionMatrix");
opacityHandle = GLES20.glGetUniformLocation(shaderProgramID,
"opacity");
colorHandle = GLES20.glGetUniformLocation(shaderProgramID, "color");
// Hide the Loading Dialog
mActivity.loadingDialogHandler
.sendEmptyMessage(LoadingDialogHandler.HIDE_LOADING_DIALOG);
}
// 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)
{
// Renders video background replacing Renderer.DrawVideoBackground()
mSampleAppRenderer.renderVideoBackground();
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
// did we find any trackables this frame?
for (int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++)
{
TrackableResult result = state.getTrackableResult(tIdx);
Trackable trackable = result.getTrackable();
printUserData(trackable);
if (!result.isOfType(ObjectTargetResult.getClassType()))
continue;
ObjectTarget objectTarget = (ObjectTarget) trackable;
Matrix44F modelViewMatrix_Vuforia = Tool
.convertPose2GLMatrix(result.getPose());
float[] modelViewMatrix = modelViewMatrix_Vuforia.getData();
// deal with the modelview and projection matrices
float[] modelViewProjection = new float[16];
float[] objectSize = objectTarget.getSize().getData();
Matrix.translateM(modelViewMatrix, 0, objectSize[0]/2, objectSize[1]/2,
objectSize[2]/2);
Matrix.scaleM(modelViewMatrix, 0, objectSize[0]/2,
objectSize[1]/2, objectSize[2]/2);
Matrix.multiplyMM(modelViewProjection, 0, projectionMatrix, 0, modelViewMatrix, 0);
// activatrigidBodyTarget.xmle the shader program and bind the vertex/normal/tex coords
GLES20.glUseProgram(shaderProgramID);
GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT,
false, 0, mTeapot.getVertices());
GLES20.glUniform1f(opacityHandle, 0.3f);
GLES20.glUniform3f(colorHandle, 0.0f, 0.0f, 0.0f);
GLES20.glVertexAttribPointer(textureCoordHandle, 2,
GLES20.GL_FLOAT, false, 0, mTeapot.getTexCoords());
GLES20.glEnableVertexAttribArray(vertexHandle);
GLES20.glEnableVertexAttribArray(textureCoordHandle);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,
mTextures.get(0).mTextureID[0]);
GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false,
modelViewProjection, 0);
GLES20.glUniform1i(texSampler2DHandle, 0);
// pass the model view matrix to the shader
GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false,
modelViewProjection, 0);
// finally render
GLES20.glDrawElements(GLES20.GL_TRIANGLES,
mTeapot.getNumObjectIndex(), GLES20.GL_UNSIGNED_SHORT,
mTeapot.getIndices());
// disable the enabled arrays
GLES20.glDisableVertexAttribArray(vertexHandle);
GLES20.glDisableVertexAttribArray(textureCoordHandle);
SampleUtils.checkGLError("Render Frame");
}
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glDisable(GLES20.GL_BLEND);
mRenderer.end();
}
private void printUserData(Trackable trackable)
{
String userData = (String) trackable.getUserData();
Log.d(LOGTAG, "UserData:Retreived User Data \"" + userData + "\"");
}
public void setTextures(Vector<Texture> textures)
{
mTextures = textures;
}
}
如果物体很远,可能是Z平移或缩放有误。检查您的 objectSize[2] 是否正确。无论如何,你可以用Matrix.translateM控制距离(最后一个参数是Z)
我试图在对象识别示例应用程序中使用茶壶而不是立方体对象,但茶壶离我的目标太远了。
非常感谢任何帮助。
这是我的 ObjectTargetRenderer:
public class ObjectTargetRenderer implements GLSurfaceView.Renderer, SampleAppRendererControl
{
private static final String LOGTAG = "ObjectTargetRenderer";
private SampleApplicationSession vuforiaAppSession;
private ObjectTargets mActivity;
private SampleAppRenderer mSampleAppRenderer;
private Vector<Texture> mTextures;
private int shaderProgramID;
private int vertexHandle;
private int textureCoordHandle;
private int texSampler2DHandle;
private int mvpMatrixHandle;
private int opacityHandle;
private int colorHandle;
private CubeObject mCubeObject;
private Teapot mTeapot;
private Renderer mRenderer;
private boolean mIsActive = false;
public ObjectTargetRenderer(ObjectTargets activity,
SampleApplicationSession session)
{
mActivity = activity;
vuforiaAppSession = session;
// SampleAppRenderer used to encapsulate the use of RenderingPrimitives setting
// the device mode AR/VR and stereo mode
mSampleAppRenderer = new SampleAppRenderer(this, mActivity, Device.MODE.MODE_AR, false, 10f, 5000f);
}
// Called to draw the current frame.
@Override
public void onDrawFrame(GL10 gl)
{
if (!mIsActive)
return;
// Call our function to render content from SampleAppRenderer class
mSampleAppRenderer.render();
}
// Called when the surface is created or recreated.
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
Log.d(LOGTAG, "GLRenderer.onSurfaceCreated");
// Call Vuforia function to (re)initialize rendering after first use
// or after OpenGL ES context was lost (e.g. after onPause/onResume):
vuforiaAppSession.onSurfaceCreated();
mSampleAppRenderer.onSurfaceCreated();
}
// Called when the surface changed size.
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
Log.d(LOGTAG, "GLRenderer.onSurfaceChanged");
// Call Vuforia function to handle render surface size changes:
vuforiaAppSession.onSurfaceChanged(width, height);
// RenderingPrimitives to be updated when some rendering change is done
mSampleAppRenderer.onConfigurationChanged(mIsActive);
// Init rendering
initRendering();
}
public void setActive(boolean active)
{
mIsActive = active;
if(mIsActive)
mSampleAppRenderer.configureVideoBackground();
}
// Function for initializing the renderer.
private void initRendering()
{
// mCubeObject = new CubeObject();
mTeapot = new Teapot();
mRenderer = Renderer.getInstance();
// Now generate the OpenGL texture objects and add settings
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);
}
SampleUtils.checkGLError("ObjectTarget GLInitRendering");
GLES20.glClearColor(0.0f, 0.0f, 0.0f, Vuforia.requiresAlpha() ? 0.0f
: 1.0f);
shaderProgramID = SampleUtils.createProgramFromShaderSrc(
CubeShaders.CUBE_MESH_VERTEX_SHADER,
CubeShaders.CUBE_MESH_FRAGMENT_SHADER);
vertexHandle = GLES20.glGetAttribLocation(shaderProgramID,
"vertexPosition");
textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramID,
"vertexTexCoord");
texSampler2DHandle = GLES20.glGetUniformLocation(shaderProgramID,
"texSampler2D");
mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramID,
"modelViewProjectionMatrix");
opacityHandle = GLES20.glGetUniformLocation(shaderProgramID,
"opacity");
colorHandle = GLES20.glGetUniformLocation(shaderProgramID, "color");
// Hide the Loading Dialog
mActivity.loadingDialogHandler
.sendEmptyMessage(LoadingDialogHandler.HIDE_LOADING_DIALOG);
}
// 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)
{
// Renders video background replacing Renderer.DrawVideoBackground()
mSampleAppRenderer.renderVideoBackground();
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
// did we find any trackables this frame?
for (int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++)
{
TrackableResult result = state.getTrackableResult(tIdx);
Trackable trackable = result.getTrackable();
printUserData(trackable);
if (!result.isOfType(ObjectTargetResult.getClassType()))
continue;
ObjectTarget objectTarget = (ObjectTarget) trackable;
Matrix44F modelViewMatrix_Vuforia = Tool
.convertPose2GLMatrix(result.getPose());
float[] modelViewMatrix = modelViewMatrix_Vuforia.getData();
// deal with the modelview and projection matrices
float[] modelViewProjection = new float[16];
float[] objectSize = objectTarget.getSize().getData();
Matrix.translateM(modelViewMatrix, 0, objectSize[0]/2, objectSize[1]/2,
objectSize[2]/2);
Matrix.scaleM(modelViewMatrix, 0, objectSize[0]/2,
objectSize[1]/2, objectSize[2]/2);
Matrix.multiplyMM(modelViewProjection, 0, projectionMatrix, 0, modelViewMatrix, 0);
// activatrigidBodyTarget.xmle the shader program and bind the vertex/normal/tex coords
GLES20.glUseProgram(shaderProgramID);
GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT,
false, 0, mTeapot.getVertices());
GLES20.glUniform1f(opacityHandle, 0.3f);
GLES20.glUniform3f(colorHandle, 0.0f, 0.0f, 0.0f);
GLES20.glVertexAttribPointer(textureCoordHandle, 2,
GLES20.GL_FLOAT, false, 0, mTeapot.getTexCoords());
GLES20.glEnableVertexAttribArray(vertexHandle);
GLES20.glEnableVertexAttribArray(textureCoordHandle);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,
mTextures.get(0).mTextureID[0]);
GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false,
modelViewProjection, 0);
GLES20.glUniform1i(texSampler2DHandle, 0);
// pass the model view matrix to the shader
GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false,
modelViewProjection, 0);
// finally render
GLES20.glDrawElements(GLES20.GL_TRIANGLES,
mTeapot.getNumObjectIndex(), GLES20.GL_UNSIGNED_SHORT,
mTeapot.getIndices());
// disable the enabled arrays
GLES20.glDisableVertexAttribArray(vertexHandle);
GLES20.glDisableVertexAttribArray(textureCoordHandle);
SampleUtils.checkGLError("Render Frame");
}
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glDisable(GLES20.GL_BLEND);
mRenderer.end();
}
private void printUserData(Trackable trackable)
{
String userData = (String) trackable.getUserData();
Log.d(LOGTAG, "UserData:Retreived User Data \"" + userData + "\"");
}
public void setTextures(Vector<Texture> textures)
{
mTextures = textures;
}
}
如果物体很远,可能是Z平移或缩放有误。检查您的 objectSize[2] 是否正确。无论如何,你可以用Matrix.translateM控制距离(最后一个参数是Z)