Work interruptions are evil

I can be doing something very important but if I get distracted for a little bit when I go back I totally forget what I was doing. Here is what happened today.

I wanted to code some new stuff and was about to add the line:

if ( !Node ) { return clPtr<clSceneNode>(); }

just before this line:

if ( !Node->LoadFromStream( Stream ) ) { return clPtr<clSceneNode>(); }

Suddenly I heard a phone ringing, got up from my computer, and left the code incomplete:

if ( !Node )
if ( !Node->LoadFromStream( Stream ) ) { return clPtr<clSceneNode>(); }

After the phone call I decided to drink some tee… I completely forgot what I was doing.
Long story short, when I returned to my coding I spent 30 minutes figuring out why my program was broken and what the heck was going on :(

Accessing Linux from Windows via sshd

I have a Virtual Box virtual machine and an Ubuntu installation running within it. Most of the time a do my development on Windows using Far Manager as my primary shell and text editor.

There is a nice plugin for it, called NetBox: http://plugring.farmanager.com/plugin.php?pid=859 (https://github.com/michaellukashov/Far-NetBox/downloads/),
which allows me to connect to a Linux machine via sshd and access its files as if they were on my local file system.

Here is a step-by-step checklist to make your Virtual Box sshd-enabled:

1. Run sudo apt-get install openssh-server
2. Run ifconfig and remember the IP-address on your virtual machine behind a NAT
3. Go to the Network settings menu: SettingsNetworkPort ForwardingInsert new rule and type:

Rule1 TCP 22 22

Reboot your VM. Now it is ready to accept sshd connections.

There are a few more steps to make your Far Manager to access the VM:

4. Unpack a NetBox distro to the plugins folder (for example, C:\Program Files (x86)\Far2\Plugins) and restart Far Manager
5. Press Alt-F1, select NetBox, press Shift+F4
6. Select the connection type: SCP. Enter the host IP-address and logic/password for your Ubuntu

This plugin allows not only accessing files but run the shell commands from Far.

Omnidirectional shadows and VSDCT on OpenGL ES 3

Recently we have ported all the parts of our shading pipeline to OpenGL ES 3. The last piece of the puzzle was a decent implementation of omnidirectional shadow maps. We used a Virtual Shadow Depth Cube Texture (VSDCT) described in ShaderX3.

Here is a simple code snipped I wrote to convert cube map vec3 into a virtual texture vec2:

vec2 GetShadowTC( vec3 Dir )
{
	float Sc;
	float Tc;
	float Ma;
	float FaceIndex;

	float rx = Dir.x;
	float ry = Dir.y;
	float rz = Dir.z;

	vec3 adir = abs(Dir);
	Ma = max( max( adir.x, adir.y ), adir.z );

	if ( adir.x > adir.y && adir.x > adir.z )
	{
		Sc = ( rx > 0.0 ) ? rz : -rz;
		Tc = ry;
		FaceIndex = ( rx > 0.0 ) ? 0.0 : 1.0;
	}
	else if ( adir.y > adir.x && adir.y > adir.z )
	{
		Sc = rx;
		Tc = ( ry > 0.0 ) ? rz : -rz;
		FaceIndex = ( ry > 0.0 ) ? 2.0 : 3.0;
	}
	else
	{
		Sc = ( rz > 0.0 ) ? -rx : rx;
		Tc = ry;
		FaceIndex = ( rz > 0.0 ) ? 4.0 : 5.0;
	}

	float s = 0.5 * ( Sc / Ma + 1.0 );
	float t = 0.5 * ( Tc / Ma + 1.0 );

	s = s / 3.0;
	t = t / 2.0;

	float Flr = floor(FaceIndex / 3.0);
	float Rmd = FaceIndex - (3.0 * Flr);

	s += Rmd / 3.0;
	t += Flr / 2.0;

	return vec2( s, t );
}

The distance from the light source is packed into a 8-bit RGBA texture using this trick. Everything else is pretty straightforward.

Android demo (requires OpenGL ES 3).

Embedding precompiled .APK into Android ROM

There a lot of tutorials out there on how to build your own Android ROM from sources and how to integrate your application into the build process. However, there are very few clean instructions on how to put your own precompiled .apk into the ROM. Here is how (I assume you have an Android working tree ready):

  1. Create a folder for your app: packages/apps/<your-app-name>
  2. Put your .apk into the packages/apps/<your-app-name>/<your-app-name>.apk
  3. Create the Android.mk file just next to it. Is should contain:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := <your-app-name>;
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)

Now Android build system will recognize the package with your application. To include it into the ROM add <your-app-name> to the PRODUCT_PACKAGES variable for a desired target configuration. I.e. in build/target/product/full_base.mk.

Build the ROM as usual and you will have your precompiled application embedded into it.

If you have native C++ library inside your .apk, you should unpack it manually, put into the packages/apps/<your-app-name> folder and describe it in Android.mk:

include $(CLEAR_VARS)
LOCAL_IS_HOST_MODULE:=
LOCAL_MODULE_CLASS:=SHARED_LIBRARIES
LOCAL_MODULE_TAGS:=optional
OVERRIDE_BUILT_MODULE_PATH:=$(PRODUCT_OUT)/obj/lib
LOCAL_UNINSTALLABLE_MODULE:=
LOCAL_SRC_FILES:=<your-library.so>
LOCAL_BUILT_MODULE_STEM:=<your-library.so>
LOCAL_STRIP_MODULE:=
LOCAL_MODULE:=<your-library>
LOCAL_MODULE_STEM:=<your-library.so>
LOCAL_CERTIFICATE:=
LOCAL_MODULE_PATH:=$(PRODUCT_OUT)/system/lib
LOCAL_REQUIRED_MODULES:=
LOCAL_SHARED_LIBRARIES:=
include $(BUILD_PREBUILT)

Add it as a dependency to your prebuilt .apk package:

LOCAL_REQUIRED_MODULES := <your-library>

The library will be copied to the system/lib folder of the target ROM.

BlackBerry 10 Native SDK command-line tools

I did some BlackBerry 10 development this year and found its native C/C++ development environment very friendly. However, Momentics IDE is nice but I was looking for a clean command-line environment to automate my daily builds and tests. It came out, the Native SDK comes with a full set of Windows-based tools required to do it, which reside in the host_…\win32\x86\usr\bin\ folder.

To make a .bar package:

blackberry-nativepackager -devMode -package <name.bar> bar-descriptor.xml

To install .bar on your device or emulator:

blackberry-deploy -installApp -launchApp -device <device_ip> <name.bar>

To bring a log file back to your PC from the device:

blackberry-deploy -getfile logs/log FileOnPC.txt -device <device_ip> <name.bar>

-devMode is required to let others access the “logs/log“ file (and other temp files).

P.S. Official documentation: https://developer.blackberry.com/native/documentation/core/com.qnx.doc.native_sdk.devguide/com.qnx.doc.native_sdk.devguide/topic/c_understanddevenv_use_commandline.html

Vertex Array Object (VAO) on Android

Always wanted to put my hands on an OpenGL ES 3 Android device. Here are the results of testing VAO on Google Nexus 10 (Android 4.3 with OpenGL ES 3) and Samsung Galaxy Nexus (Android 4.3 with OpenGL ES 2 and OES_vertex_array_object extension).

1. First, the old Samsung Galaxy Nexus. 
The extensions list claims the OES_vertex_array_object extension is supported. So, I load the entry points:

#define BIND_EXT( VarName, Type, Bind1, Bind2 )\
        VarName = (Type)GetGLProc( API, Bind1 );\
        if ( !VarName ) VarName = (Type)GetGLProc( API, Bind2 );
BIND_EXT( API->glBindVertexArray,
          PFNGLBINDVERTEXARRAYPROC,
          "glBindVertexArray", "glBindVertexArrayOES" );
BIND_EXT( API->glDeleteVertexArrays,
          PFNGLDELETEVERTEXARRAYSPROC,
          "glDeleteVertexArrays", "glDeleteVertexArraysOES" );
BIND_EXT( API->glGenVertexArrays,
          PFNGLGENVERTEXARRAYSPROC,
          "glGenVertexArrays", "glGenVertexArraysOES" );

Just in case, I check for the presence of actual functions.

bool IsVAOSupported = API->glBindVertexArray &&
                      API->glDeleteVertexArrays &&
                      API->glGenVertexArrays;

It looks fine, so we start rendering using VAO in hope everything will go as expected. Nope, it doesn’t:

E/libEGL: called unimplemented OpenGL ES API.

Pfff, stop saying “Yes, we support VAO!”.

2. Here goes the Google Nexus 10 (with an awesome 2560×1600 10-inch touchscreen).

I/LEngine: OpenGL version   : OpenGL ES 3.0
I/LEngine: OpenGL vendor    : ARM
I/LEngine: OpenGL renderer  : Mali-T604
I/LEngine: GLSL version     : OpenGL ES GLSL ES 3.00

VAO just works using the same code path, which is used on a desktop OpenGL 3.2.