Skip to content

Instantly share code, notes, and snippets.

@holocronweaver
Last active August 29, 2015 14:26
Show Gist options
  • Save holocronweaver/3371c0474853e76115a8 to your computer and use it in GitHub Desktop.
Save holocronweaver/3371c0474853e76115a8 to your computer and use it in GitHub Desktop.
Slightly modified OgreJNI app for Android meant to show a triangle. Instead shows nothing!

This is a bare modification of the OgreJNI example to render a white triangle at the origin of the scene. Using the latest default branch of OGRE (2015-08-01), only a blue background appears on my Nexus 5 (Android 5.1.1, Adreno 330, GLES3 support enabled), HP Slate S7-4400US (Android 4.4.2, Tegra 4, GLES2.0 only), and Nexus 4 (Android 5.1.1, Adreno 320, GLES2.0 only).

I also tried adding OGRE standard entities (Ogre head, penguin, etc.) and adding the RTSS, but still just a blue background. I removed those attempts from this demo to keep things simple.

The original build was on Linux using android-ndk-r10e, android-sdk-r24.3.3, and targeting API level 19 for armeabi.

Build Instructions

  1. Add the material and shaders to the OgreJNI/assets folder.
  2. Overwrite the OgreActivityJNI.cpp in the OgreJNI/jni folder.
  3. Either build as usual or use the build.sh script while inside the OgreJNI folder.
#! /usr/bin/env sh
ndk-build
# Should only be required to initialize project.
#android update project --name OgreJNI --path . --target "android-19" --subprojects
ant clean
ant debug
adb install -r bin/OgreJNI-debug.apk
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2012 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include <jni.h>
#include <EGL/egl.h>
#include <android_native_app_glue.h>
#include <android/api-level.h>
#include <android/native_window_jni.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include "OgrePlatform.h"
#include "OgreRoot.h"
#include "OgreRenderWindow.h"
#include "OgreArchiveManager.h"
#include "OgreViewport.h"
#include "OgreCamera.h"
#include "OgreManualObject.h"
#include "OgreSceneNode.h"
#include "Android/OgreAndroidEGLWindow.h"
#include "Android/OgreAPKFileSystemArchive.h"
#include "Android/OgreAPKZipArchive.h"
#ifdef OGRE_BUILD_PLUGIN_OCTREE
# include "OgreOctreePlugin.h"
#endif
#ifdef OGRE_BUILD_PLUGIN_PFX
# include "OgreParticleFXPlugin.h"
#endif
#ifdef OGRE_BUILD_COMPONENT_OVERLAY
# include "OgreOverlaySystem.h"
#endif
#include "OgreConfigFile.h"
#ifdef OGRE_BUILD_RENDERSYSTEM_GLES2
# include "OgreGLES2Plugin.h"
# define GLESRS GLES2Plugin
#else
# include "OgreGLESPlugin.h"
# define GLESRS GLESPlugin
#endif
using namespace Ogre;
namespace {
bool gInit = false;
Ogre::Root* gRoot = NULL;
Ogre::RenderWindow* gRenderWnd = NULL;
#ifdef OGRE_BUILD_PLUGIN_OCTREE
Ogre::OctreePlugin* gOctreePlugin = NULL;
#endif
#ifdef OGRE_BUILD_PLUGIN_PFX
Ogre::ParticleFXPlugin* gParticleFXPlugin = NULL;
#endif
#ifdef OGRE_BUILD_COMPONENT_OVERLAY
Ogre::OverlaySystem* gOverlaySystem = NULL;
#endif
Ogre::GLESRS* gGLESPlugin = NULL;
Ogre::SceneManager* pSceneMgr = NULL;
Ogre::Camera* pCamera = NULL;
Ogre::LogManager* mLog = NULL;
JavaVM* gVM = NULL;
AAssetManager* mAssetMgr = NULL;
}
// enable JNI calling conventions for functions defined here
extern "C"
{
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved);
JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_create(JNIEnv * env, jobject obj, jobject assetManager);
JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_destroy(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_initWindow(JNIEnv * env, jobject obj, jobject surface);
JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_termWindow(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_renderOneFrame(JNIEnv * env, jobject obj);
}
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
gVM = vm;
return JNI_VERSION_1_4;
}
void Java_org_ogre3d_android_OgreActivityJNI_create(JNIEnv * env, jobject obj, jobject assetManager)
{
if(gInit)
return;
gRoot = new Ogre::Root();
mLog = new Ogre::LogManager();
mLog->createLog("/sdcard/ogre.log");
gGLESPlugin = OGRE_NEW GLESRS();
gRoot->installPlugin(gGLESPlugin);
#ifdef OGRE_BUILD_PLUGIN_OCTREE
gOctreePlugin = OGRE_NEW OctreePlugin();
gRoot->installPlugin(gOctreePlugin);
#endif
#ifdef OGRE_BUILD_PLUGIN_PFX
gParticleFXPlugin = OGRE_NEW ParticleFXPlugin();
gRoot->installPlugin(gParticleFXPlugin);
#endif
#ifdef OGRE_BUILD_COMPONENT_OVERLAY
gOverlaySystem = OGRE_NEW OverlaySystem();
#endif
gRoot->setRenderSystem(gRoot->getAvailableRenderers().at(0));
gRoot->initialise(false);
gInit = true;
mAssetMgr = AAssetManager_fromJava(env, assetManager);
if (mAssetMgr)
{
ArchiveManager::getSingleton().addArchiveFactory( new APKFileSystemArchiveFactory(mAssetMgr) );
ArchiveManager::getSingleton().addArchiveFactory( new APKZipArchiveFactory(mAssetMgr) );
}
}
void Java_org_ogre3d_android_OgreActivityJNI_destroy(JNIEnv * env, jobject obj)
{
if(!gInit)
return;
gInit = false;
#ifdef OGRE_BUILD_COMPONENT_OVERLAY
OGRE_DELETE gOverlaySystem;
gOverlaySystem = NULL;
#endif
OGRE_DELETE gRoot;
gRoot = NULL;
gRenderWnd = NULL;
#ifdef OGRE_BUILD_PLUGIN_PFX
OGRE_DELETE gParticleFXPlugin;
gParticleFXPlugin = NULL;
#endif
#ifdef OGRE_BUILD_PLUGIN_OCTREE
OGRE_DELETE gOctreePlugin;
gOctreePlugin = NULL;
#endif
OGRE_DELETE gGLESPlugin;
gGLESPlugin = NULL;
}
Ogre::DataStreamPtr openAPKFile(const Ogre::String& fileName)
{
Ogre::DataStreamPtr stream;
AAsset* asset = AAssetManager_open(mAssetMgr, fileName.c_str(), AASSET_MODE_BUFFER);
if (asset)
{
off_t length = AAsset_getLength(asset);
void* membuf = OGRE_MALLOC(length, Ogre::MEMCATEGORY_GENERAL);
memcpy(membuf, AAsset_getBuffer(asset), length);
AAsset_close(asset);
stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(membuf, length, true, true));
}
return stream;
}
void Java_org_ogre3d_android_OgreActivityJNI_initWindow(JNIEnv * env, jobject obj, jobject surface)
{
if (!surface) {
return;
}
ANativeWindow* nativeWnd = ANativeWindow_fromSurface(env, surface);
if (!nativeWnd || !gRoot) {
return;
}
if (!gRenderWnd) {
Ogre::NameValuePairList opt;
opt["externalWindowHandle"] = Ogre::StringConverter::toString(reinterpret_cast<size_t>(nativeWnd));
gRenderWnd = Ogre::Root::getSingleton().createRenderWindow("OgreWindow", 0, 0, false, &opt);
if (!pSceneMgr) {
pSceneMgr = gRoot->createSceneManager(Ogre::ST_GENERIC);
pCamera = pSceneMgr->createCamera("MyCam");
Ogre::Viewport* vp = gRenderWnd->addViewport(pCamera);
vp->setBackgroundColour(Ogre::ColourValue(0,0,1));
Ogre::ConfigFile cf;
cf.load(openAPKFile("resources.cfg"));
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
Ogre::String sec, type, arch;
// Go through all specified resource groups.
while (seci.hasMoreElements())
{
sec = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
// Go through all resource paths.
for (i = settings->begin(); i != settings->end(); i++)
{
type = i->first;
arch = i->second;
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch, type, sec);
}
}
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets();
Ogre::Root::getSingleton().clearEventTimes();
Ogre::SceneNode* rootNode = pSceneMgr->getRootSceneNode();
pSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
Ogre::Light* l = pSceneMgr->createLight("MainLight");
l->setPosition((Ogre::Real)20.0, (Ogre::Real)80.0, (Ogre::Real)50.0);
pCamera->setPosition(0, 0, 80);
pCamera->lookAt(0, 0, -3);
pCamera->setNearClipDistance(2); // default 100
pCamera->setFarClipDistance(10000); // default 10000
pCamera->setAspectRatio(
Ogre::Real(vp->getActualWidth()
/ Ogre::Real(vp->getActualHeight())));
// White triangle for debugging.
Ogre::ManualObject* manObj = new Ogre::ManualObject("triangle");
manObj->setDynamic(false);
// manObj->begin("BaseWhiteNoLighting",
manObj->begin("White",
Ogre::RenderOperation::OT_TRIANGLE_LIST);
{
manObj->position(0, 1, 0);
manObj->position(0, 0, 1);
manObj->position(1, 0, 0);
manObj->position(1, 0, 0);
manObj->position(0, 0, 1);
manObj->position(0, 1, 0);
}
manObj->end();
Ogre::SceneNode* manObjNode = rootNode->createChildSceneNode();
manObjNode->setPosition(0, 0, 0);
manObjNode->scale(Ogre::Vector3(5));
manObjNode->attachObject(manObj);
}
} else {
static_cast<Ogre::AndroidEGLWindow*>(gRenderWnd)->_createInternalResources(nativeWnd, NULL);
}
}
void Java_org_ogre3d_android_OgreActivityJNI_termWindow(JNIEnv * env, jobject obj)
{
if(gRoot && gRenderWnd)
{
static_cast<Ogre::AndroidEGLWindow*>(gRenderWnd)->_destroyInternalResources();
}
}
void Java_org_ogre3d_android_OgreActivityJNI_renderOneFrame(JNIEnv * env, jobject obj)
{
if(gRenderWnd && gRenderWnd->isActive())
{
if(gVM->AttachCurrentThread(&env, NULL) < 0)
return;
gRenderWnd->windowMovedOrResized();
gRoot->renderOneFrame();
// gVM->DetachCurrentThread();
}
}
material White
{
technique
{
pass
{
polygon_mode wireframe
vertex_program White/WhiteVS glsles
{
source WhiteVS.glsl
syntax glsles
param_named_auto wvp worldviewproj_matrix
}
fragment_program White/WhiteFS glsles
{
source WhiteFS.glsl
syntax glsles
}
}
}
}
#version 100
precision highp int;
precision highp float;
void main()
{
gl_FragColor = vec4(1.0);
}
#version 100
precision highp int;
precision highp float;
uniform mat4 wvp;
attribute vec4 position;
void main()
{
gl_Position = wvp * position;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment