Rendering

This example shows and explain how rendering works in combination with the Wikitude SDK Native API. There are two methods of rendering available in the Wikitude Native SDK. We call them internal and external rendering. Internal means the OpenGL view is setup by the Wikitude SDK and the SDK user can define custom rendering, that is executed by the Wikitude SDK. On the other hand external rendering means the SDK user sets up the OpenGL view and integrates the Wikitude SDK into this rendering setup.

External Rendering

To activate external rendering you need to pass an object implementing the ExternalRendering interface to the constructor of the WikitudeSDK class. In the following example this object will be an instance of the ExternalRenderingActivity class which you can find in our sample application under the package com.wikitude.samples.rendering.external.

public class ExternalRenderingActivity extends Activity implements ClientTrackerEventListener, ExternalRendering {

    private WikitudeSDK _wikitudeSDK;
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        _wikitudeSDK = new WikitudeSDK(this);

In the method onRenderExtensionCreated which is defined by the ExternalRendering interface we receive a RenderExtension instance as a parameter. We pass that parameter to our OpenGL renderer which extends GLSurfaceView.Renderer. We also create a Driver which calls the Renderer 30 times per second to draw the current frame.

    @Override
    public void onRenderExtensionCreated(final RenderExtension renderExtension_) {
        _glRenderer = new GLRenderer(renderExtension_);
        _view = new CustomSurfaceView(getApplicationContext(), _glRenderer);
        _driver = new Driver(_view, 30);
        setContentView(_view);
    }

The following code shows a very basic implementation of a GLSurfaceView.Renderer. Please note that the first thing to do in every method is to call the WikitudeSDK RenderExtension, otherwise the WikitudeSDK won't be able to render the camera frame or perform any image recognition.

public class GLRenderer implements GLSurfaceView.Renderer, RenderExtension {

    private RenderExtension _wikitudeRenderExtension = null;
    private RecognizedTarget _currentlyRecognizedTarget = null;
    private StrokedRectangle _strokedRectangle;

    public GLRenderer(RenderExtension wikitudeRenderExtension_) {
        _wikitudeRenderExtension = wikitudeRenderExtension_;
    }

    @Override
    public void onDrawFrame(final GL10 unused) {
        if (_wikitudeRenderExtension != null) {
            _wikitudeRenderExtension.onDrawFrame(unused);
        }
        if (_currentlyRecognizedTarget != null) {
            _strokedRectangle.onDrawFrame(_currentlyRecognizedTarget);
        }
    }

    @Override
    public void onSurfaceCreated(final GL10 unused, final EGLConfig config) {
        if (_wikitudeRenderExtension != null) {
            _wikitudeRenderExtension.onSurfaceCreated(unused, config);
        }
        _strokedRectangle = new StrokedRectangle();
    }

    @Override
    public void onSurfaceChanged(final GL10 unused, final int width, final int height) {
        if (_wikitudeRenderExtension != null) {
            _wikitudeRenderExtension.onSurfaceChanged(unused, width, height);
        }
    }

    public void onResume() {
        if (_wikitudeRenderExtension != null) {
            _wikitudeRenderExtension.onResume();
        }
    }

    public void onPause() {
        if (_wikitudeRenderExtension != null) {
            _wikitudeRenderExtension.onPause();
        }
    }

    public void setCurrentlyRecognizedTarget(final RecognizedTarget currentlyRecognizedTarget_) {
        _currentlyRecognizedTarget = currentlyRecognizedTarget_;
    }

}

Internal Rendering

To activate internal rendering you need to pass an object implementing the InternalRendering interface to the constructor of the WikitudeSDK class. In the following example this object will be an instance of the InternalRenderingActivity which you can find in our sample application under the package com.wikitude.samples.rendering.internal.

public class InternalRenderingActivity extends Activity implements InternalRendering, ClientTrackerEventListener {
    ...
    private WikitudeSDK _wikitudeSDK;
    ...
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        _wikitudeSDK = new WikitudeSDK(this);
           ...

In the method provideRenderExtension which is defined by the InternalRendering interface we create an instance of our CustomRenderExtension and return it.

    @Override
    public RenderExtension provideRenderExtension() {
        _renderExtension = new CustomRenderExtension();
        return _renderExtension;
    }

The CustomRenderExtension was defined like in the following code snippet. All defined methods will be called in the appropriate methods of the WikitudeSDK renderer which extends the standard Android GLSurfaceView.Renderer.

public class CustomRenderExtension implements GLSurfaceView.Renderer, RenderExtension {

    private RecognizedTarget _currentlyRecognizedTarget = null;
    private StrokedRectangle _strokedRectangle;

    @Override
    public void onDrawFrame(final GL10 unused) {
        if (_currentlyRecognizedTarget != null) {
            _strokedRectangle.onDrawFrame(_currentlyRecognizedTarget);
        }
    }

    @Override
    public void onSurfaceCreated(final GL10 unused, final EGLConfig config) {
        _strokedRectangle = new StrokedRectangle();
    }

    @Override
    public void onSurfaceChanged(final GL10 unused, final int width, final int height) {
    }

    public void onResume() {
    }

    public void onPause() {
    }

    public void setCurrentlyRecognizedTarget(final RecognizedTarget currentlyRecognizedTarget_) {
        _currentlyRecognizedTarget = currentlyRecognizedTarget_;
    }

}