void drawCube(float *viewProjectionMatrix, float size, float x, float y, float z) { // Colour cube data. int i; const GLfloat cube_vertices [8][3] = { /* +z */ {0.5f, 0.5f, 0.5f}, {0.5f, -0.5f, 0.5f}, {-0.5f, -0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f}, /* -z */ {0.5f, 0.5f, -0.5f}, {0.5f, -0.5f, -0.5f}, {-0.5f, -0.5f, -0.5f}, {-0.5f, 0.5f, -0.5f} }; const GLubyte cube_vertex_colors [8][4] = { {255, 255, 255, 255}, {255, 255, 0, 255}, {0, 255, 0, 255}, {0, 255, 255, 255}, {255, 0, 255, 255}, {255, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 255, 255} }; const GLubyte cube_vertex_colors_black [8][4] = { {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255} }; const GLushort cube_faces [6][4] = { /* ccw-winding */ /* +z */ {3, 2, 1, 0}, /* -y */ {2, 3, 7, 6}, /* +y */ {0, 1, 5, 4}, /* -x */ {3, 0, 4, 7}, /* +x */ {1, 2, 6, 5}, /* -z */ {4, 5, 6, 7} }; float modelViewProjection[16]; mtxLoadMatrixf(modelViewProjection, viewProjectionMatrix); mtxTranslatef(modelViewProjection, x, y, z); // Rotate about z axis. mtxScalef(modelViewProjection, size, size, size); glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEW_PROJECTION_MATRIX], 1, GL_FALSE, modelViewProjection); glVertexAttribPointer(ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, cube_vertices); glEnableVertexAttribArray(ATTRIBUTE_VERTEX); glVertexAttribPointer(ATTRIBUTE_COLOUR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, cube_vertex_colors); glEnableVertexAttribArray(ATTRIBUTE_COLOUR); #ifdef DEBUG if (!arglGLValidateProgram(program)) { ARLOGe("Error: shader program %d validation failed.\n", program); return; } #endif for (i = 0; i < 6; i++) { glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, &(cube_faces[i][0])); } glVertexAttribPointer(ATTRIBUTE_COLOUR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, cube_vertex_colors_black); glEnableVertexAttribArray(ATTRIBUTE_COLOUR); for (i = 0; i < 6; i++) { glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, &(cube_faces[i][0])); } }
JNIEXPORT void JNICALL JNIFUNCTION_NATIVE(nativeDrawFrame(JNIEnv* env, jobject obj)) { float width, height; float viewProjection[16]; if (!videoInited) { #ifdef DEBUG LOGI("nativeDrawFrame !VIDEO\n"); #endif return; // No point in trying to draw until video is inited. } #ifdef DEBUG LOGI("nativeDrawFrame\n"); #endif if (!gARViewInited) { if (!initARView()) return; } if (gARViewLayoutRequired) layoutARView(); // Upload new video frame if required. if (videoFrameNeedsPixelBufferDataUpload) { arglPixelBufferDataUploadBiPlanar(gArglSettings, gVideoFrame, gVideoFrame + videoWidth*videoHeight); videoFrameNeedsPixelBufferDataUpload = false; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame. // Display the current frame arglDispImage(gArglSettings); if (!program) { GLuint vertShader = 0, fragShader = 0; // A simple shader pair which accepts just a vertex position and colour, no lighting. const char vertShaderString[] = "attribute vec4 position;\n" "attribute vec4 colour;\n" "uniform mat4 modelViewProjectionMatrix;\n" "varying vec4 colourVarying;\n" "void main()\n" "{\n" "gl_Position = modelViewProjectionMatrix * position;\n" "colourVarying = colour;\n" "}\n"; const char fragShaderString[] = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "varying vec4 colourVarying;\n" "void main()\n" "{\n" "gl_FragColor = colourVarying;\n" "}\n"; if (program) arglGLDestroyShaders(0, 0, program); program = glCreateProgram(); if (!program) { ARLOGe("drawCube: Error creating shader program.\n"); arglGLDestroyShaders(vertShader, fragShader, program); return; } if (!arglGLCompileShaderFromString(&vertShader, GL_VERTEX_SHADER, vertShaderString)) { ARLOGe("drawCube: Error compiling vertex shader.\n"); arglGLDestroyShaders(vertShader, fragShader, program); return; } if (!arglGLCompileShaderFromString(&fragShader, GL_FRAGMENT_SHADER, fragShaderString)) { ARLOGe("drawCube: Error compiling fragment shader.\n"); arglGLDestroyShaders(vertShader, fragShader, program); return; } glAttachShader(program, vertShader); glAttachShader(program, fragShader); glBindAttribLocation(program, ATTRIBUTE_VERTEX, "position"); glBindAttribLocation(program, ATTRIBUTE_COLOUR, "colour"); if (!arglGLLinkProgram(program)) { ARLOGe("drawCube: Error linking shader program.\n"); arglGLDestroyShaders(vertShader, fragShader, program); return; } arglGLDestroyShaders(vertShader, fragShader, 0); // After linking, shader objects can be deleted. // Retrieve linked uniform locations. uniforms[UNIFORM_MODELVIEW_PROJECTION_MATRIX] = glGetUniformLocation(program, "modelViewProjectionMatrix"); } glUseProgram(program); // Set up 3D mode. mtxLoadIdentityf(viewProjection); mtxMultMatrixf(viewProjection, cameraLens); glStateCacheEnableDepthTest(); // Set any initial per-frame GL state you require here. // ---> // Lighting and geometry that moves with the camera should be added here. // (I.e. should be specified before camera pose transform.) // ---> // Draw an object on all valid markers. for (int i = 0; i < markersSquareCount; i++) { if (markersSquare[i].valid) { float viewProjection2[16]; mtxLoadMatrixf(viewProjection2, viewProjection); mtxMultMatrixf(viewProjection2, markersSquare[i].pose.T); drawCube(viewProjection2, 40.0f, 0.0f, 0.0f, 20.0f); } } if (cameraPoseValid) { mtxMultMatrixf(viewProjection, cameraPose); // All lighting and geometry to be drawn in world coordinates goes here. // ---> } // If you added external OpenGL code above, and that code doesn't use the glStateCache routines, // then uncomment the line below. //glStateCacheFlush(); // Set up 2D mode. mtxLoadIdentityf(viewProjection); width = (float)viewPort[viewPortIndexWidth]; height = (float)viewPort[viewPortIndexHeight]; mtxOrthof(viewProjection, 0.0f, width, 0.0f, height, -1.0f, 1.0f); glStateCacheDisableDepthTest(); // Add your own 2D overlays here. // ---> // If you added external OpenGL code above, and that code doesn't use the glStateCache routines, // then uncomment the line below. //glStateCacheFlush(); #ifdef DEBUG // Example of 2D drawing. It just draws a white border line. Change the 0 to 1 to enable. const GLfloat square_vertices [4][3] = { {0.5f, 0.5f, 0.0f}, {0.5f, height - 0.5f, 0.0f}, {width - 0.5f, height - 0.5f, 0.0f}, {width - 0.5f, 0.5f, 0.0f} }; const GLubyte square_vertex_colors_white [4][4] = { {255, 255, 255, 255}, {255, 255, 255, 255}, {255, 255, 255, 255}, {255, 255, 255, 255}}; glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEW_PROJECTION_MATRIX], 1, GL_FALSE, viewProjection); glVertexAttribPointer(ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, square_vertices); glEnableVertexAttribArray(ATTRIBUTE_VERTEX); glVertexAttribPointer(ATTRIBUTE_COLOUR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, square_vertex_colors_white); glEnableVertexAttribArray(ATTRIBUTE_COLOUR); if (!arglGLValidateProgram(program)) { ARLOGe("Error: shader program %d validation failed.\n", program); return; } glDrawArrays(GL_LINE_LOOP, 0, 4); #endif #ifdef DEBUG CHECK_GL_ERROR(); #endif }