Hey guys,
I’m very new to Juce and I am trying to set up a simple OpenGL app that would run on Win/Linux/MacOSX/iOS/Android with the same code base.
Right now, I’m just trying to display a simple RGB triangle on the screen under every available platform.
So far, this app works well on MacOSX and Windows (RGB triangle is displayed correctly), but somehow it doesn’t work on iOS (it display a black screen with the Juce menu).
Questions :
- What the hell is wrong with my code ? I’ve tried many different approaches, let me know if I’m doing so bad practice or anything wrong …
- I’m using some #if for the OpenGL ES headers, I have the feeling that it is not the right thing to do, Juce is supposed to handle that, right ?
- I haven’t found any GL iOS sample for Juce, is there one somewhere ?
Cheers, here is the code :
#include "../JuceLibraryCode/JuceHeader.h"
#if JUCE_IOS
# include <OpenGLES/ES1/gl.h>
# include <OpenGLES/ES1/glext.h>
# include <OpenGLES/ES2/gl.h>
# include <OpenGLES/ES2/glext.h>
#endif
class Window;
class OpenGLCanvas;
class App;
class OpenGLCanvas : public Component, public OpenGLRenderer, public Timer, public ApplicationCommandTarget
{
public:
OpenGLCanvas(Window& window)
{
m_OpenGLContext.setRenderer(this);
m_OpenGLContext.setComponentPaintingEnabled (true);
m_OpenGLContext.attachTo(*getTopLevelComponent());
startTimer(1000 / 30);
}
~OpenGLCanvas()
{
m_OpenGLContext.detach();
}
void timerCallback()
{
}
void newOpenGLContextCreated()
{
}
virtual void renderOpenGL()
{
GLfloat vertices[] =
{
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0
};
GLfloat colors[] =
{
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0
};
OpenGLHelpers::clear(Colours::black);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(3, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
virtual void openGLContextClosing()
{
}
ApplicationCommandTarget* getNextCommandTarget()
{
// this will return the next parent component that is an ApplicationCommandTarget (in this
// case, there probably isn't one, but it's best to use this method in your own apps).
return findFirstTargetParentComponent();
}
void getAllCommands (Array <CommandID>& commands)
{
const CommandID ids[] =
{
MoveLeft,
MoveRight,
MoveUp,
MoveDown,
MoveFar,
MoveNear,
};
commands.addArray(ids, numElementsInArray(ids));
}
void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result)
{
const String general ("General" );
switch(commandID)
{
case MoveLeft:
result.setInfo("Camera Movement", "Move left", general, 0);
result.addDefaultKeypress (KeyPress::leftKey, ModifierKeys::noModifiers);
break;
case MoveRight:
result.setInfo("Camera Movement", "Move right", general, 0);
result.addDefaultKeypress (KeyPress::rightKey, ModifierKeys::noModifiers);
break;
case MoveUp:
result.setInfo("Camera Movement", "Move up", general, 0);
result.addDefaultKeypress (KeyPress::pageUpKey, ModifierKeys::noModifiers);
break;
case MoveDown:
result.setInfo("Camera Movement", "Move down", general, 0);
result.addDefaultKeypress (KeyPress::pageDownKey, ModifierKeys::noModifiers);
break;
case MoveFar:
result.setInfo("Camera Movement", "Move far", general, 0);
result.addDefaultKeypress (KeyPress::upKey, ModifierKeys::noModifiers);
break;
case MoveNear:
result.setInfo("Camera Movement", "Move near", general, 0);
result.addDefaultKeypress (KeyPress::downKey, ModifierKeys::noModifiers);
break;
default:
break;
};
}
bool perform(const InvocationInfo& info)
{
return true;
}
private:
OpenGLContext m_OpenGLContext;
enum CommandIDs
{
MoveLeft = 0x0001,
MoveRight = 0x0002,
MoveUp = 0x0003,
MoveDown = 0x0004,
MoveFar = 0x0005,
MoveNear = 0x0006,
};
};
class Window : public DocumentWindow
{
public:
Window()
: DocumentWindow("MyApp", Colours::grey, DocumentWindow::allButtons, true)
{
addKeyListener(m_CommandManager.getKeyMappings());
m_Canvas = new OpenGLCanvas(*this);
setContentComponent(m_Canvas);
// m_Canvas->setApplicationCommandManagerToWatch(&m_CommandManager);
m_CommandManager.registerAllCommandsForTarget(m_Canvas);
}
~Window()
{
}
void closeButtonPressed()
{
JUCEApplication::quit();
}
private:
ApplicationCommandManager m_CommandManager;
ScopedPointer<OpenGLCanvas> m_Canvas;
};
class App : public JUCEApplication
{
public:
App()
{
}
~App()
{
}
void initialise (const String& commandLine)
{
#if JUCE_IOS || JUCE_ANDROID
m_Window.setVisible (true);
m_Window.setFullScreen (true);
#else
m_Window.centreWithSize (800, 600);
m_Window.setVisible (true);
#endif
}
void shutdown()
{
}
void systemRequestedQuit()
{
quit();
}
const String getApplicationName()
{
return "MyApp";
}
const String getApplicationVersion()
{
return ProjectInfo::versionString;
}
bool moreThanOneInstanceAllowed()
{
return false;
}
void anotherInstanceStarted (const String& commandLine)
{
}
private:
Window m_Window;
};
START_JUCE_APPLICATION(App)