Posts RSS Comments RSS Del.icio.us Digg Technorati Blinklist Furl reddit 66 Posts and Comments till now
This wordpress theme is downloaded from wordpress themes website.

Archive for December, 2013 (2013/12)

Simple texture example

I loaded three simple bmp’s and blended them with a GLSL fragment shader:
out_Color = texture(sam0, ex_TexCoord)/3.0 + texture(sam1, ex_TexCoord)/3.0 + texture(sam2, ex_TexCoord)/3.0;

This was just to make sure I had a cross-platform texture example for SDL2 with OpenGL 4 (OpenGL ES 2 or 3) on (Windows, Linux, OS X, iOS, Android).  I loaded pixels from bmp file with this simple code ( http://stackoverflow.com/questions/12518111/how-to-load-a-bmp-on-glut-to-use-it-as-a-texture ).  SLD2 doesn’t include any image loading functionality; it’s FAQ ( http://wiki.libsdl.org/FAQDevelopment ) references SDL_image.  The uncompressed source code for SDL2_image-2.0.0 is 27.7 MB (31.3 MB on disk).  I may later integrate SDL2_image (or some other image loading library), but for now I am just using bmp’s.  Another option would be to use KTX file format (an official Khronos OpenGL & OpenGL ES texture file format) or DDS; this link ( http://stackoverflow.com/questions/18058669/ktx-vs-dds-images-in-opengl ) says NVIDIA OpenGL driver supports GPU acceleration for compressed textures with DDS but not for KTX (as of Aug 14 2013).  Or I could even write code that converts from BMP (etc) to a custom format file, and code that loads the texture from that custom format file.

image image

Another relevant texture issue is “texture atlas” and “array texture”.  This is relevant to the example of a thumbnail viewer, because the folder could contain an arbitrary number of image files (png bmp etc).

My AMD Radeon HD 6520G (HP laptop) has a GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value of 32 (checked on Windows 7).  According to gfxbench.com, the Asus Nexus 7 has a value of 16 for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS.  A naïve approach of using one texture unit per thumbnail would limit you to only one GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS thumbnails (loaded at a time).  To render more thumbnails (than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS), you would require state changes.

A more sane approach would be to fit all the thumbnails on one texture with a texture atlas, or to use hardware support for array textures.  My AMD Radeon HD 6520G (HP laptop) has a value of 8192 for GL_MAX_ARRAY_TEXTURE_LAYERS.  According to ( http://www.opengl.org/wiki/Array_Texture ), array textures (EXT_texture_array) was core since OpenGL 3.0.  OpenGL ES 3.0 lists array textures as a new feature.  Unfortunately, OpenGL ES 2.0 does not appear to support array textures, except as an extension – see ( http://stackoverflow.com/questions/16147700/opengl-es-using-tegra-specific-extensions-gl-ext-texture-array ).

Linux with modern OpenGL

I didn’t have a great experience finding modern OpenGL (3, 4) support in virtual machines such as VMware Player for guest Linux, and I didn’t want to bother with the hassle of dual-booting.  So I built a (good but not super high end) desktop computer from parts with a recent (but not high end PCIe) GPU .  I installed Ubuntu 12.04 LTS, installed updates (including “Additional Drivers” AMD proprietary) and got the C++ compilation to work for my cross-platform C++ OpenGL SDL2 based program.  Aside, NoMachine on my LAN works great for remote desktop from Windows to Linux with modern OpenGL.  To compile my source code, I needed a few small edits to the build file, and to fix some linker errors I had to install some libraries with “sudo apt-get install”.

Screenshot from 2013-12-21 01_53_38

So my cross-platform code setup with C++ OpenGL SDL2 upgraded to use modern OpenGL (OpenGL 3 & 4, OpenGL ES 2 & 3) style code now builds & runs on five platforms (Windows, OS X, Linux eg Ubuntu, Android, iOS).  Ideas for what I might do next are…  Further refactor / cleanup / streamline the code & build process.  Some less trivial but still simple graphics demos (eg lighting, textures, bump mapping, shadow mapping).  OpenGL-based GUI (eg expand the thumbnail viewer).  Add another platform (I think the most obvious choice is Windows Phone, which would possibly mean adding a DirectX code path for Windows & Windows Phone).

Grid view prototype (such as a for thumbnails)

Here’s an Android (DroitAtScreen) screen shot and a Windows screen shot for a quick prototype of a grid view (such as for a thumbnail viewer).  Cross-platform OpenGL C++ SDL2.  Uses orthographic projection (not perspective).  The camera in my previous post did not have an ortho mode, so I added one (this was easy because although the camera did not have ortho, GLM does).
image image

Here’s what the same program looks like with projective perspective:
image image image image

Ideas.  A texture on each thumbnail.  Resize thumbnails with pinch-to-zoom.  Logic to organize the boxes based on the thumbnail size and the near plane dimensions…  Keep thumbnails in view horizontally, scroll down to see vertically off-screen thumbnails.  Fill screen top-left to bottom-right.  Horizontal spacing between thumbnails could either be constant, or a range (used to fill the row).

Edit: SDL2 made it super-easy to add a prototype pinch-zoom (tested on Android).  For this example, “zoom” just means to walk forward (or backward):
case SDL_MULTIGESTURE:
{
    const float fZoomSpeed = 10.0f;
    g_Camera.offsetPosition(fZoomSpeed * event.mgesture.dDist * g_Camera.forward());
    break;
}
image image

Edit: I added resizing to allow any number of boxes and different widths.  This could be used with vertical-only scrolling
image image image

Edit: I added the ability (quick prototype) to dynamically resize the grid based on a change in window width – here it is with orthographic projection.  For ortho, I use:
xMin = -m_state->window_w / m_fScaleOrtho + m_HalfModelW + xGap;
xMax = m_state->window_w / m_fScaleOrtho – m_HalfModelW – xGap;
image image image image image image image

Camera integration

Summary

Basically what I did was just to integrate the camera from this tutorial/project (and GLM) into my cross-platform SDL2 OpenGL project.  This is also a good tutorial series to review basics (concepts, code) using modern OpenGL 3 & 4 style:

http://tomdalling.com/blog/modern-opengl/04-cameras-vectors-and-input/

http://glm.g-truc.net

Screen shots on Windows 7 shows… Window resize (notice the cubes are no longer stretched / distorted).  Keyboard controls to walk around (WASD, QE turn left/right):
image image image image

Here are screen shots on Android (Nexus 7, DroidAtScreen) in portrait and landscape modes:

image image

For Android screen rotation to work properly, I added this to AndroidManifest.xml –> <manifest> –> <application> –> <activity>:
android:configChanges=”keyboard|keyboardHidden|orientation|screenSize”

The WASD camera controls are time independent because I use use Simulate(Uint32 dt) as described in an earlier post:
const Uint8 *state = SDL_GetKeyboardState(NULL);
const float moveSpeed = 0.01f;
if (state[SDL_SCANCODE_W]) {
    g_Camera.offsetPosition(dt * moveSpeed * g_Camera.forward());
}

Once I got my code to work on Windows and Android, it also worked on OS X and iOS:
image image image

I haven’t tried this on Linux yet because I’m planning to build a separate desktop computer to build & test for Linux support (my experience with Ubuntu Linux on VMWare Player was that OpenGL 2 support worked but not OpenGL 4).

OpenGL 3+ & OpenGL ES 2.0+ style (with VAO’s)

I upgrade my project to a more modern style of OpenGL API calls.  Here’s a screen shot using OpenGL ES 2.0 with an extension to enable VAO’s (glBindVertexArrayOES, glDeleteVertexArraysOES, glGenVertexArraysOES, glIsVertexArrayOES) on my Nexus 7 (using DroidAtScreen).  And the same source code compiled to run on Windows 7, Mac OS X.  It draws a triangle and a cube using VBO’s, IBO’s, VAO’s (vertex buffer objects, index buffer objects, vertex array objects).

image_thumb[30] image image image

Although my OpenGL 2 version worked on Ubuntu Linux in VMware Player, I had some trouble getting my VMware Player to work with Ubuntu for OpenGL 3+.  I think this is due to lack of support by VMware.  I tried installing the latest Mesa release (Mesa 10.0), which implements OpenGL 3.3 API.  I thought maybe the Mesa software rendering mode would work for OpenGL 3.3.  My VMware Ubuntu install glxinfo still reports only support for OpenGL 2.0.  However, I don’t think that’s the case.  Mesa3d.org doc says:

http://www.mesa3d.org/relnotes/10.0.html
> Mesa 10.0 implements the OpenGL 3.3 API, but the version reported by glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) / glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used. Some drivers don’t support all the features required in OpenGL 3.3. OpenGL 3.3 is only available if requested at context creation because compatibility contexts are not supported.

Virtual Machines have a history of limited support for OpenGL & DirectX, especially on a Linux guest.  Windows Remote Desktop was also unable to support hello world OpenGL 3+ (although VNC might work).

Part of the educational value (and fun) of this project is to get some exposure to software development on other platforms (via cross-platform software development), so I’d like my little SDL2 OpenGL project to at least run on (Windows 7+, Mac OS X, Linux Ubuntu, iOS, Android).  So I might try dual-booting, or even just buying a separate cheap computer to run Ubuntu Linux with OpenGL 4.x.

First I ported my OpenGL 2 style code to OpenGL 3+ (4) style and got the Windows version to work, then the Mac OS X version.  Then I tried it on Linux (and ran into the VMware issue).  Then I got it to work on Android, which required some hacking.  Build uses API Level 18.  Use SDL_RWFromFile() to read vertex & fragment shaders from Android assets.  Use a separate GLSL vertex & fragment shader for Windows (in, out) vs. Android (attribute, varying).  Then I got it to work on iOS, which did not require much additional hacking.  Like on Android, for iOS I had to add my shaders folder (GLSL text files) via Project -> Build Phases -> Copy Bundle Resources –> add “shaders” folder.

Edit 2013/12/14: a couple notes on my setup.  I’m going to put together a Linux (Ubuntu) computer rather than rely on VMWare.  I also found that although Microsoft Remote Desktop does not support newer versions of OpenGL, I found that NoMachine (NX) does (I tried Windows to Windows).

Platforms, platform versions, API versions, supported features, OpenGL ES 2.0 & 3.0

Background – SDL2, C++, Graphics API’s, Platforms, Devices

libsdl.org says: Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D. It is used by video playback software, emulators, and popular games…

SDL2 can help with cross-platform development using OpenGL (OpenGL ES, DirectX), such as setting up a cross-platform context, and it’s one path to enable you to share C++ code across the multiple platforms.  I started from the sample project, which gives you a build setup with wrappers for each platform.  For Android, I’m not writing OpenGL ES directly in Java JDK – rather the JDK calls to my cross-platform C++ code that is compiled with Android NDK.  Similarly, my iOS project shares the same C++ code base (ie compile source as Objective-C++ instead of as Objective-C).

Since Dec 2005 I’ve worked on a GPU model simulation.  From the perspective of writing GPU models, the GPU API’s (OpenGL, OpenGL ES, DirectX) may seem high level.  But from the perspective of applications software (or middleware), using these APIs is the lowest layer you’d write.  Anything lower and you’d be writing the API’s or the associated GPU drivers.  Also, starting from scratch (or near scratch) is different than modifying an existing code base.

So my SDL2 setup is not comparable to using middleware or a game engine (in terms of the layers, it’s closer to writing one).  SDL2 just makes it a little easier to setup a cross-platform C++ code base that accesses the low level API’s (OpenGL, OpenGL ES, DirectX) to run on multiple operating systems (Windows, Linux Ubuntu, Mac OS X, Android, iOS, etc).

Even if you only develop GPU software for one operating system, you have to face the issue of API versions and GPU hardware features (supported by GPU & its driver).  For example, on Windows you might decide to use only DirectX 11, and only worry about Windows 7+ with GPU’s that support DirectX 11.

Android API versions & device support

Or on Android, you might decide to use OpenGL ES 3.0, or OpenGL ES 2.0 and check extensions for newer features (such as VAO).  On Android, you’d also have to decide what Android API level (which correlates to support on Android Platform versions).  Of course you could have multiple builds (and corresponding code paths with #ifdef’s) for more than one Android API level – for example, have a newer code base with some fall-back support for old Android platforms.

http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels
image

And here’s a screenshot form Android Eclipse –> Window –> Android SDK Manager.  Notice how it says “Android 4.4 (API 19)”.  Also notice Kindle Fire HDX is listed under “Android 4.2.2 (API 17)”.
image

My current plan (for my small hobby project of simple graphics demos) is to support multiple platforms (Android, iOS, Windows, Linux, Mac OS X), but only support reasonably new versions of each platform (such as Android 4.4 with OpenGL ES 2.0 or 3.0).  I especially don’t want to waste a lot of time on any really old API’s such as fixed function pipeline style OpenGL ES 1.1 or OpenGL 2.x.  It’s worth mention that the older deprecated stuff gets older and more deprecated as each day passes.

The cross-platform hello world cube in my previous post started from the SDL2 (2.0.0) testgl2.cpp and testgles.cpp examples.  It was at least using glDrawElements() / glDrawArrays() instead of intermediate mode glBegin() / glEnd().  However, it was still using old fixed function code like glMatrixMode(GL_MODELVIEW), which is deprecated in OpenGL 3.0, and removed from OpenGL ES 2.0.  I’m planning to at least upgrade my project to exclusively use reasonably new API’s such as OpenGL shaders instead of fixed function.  I’ll probably use OpenGL ES 2.0 with extensions (such as for VAO’s) or OpenGL ES 3.0 (Android, iOS), OpenGL 3.x or 4.x (Windows, Linux, OS X), and later I might add a DirectX 11 path too (for Windows and Windows Phone).

I found more info on Android OpenGL ES version support here:
http://developer.android.com/guide/topics/graphics/opengl.html
image
So OpenGL ES 3.0 requires at least Android 4.3 (API level 18), and a device that supports OpenGL ES 3.0.

Here’s an Android chart that claims 96.3% of devices (as of Dec 2, 2013) support OpenGL ES 2.0, and only 3.6% support OpenGL ES 3.0:
http://developer.android.com/about/dashboards/index.html#OpenGL
image

0.1% distribution suggests that a fallback path to OpenGL ES 1.1 is not useful for Android (to put it lightly), while OpenGL ES 2.0 is dominant.  However, maybe in 2 to 5, OpenGL ES 3.0 support will be above 90%.

Kindle HDX uses API Level 17 & OpenGL ES 2.0

Amazon Kindle uses a fork of Android called Fire OS which uses API Level 17.  OpenGL ES 3.0 requires Android API level 18 (Android 4.3) or higher, so if I want to support Kindle Fire HDX then I shouldn’t use anything newer than API Level 17 and OpenGL ES 2.0.  Probably there are other Android devices also very recently released that do not yet support OpenGL ES 3.0.

https://developer.amazon.com/sdk/fire/emulator-manual-settings.html
image
https://developer.amazon.com/sdk/fire/submit-android-app.html
image

OpenGL ES versioning (Apple iOS, wikipedia)

So with SDL2, you still get to deal with all the “fun” of versioning.  For example, the following Apple iOS page lists a small number of devices with support for different versions of OpenGL ES (versions 1.1, 2.0, 3.0):

https://developer.apple.com/library/ios/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/OpenGLESPlatforms/OpenGLESPlatforms.html
image

As of 2013/12, this list goes back to iPod touch 3G (September 9, 2009).  Every Apple iOS device here is listed as supporting OpenGL ES 1.1, 2.0.  But only the latest are listed as supporting OpenGL ES 3.0 – iPhone 5s, iPad Air, iPad Mini Retina.  iPod touch 5G does not support OpenGL ES 3.0.  So unless I want to only support the newest devices (which might be fine since this project is just for fun & learning), then I should not exclusively use OpenGL ES 3.0.  However, anything older than Sep 2009 is very old (that’s 4 years 3 months).  Also, as described on wikipedia, OpenGL ES 2.0 requires programmable pipeline (good):

> OpenGL ES 2.0 was publicly released in March 2007.[2] It is based roughly on OpenGL 2.0, but it eliminates most of the fixed-function rendering pipeline in favor of a programmable one in a move similar to transition from OpenGL 3.0 to 3.1.[3] Control flow in shaders is generally limited to forward branching and to loops where the maximum number of iterations can easily be determined at compile time.[4] Almost all rendering features of the transform and lighting stage, such as the specification of materials and light parameters formerly specified by the fixed-function API, are replaced by shaders written by the graphics programmer. As a result, OpenGL ES 2.0 is not backward compatible with OpenGL ES 1.1. Some incompatibilities between the desktop version of OpenGL and OpenGL ES 2.0 persisted until OpenGL 4.1, which added the GL_ARB_ES2_compatibility extension.[5]

Here’s what wikipedia says about OpenGL ES 3.0:

> The OpenGL ES 3.0 specification[6] was publicly released in August 2012.[7] OpenGL ES 3.0 is backwards compatible with OpenGL ES 2.0, enabling applications to incrementally add new visual features to applications. OpenGL 4.3 provides full compatibility with OpenGL ES 3.0.

So the iOS scene is similar to the Android scene.  OpenGL ES 2.0 is the primary version supported, but OpenGL ES 3.0 is the future (and exists today on a small subset of devices).

OpenGL ES 2.0 or 3.0 or both?

For my project, I can use OpenGL ES 2.0 or 3.0 or both (aka 3.0 with a 2.0 fall-back path).  If I use OpenGL ES 2.0, I can still use extensions to detect additional features such as GL_OES_vertex_array_object for Vertex Array Object support.  If I want to develop for the present, 2.0 is the obvious choice.  If I want to develop for the future I could move completely to 3.0.