Reputation: 587
I tried to develop a mobile cardboard application, which renders 3d objects into a camera view (some kind of ar).
I used this project and tried to render a simple cube in the camera: https://github.com/Sveder/CardboardPassthrough/
I didn't get it working, the background is always black or the app wrecked.
I would be very grateful for any help or suggestions.
Thanks
here is the working code, with the cubes
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.Log;
import android.view.KeyEvent;
import com.google.vrtoolkit.cardboard.*;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class Card extends CardboardActivity implements CardboardView.StereoRenderer, SurfaceTexture.OnFrameAvailableListener {
private static final float CAMERA_Z = 0.01f;
private static final float TIME_DELTA = 0.3f;
private static final float YAW_LIMIT = 0.12f;
private static final float PITCH_LIMIT = 0.12f;
//---------------------------------------------------
private int intCurrentI = -1;
private int intCurrentI1 = -1;
//---------------------------------------------------
// We keep the light always position just above the user.
private final float[] mLightPosInWorldSpace = new float[]{0.0f, 2.0f, 0.0f, 1.0f};
private final float[] mLightPosInEyeSpace = new float[4];
private static final int COORDS_PER_VERTEX = 3;
private final WorldLayoutData DATA = new WorldLayoutData();
private FloatBuffer mCubeVertices;
private FloatBuffer mCubeColors;
private FloatBuffer mCubeFoundColors;
private FloatBuffer mCubeNormals;
private int mGlProgram;
private int mPositionParam;
private int mNormalParam;
private int mColorParam;
private int mModelViewProjectionParam;
private int mLightPosParam;
private int mModelViewParam;
private int mModelParam;
private int mIsFloorParam;
private float[] mModelCube;
private float[] mCamera;
private float[] mView;
private float[] mHeadView;
private float[] mModelViewProjection;
private float[] mModelView;
private float[] mModelCube2;
private float[] mModelFloor;
private float mObjectDistance = 12f;
private float mFloorDepth = 20f;
private Vibrator mVibrator;
private CardboardOverlayView mOverlayView;
private SurfaceTexture surface;
private Camera camera;
private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
private final String vertexShaderCode =
"attribute vec4 position;" +
"attribute vec2 inputTextureCoordinate;" +
"varying vec2 textureCoordinate;" +
"void main()" +
"{" +
"gl_Position = position;" +
"textureCoordinate = inputTextureCoordinate;" +
"}";
private final String fragmentShaderCode =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;" +
"varying vec2 textureCoordinate; \n" +
"uniform samplerExternalOES s_texture; \n" +
"void main(void) {" +
" gl_FragColor = texture2D( s_texture, textureCoordinate );\n" +
//" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" +
"}";
private int texture;
private CardboardView cardboardView;
/**
* Converts a raw text file, saved as a resource, into an OpenGL ES shader
*
* @param type The type of shader we will be creating.
* @param resId The resource ID of the raw text file about to be turned into a shader.
* @return
*/
private int loadGLShader(int type, int resId) {
String code = readRawTextFile(resId);
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, code);
GLES20.glCompileShader(shader);
// Get the compilation status.
final int[] compileStatus = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
// If the compilation failed, delete the shader.
if (compileStatus[0] == 0) {
GLES20.glDeleteShader(shader);
shader = 0;
}
if (shader == 0) {
throw new RuntimeException("Error creating shader.");
}
return shader;
}
/**
* Checks if we've had an error inside of OpenGL ES, and if so what that error is.
*
* @param func
*/
private static void checkGLError(String func) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
throw new RuntimeException(func + ": glError " + error);
}
}
/**
* Sets the view to our CardboardView and initializes the transformation matrices we will use
* to render our scene.
*
* @param savedInstanceState
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.common_ui);
cardboardView = (CardboardView) findViewById(R.id.cardboard_view);
/*********************/
cardboardView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
/*********************/
cardboardView.setRenderer(this);
setCardboardView(cardboardView);
/* 2014-10-16 */
mModelCube2 = new float[16];
/* 2014-10-16 */
mModelCube = new float[16];
mCamera = new float[16];
mView = new float[16];
mModelViewProjection = new float[16];
mModelView = new float[16];
mModelFloor = new float[16];
mHeadView = new float[16];
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mOverlayView = (CardboardOverlayView) findViewById(R.id.overlay);
mOverlayView.show3DToast("VR-Test");
}
@Override
public void onRendererShutdown() {
}
@Override
public void onSurfaceChanged(int width, int height) {
}
/**
* Creates the buffers we use to store information about the 3D world. OpenGL doesn't use Java
* arrays, but rather needs data in a format it can understand. Hence we use ByteBuffers.
*
* @param config The EGL configuration used when creating the surface.
*/
@Override
public void onSurfaceCreated(EGLConfig config) {
GLES20.glClearColor(0.1f, 0.1f, 0.1f, 0.5f); // Dark background so text shows up well
ByteBuffer bbVertices = ByteBuffer.allocateDirect(DATA.CUBE_COORDS.length * 4);
bbVertices.order(ByteOrder.nativeOrder());
mCubeVertices = bbVertices.asFloatBuffer();
mCubeVertices.put(DATA.CUBE_COORDS);
mCubeVertices.position(0);
ByteBuffer bbColors = ByteBuffer.allocateDirect(DATA.CUBE_COLORS.length * 4);
bbColors.order(ByteOrder.nativeOrder());
mCubeColors = bbColors.asFloatBuffer();
mCubeColors.put(DATA.CUBE_COLORS);
mCubeColors.position(0);
ByteBuffer bbFoundColors = ByteBuffer.allocateDirect(DATA.CUBE_FOUND_COLORS.length * 4);
bbFoundColors.order(ByteOrder.nativeOrder());
mCubeFoundColors = bbFoundColors.asFloatBuffer();
mCubeFoundColors.put(DATA.CUBE_FOUND_COLORS);
mCubeFoundColors.position(0);
ByteBuffer bbNormals = ByteBuffer.allocateDirect(DATA.CUBE_NORMALS.length * 4);
bbNormals.order(ByteOrder.nativeOrder());
mCubeNormals = bbNormals.asFloatBuffer();
mCubeNormals.put(DATA.CUBE_NORMALS);
mCubeNormals.position(0);
int vertexShader = loadGLShader(GLES20.GL_VERTEX_SHADER, R.raw.light_vertex);
int gridShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, R.raw.grid_fragment);
mGlProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mGlProgram, vertexShader);
GLES20.glAttachShader(mGlProgram, gridShader);
GLES20.glLinkProgram(mGlProgram);
texture = createTexture();
startCamera(texture);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
// Object first appears directly in front of user
Matrix.setIdentityM(mModelCube, 0);
Matrix.translateM(mModelCube, 0, 0, 0, -mObjectDistance);
Matrix.setIdentityM(mModelCube2, 0);
Matrix.translateM(mModelCube2, 0, -10.0f, -10.0f, -mObjectDistance - 12.0f);
Matrix.setIdentityM(mModelFloor, 0);
Matrix.translateM(mModelFloor, 0, 0, -mFloorDepth, 0); // Floor appears below user
checkGLError("onSurfaceCreated");
}
/**
* Converts a raw text file into a string.
*
* @param resId The resource ID of the raw text file about to be turned into a shader.
* @return
*/
private String readRawTextFile(int resId) {
InputStream inputStream = getResources().openRawResource(resId);
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* Prepares OpenGL ES before we draw a frame.
*
* @param headTransform The head transformation in the new frame.
*/
@Override
public void onNewFrame(HeadTransform headTransform) {
GLES20.glUseProgram(mGlProgram);
mModelViewProjectionParam = GLES20.glGetUniformLocation(mGlProgram, "u_MVP");
mLightPosParam = GLES20.glGetUniformLocation(mGlProgram, "u_LightPos");
mModelViewParam = GLES20.glGetUniformLocation(mGlProgram, "u_MVMatrix");
mModelParam = GLES20.glGetUniformLocation(mGlProgram, "u_Model");
mIsFloorParam = GLES20.glGetUniformLocation(mGlProgram, "u_IsFloor");
// Build the Model part of the ModelView matrix.
Matrix.rotateM(mModelCube, 0, TIME_DELTA, 0.5f, 0.5f, 1.0f);
Matrix.rotateM(mModelCube2, 0, TIME_DELTA, 0.5f, 0.5f, 1.0f);
//--------------------------------------
// Build the camera matrix and apply it to the ModelView.
Matrix.setLookAtM(mCamera, 0, 0.0f, 0.0f, CAMERA_Z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
headTransform.getHeadView(mHeadView, 0);
checkGLError("onReadyToDraw");
}
/**
* Draws a frame for an eye. The transformation for that eye (from the camera) is passed in as
* a parameter.
*
* @param transform The transformations to apply to render this eye.
*/
@Override
public void onDrawEye(EyeTransform transform) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
mPositionParam = GLES20.glGetAttribLocation(mGlProgram, "a_Position");
mNormalParam = GLES20.glGetAttribLocation(mGlProgram, "a_Normal");
mColorParam = GLES20.glGetAttribLocation(mGlProgram, "a_Color");
GLES20.glEnableVertexAttribArray(mPositionParam);
GLES20.glEnableVertexAttribArray(mNormalParam);
GLES20.glEnableVertexAttribArray(mColorParam);
checkGLError("mColorParam");
// Apply the eye transformation to the camera.
Matrix.multiplyMM(mView, 0, transform.getEyeView(), 0, mCamera, 0);
// Set the position of the light
Matrix.multiplyMV(mLightPosInEyeSpace, 0, mView, 0, mLightPosInWorldSpace, 0);
GLES20.glUniform3f(mLightPosParam, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1],
mLightPosInEyeSpace[2]);
// Build the ModelView and ModelViewProjection matrices
// for calculating cube position and light.
Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube, 0);
Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0,
mModelView, 0);
drawCube(1);
//--------------------------------------
Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube2, 0);
Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0,
mModelView, 0);
drawCube(0);
//--------------------------------------
}
@Override
public void onFinishFrame(Viewport viewport) {
}
public void drawCube(int i1) {
// This is not the floor!
GLES20.glUniform1f(mIsFloorParam, 0f);
// Set the Model in the shader, used to calculate lighting
if (i1 == 1) {
GLES20.glUniformMatrix4fv(mModelParam, 1, false, mModelCube, 0);
} else if (i1 == 0) {
//--2014-10-16 ??--------------------------------
GLES20.glUniformMatrix4fv(mModelParam, 1, false, mModelCube2, 0);
//-------------------------------------------------
}
// Set the ModelView in the shader, used to calculate lighting
GLES20.glUniformMatrix4fv(mModelViewParam, 1, false, mModelView, 0);
// Set the position of the cube
GLES20.glVertexAttribPointer(mPositionParam, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
false, 0, mCubeVertices);
// Set the ModelViewProjection matrix in the shader.
GLES20.glUniformMatrix4fv(mModelViewProjectionParam, 1, false, mModelViewProjection, 0);
// Set the normal positions of the cube, again for shading
GLES20.glVertexAttribPointer(mNormalParam, 3, GLES20.GL_FLOAT,
false, 0, mCubeNormals);
if (isLookingAtObject(i1)) {
GLES20.glVertexAttribPointer(mColorParam, 4, GLES20.GL_FLOAT, false,
0, mCubeFoundColors);
if (i1 == 1)
intCurrentI1 = i1;
else
intCurrentI1 = -1;
intCurrentI = i1;
System.out.println("drawCube->intCurrentI2:" + intCurrentI);
} else {
GLES20.glVertexAttribPointer(mColorParam, 4, GLES20.GL_FLOAT, false,
0, mCubeColors);
intCurrentI = -1;
}
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36);
checkGLError("Drawing cube");
if (intCurrentI1 != -1)
intCurrentI = intCurrentI1;
System.out.println("drawCube_out_if->intCurrentI4:" + intCurrentI);
}
private boolean isLookingAtObject(int i1) {
float[] initVec = {0, 0, 0, 1.0f};
float[] objPositionVec = new float[4];
System.out.println("isLookingAtObject1->i1:" + i1);
// Convert object space to camera space. Use the headView from onNewFrame.
if (i1 == 1) {
Matrix.multiplyMM(mModelView, 0, mHeadView, 0, mModelCube, 0);
Matrix.multiplyMV(objPositionVec, 0, mModelView, 0, initVec, 0);
intCurrentI = i1;
} else if (i1 == 0) {
Matrix.multiplyMM(mModelView, 0, mHeadView, 0, mModelCube2, 0);
Matrix.multiplyMV(objPositionVec, 0, mModelView, 0, initVec, 0);
intCurrentI = i1;
}
float pitch = (float) Math.atan2(objPositionVec[1], -objPositionVec[2]);
float yaw = (float) Math.atan2(objPositionVec[0], -objPositionVec[2]);
boolean bool1 = (Math.abs(pitch) < PITCH_LIMIT) && (Math.abs(yaw) < YAW_LIMIT);
return bool1;
}
public void startCamera(int texture) {
surface = new SurfaceTexture(texture);
surface.setOnFrameAvailableListener(this);
camera = Camera.open();
try {
camera.setPreviewTexture(surface);
camera.startPreview();
} catch (IOException ioe) {
Log.w("MainActivity", "CAM LAUNCH FAILED");
}
}
static private int createTexture() {
int[] texture = new int[1];
GLES20.glGenTextures(1, texture, 0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture[0]);
GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
return texture[0];
}
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
this.cardboardView.requestRender();
}
}
Edit 11.07.16
I cut the vertex in half, to see posible vertex behind it.
But i think the problem is vertex and fragment-shader
The Cube is only showing up, when im using this vertex and fragment-shader
simple_fragment.shader
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
light_vertex.shader
uniform mat4 u_MVP;
uniform mat4 u_MVMatrix;
uniform mat4 u_Model;
uniform vec3 u_LightPos;
uniform float u_IsFloor;
attribute vec4 a_Position;
attribute vec4 a_Color;
attribute vec3 a_Normal;
varying vec4 v_Color;
varying vec3 v_Grid;
varying float v_isFloor;
void main()
{
vec3 modelVertex = vec3(u_Model * a_Position);
v_Grid = modelVertex;
vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);
vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));
float distance = length(u_LightPos - modelViewVertex);
vec3 lightVector = normalize(u_LightPos - modelViewVertex);
float diffuse = max(dot(modelViewNormal, lightVector), 0.5 );
diffuse = diffuse * (1.0 / (1.0 + (0.00001 * distance * distance)));
v_Color = a_Color * diffuse;
gl_Position = u_MVP * a_Position;
v_isFloor = u_IsFloor;
}
and the camera is only showing up when im using this shaders
vertex.shader
attribute vec4 position;
attribute vec2 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate;
}
fragment.shader
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 textureCoordinate;
varying vec4 v_Color;
uniform samplerExternalOES s_texture;
void main(void) {
gl_FragColor = texture2D( s_texture, textureCoordinate );
}
i don't know how to fix the shaders
Upvotes: 3
Views: 2465
Reputation: 147
I would suggest that you disable glEnable(GL_DEPTH_TEST) to render background objects in the foreground then switch between shaders using:
GLES20.glUseProgram();
For your example this might be:
@Override
public void onSurfaceCreated(EGLConfig config) {
Log.i(TAG, "onSurfaceCreated");
GLES20.glClearColor(0.1f, 0.1f, 0.1f, 0.5f); // Dark background so text shows up well
ByteBuffer bb = ByteBuffer.allocateDirect(squareVertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareVertices);
vertexBuffer.position(0);
ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
ByteBuffer bb2 = ByteBuffer.allocateDirect(textureVertices.length * 4);
bb2.order(ByteOrder.nativeOrder());
textureVerticesBuffer = bb2.asFloatBuffer();
textureVerticesBuffer.put(textureVertices);
textureVerticesBuffer.position(0);
//Cube
ByteBuffer bbVertices = ByteBuffer.allocateDirect(DATA.CUBE_COORDS.length * 4);
bbVertices.order(ByteOrder.nativeOrder());
mCubeVertices = bbVertices.asFloatBuffer();
mCubeVertices.put(DATA.CUBE_COORDS);
mCubeVertices.position(0);
ByteBuffer bbColors = ByteBuffer.allocateDirect(DATA.CUBE_COLORS.length * 4);
bbColors.order(ByteOrder.nativeOrder());
mCubeColors = bbColors.asFloatBuffer();
mCubeColors.put(DATA.CUBE_COLORS);
mCubeColors.position(0);
ByteBuffer bbFoundColors = ByteBuffer.allocateDirect(DATA.CUBE_FOUND_COLORS.length * 4);
bbFoundColors.order(ByteOrder.nativeOrder());
mCubeFoundColors = bbFoundColors.asFloatBuffer();
mCubeFoundColors.put(DATA.CUBE_FOUND_COLORS);
mCubeFoundColors.position(0);
ByteBuffer bbNormals = ByteBuffer.allocateDirect(DATA.CUBE_NORMALS.length * 4);
bbNormals.order(ByteOrder.nativeOrder());
mCubeNormals = bbNormals.asFloatBuffer();
mCubeNormals.put(DATA.CUBE_NORMALS);
mCubeNormals.position(0);
int vertexShader = loadGLShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mCameraProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
GLES20.glAttachShader(mCameraProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mCameraProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mCameraProgram);
vertexShader = loadGLShader(GLES20.GL_VERTEX_SHADER, R.raw.light_vertex);
fragmentShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, R.raw.grid_fragment);
mCubeProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
GLES20.glAttachShader(mCubeProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mCubeProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mCubeProgram);
texture = createTexture();
startCamera(texture);
Matrix.setIdentityM(mModelCube, 0);
Matrix.translateM(mModelCube, 0, 0, 0, -mObjectDistance);
checkGLError("onSurfaceCreated");
}
@Override
public void onNewFrame(HeadTransform headTransform) {
GLES20.glUseProgram(mCubeProgram);
mModelViewProjectionParam = GLES20.glGetUniformLocation(mCubeProgram, "u_MVP");
mLightPosParam = GLES20.glGetUniformLocation(mCubeProgram, "u_LightPos");
mModelViewParam = GLES20.glGetUniformLocation(mCubeProgram, "u_MVMatrix");
mModelParam = GLES20.glGetUniformLocation(mCubeProgram, "u_Model");
mIsFloorParam = GLES20.glGetUniformLocation(mCubeProgram, "u_IsFloor");
// Build the Model part of the ModelView matrix.
Matrix.rotateM(mModelCube, 0, TIME_DELTA, 0.5f, 0.5f, 1.0f);
// Build the camera matrix and apply it to the ModelView.
Matrix.setLookAtM(mCamera, 0, 0.0f, 0.0f, CAMERA_Z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
headTransform.getHeadView(mHeadView, 0);
GLES20.glUseProgram(mCameraProgram);
float[] mtx = new float[16];
//GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
surface.updateTexImage();
surface.getTransformMatrix(mtx);
}
@Override
public void onDrawEye(EyeTransform transform) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
//Camera
GLES20.glUseProgram(mCameraProgram);
GLES20.glActiveTexture(GL_TEXTURE_EXTERNAL_OES);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
mPositionHandle = GLES20.glGetAttribLocation(mCameraProgram, "position");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
false, vertexStride, vertexBuffer);
mTextureCoordHandle = GLES20.glGetAttribLocation(mCameraProgram, "inputTextureCoordinate");
GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
GLES20.glVertexAttribPointer(mTextureCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
false, vertexStride, textureVerticesBuffer);
mColorHandle = GLES20.glGetAttribLocation(mCameraProgram, "s_texture");
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
//cube
GLES20.glUseProgram(mCubeProgram);
mPositionParam = GLES20.glGetAttribLocation(mCubeProgram, "a_Position");
mNormalParam = GLES20.glGetAttribLocation(mCubeProgram, "a_Normal");
mColorParam = GLES20.glGetAttribLocation(mCubeProgram, "a_Color");
GLES20.glEnableVertexAttribArray(mPositionParam);
GLES20.glEnableVertexAttribArray(mNormalParam);
GLES20.glEnableVertexAttribArray(mColorParam);
// Set the position of the light
Matrix.multiplyMV(mLightPosInEyeSpace, 0, mView, 0, mLightPosInWorldSpace, 0);
GLES20.glUniform3f(mLightPosParam, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1],
mLightPosInEyeSpace[2]);
Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube, 0);
Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0,
mModelView, 0);
drawCube(1);
Matrix.multiplyMM(mView, 0, transform.getEyeView(), 0, mCamera, 0);
Upvotes: 1
Reputation: 6884
Just an open suggestion. I developed an AR project for a University assignment I had, a couple of months ago. In my case I used a tool called Vuforia and integrated it with Unity for it to work on mobile devices. You can get your app to work on both Android and iOS devices. The latest releases of both Unity and Vuforia both help in the development of AR projects, since it is currently at its hype.
Depending on the work you need you AR project to perform, and your experience with Unity, the learning curve increases. In my case, I augmented the construction of a roof for a neolithical site. I also used a third party software called makehuman and Blender to create a walking human being. In all of my project, I didn't need to touch a line of code at all :)
Hope this helps.
Upvotes: 1