Building with Marmalade SDK

Hi all! Please help me to run cocos2d-1.0.1-x-0.13.0-beta with latest Marmalade SDK (6.1.1).
I build the HelloWorld project using X-Code 4.4.1.

Got assertion failure in emulator:

15/10/12 19:49:21.609: [0xfa0] DEBUG: s3eDebugAssertShow 0x00000000 type=2 'IwAssert failure (S3E, 1694).
Message: Unavailable GLES function called

Assertion failure occurs in CCGL.cpp:

void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
{   
    GLfloat xmin, xmax, ymin, ymax;

    ymax = zNear * (GLfloat)tanf(fovy * (float)M_PI / 360);
    ymin = -ymax;
    xmin = ymin * aspect;
    xmax = ymax * aspect;



    glFrustumf(xmin, xmax,    <---------- ASSERTION HERE
        ymin, ymax,
        zNear, zFar);   
}

It’s called from CCDirector.cpp: CCDirectior::setProjection():

    case kCCDirectorProjection3D:       
        if (m_pobOpenGLView) 
        {
            m_pobOpenGLView->setViewPortInPoints(0, 0, size.width, size.height);
        }
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        // accommodate iPad retina while keep backward compatibility
        if (m_pobOpenGLView && m_pobOpenGLView->isIpad() && m_pobOpenGLView->getMainScreenScale() > 1.0)
        {
            gluPerspective(60, (GLfloat)size.width/size.height, zeye-size.height/2, zeye+size.height/2);    
        }
        else
        {
            gluPerspective(60, (GLfloat)size.width/size.height, 0.5f, 1500.0f);   /////////    CALLED FROM HERE
        }               

        glMatrixMode(GL_MODELVIEW); 
        glLoadIdentity();
        gluLookAt( size.width/2, size.height/2, zeye,
                 size.width/2, size.height/2, 0,
                 0.0f, 1.0f, 0.0f);             
        break;

Maybe this is ATI-videocard related. Marmalade had problems with ATI videocards before which were at least partially fixed (at least their OpenGL samples work).

I have ATI Radeon HD 6870.

Got cocos2d-x working on Windows 7 virtual machine / VS2010 / Marmalade 6.1.1, but had to change OpenGL driver from PowerVR to Qualcomm one in emulator.

Please help me to get it running on MacOS. Any suggestions are welcome.
Thank you very much!

Hi Andrey.

Since Marmalade 6.1 version in order to use OpengGL ES 1.x ( which is the version cocos2d-1.0.1-x-0.13.0-beta uses )
you have to put:

[S3E]
SysGlesVersion = 1

In yor app.icf file. I hope it helps!

Cheers!

It works! Thanks! :slight_smile:

Correct… from Marmalade 6.1, the default is to run using OpenGL ES 2.0. So to run using OpenGL ES 1.1 drivers, you need the setting as described above.

On desktop Windows, Marmalade now uses the Google ANGLE drivers (OpenGL ES 2.0 implementation on top of Direct3D) in order to get much more consistent performance across PC graphics cards. That’s one of the reasons why Marmalade now claims full commercial support for deploying games to Windows (Steam, etc).

Marmalade is currently adding support into Cocos2d-x 2.x and hopes to submit that to the project very soon.

Tom
It sounds like Marmalade will officially start supporting cocos2dx. If that is the case then I will abandon my branch that was adding marmalade support.

Regards
Francis

@Tim Closs, on windows desktop we can still use OpenGL. The headache is win8 metro, wp8, which uses dx11. How do you think about these? ANGLE project can’t support dx10 and higher so far.

We used to have our Windows support based on OpenGL. But more recently we realised that the only way to get really good cross-PC graphics support is to use DirectX. So from Marmalade 6.1, we use the ANGLE drivers as the back-end for the Marmalade desktop Windows support. That’s why Google adopted ANGLE (from TransGaming)… because they saw it as the only way to get really good cross-PC support for OpenGL ES 2.0 (required by them for WebGL and NaCl).

In terms of the Windows 8 platform family, you are right they currently use DirectX 11, and ANGLE is built on DirectX 9. Marmalade si developing its own solution allowing OpenGL ES 2.0 to run on DirectX 11, and we will use this as the basis of our graphics support on the Windows 8 family.

Thank you Tim, good suggestion!

Hi Tim,

Any idea about which version of Marmalade will come with the latest version of cocos2d-x integrated?
Maybe 6.2?

Thank you.

We are not currently planning to actually redistribute Cocos2d-x within the Marmalade SDK installer. But hopefully the Cocos2d-x packages will soon include full Marmalade platform support (proj.marmalade folders, etc).

Our current tests show that these work with any recent version of Marmalade SDK.

We are currently making our GitHub pull requests to the project, and working with the Cocos2d-x engineers to try to get this into the end-October release of Cocos2d-x.

Thanks Tim for the clarification :slight_smile:

Cheers!

Hi Tim,

New verion of Cocos2d-X has been released ( 2.0.4 ) but there aren’t any proj.marmalade folders!
Do have any estimations about when Cocos2d-X 2.0.x will have Marmalade integrated?
Could you tell me if there are any GitHub branch I could get the code from?

Cheers!

Marmalade support missed 2.0.4 I’m afraid. Until it makes it into the main distro you can use this branch at https://github.com/mrmop/cocos2d-x

Hi Matt,

Thank you for the github link! I’ll give it a try.

Cheers!

Hi Matt,

I’m running my Marmalade project with the code which is in the branch! everything is working so far but
I’m having problems trying to put my iPhone in landscape retina mode. even using the flag

[s3e]
IOSDispScaleFactor = 200
DispFixRot = Landscape

Do you know how to do it?

Thanks!

PS: I’m using Marmalade v6.1.2

Hi Matt,

Finally I’ve got it!

You have to rotate the projection matrix depending on the device orientation.
You get the number of times you have to rotate 90º calling this method:

IwGLGetInt( IW_GL_ROTATE );

So if you have your device in landscape mode you get 1 as a result. So you
will have to rotate 90º your projection matrix.
Creating a 2d projection I have added this code:

case kCCDirectorProjection2D:{
@ kmGLMatrixMode(KM_GL_PROJECTION);
@ kmGLLoadIdentity();
@ kmGLRotatef( –90, 0, 0, 1 ); // New code: rotate to achieve landscape orientation
@ kmMat4 orthoMatrix;
@ kmMat4OrthographicProjection(&orthoMatrix, 0, size.width, 0, size.height, –1024, 1024 );
@ kmGLMultMatrix(&orthoMatrix);
@ kmGLMatrixMode(KM_GL_MODELVIEW);
@ kmGLLoadIdentity();
} break;

My app.icf file:

[s3e]
IOSDispScaleFactor = 200
DispFixRot = FixedLandscape

So to have it working I think you have to modify the CCEGLView interface in order to get the
number of degrees to rotate the projection matrix.

I hope this post helps someone.

Cheers!

Hey, Óscar García
I think we should not use kmGLRotatef to make your game into Landscape mode, it’s not really Landscape mode since it’s implemented by OPENGL, so your window is in Portrait mode in fact.
Therefore, It should be set to Landscape by the project file HelloCPP.mkb to achieve that. But i am not familiar with Marmalade, i don’t know how to make it work in this way.

Óscar García wrote:

Hi Matt,
>
Finally I’ve got it!
>
You have to rotate the projection matrix depending on the device orientation.
You get the number of times you have to rotate 90º calling this method:
>
IwGLGetInt( IW_GL_ROTATE );
>
So if you have your device in landscape mode you get 1 as a result. So you
will have to rotate 90º your projection matrix.
Creating a 2d projection I have added this code:
>
case kCCDirectorProjection2D:{
@ kmGLMatrixMode(KM_GL_PROJECTION);
@ kmGLLoadIdentity();
@ kmGLRotatef( –90, 0, 0, 1 ); // New code: rotate to achieve landscape orientation
@ kmMat4 orthoMatrix;
@ kmMat4OrthographicProjection(&orthoMatrix, 0, size.width, 0, size.height, –1024, 1024 );
@ kmGLMultMatrix(&orthoMatrix);
@ kmGLMatrixMode(KM_GL_MODELVIEW);
@ kmGLLoadIdentity();
} break;
>
My app.icf file:
>
[s3e]
IOSDispScaleFactor = 200
DispFixRot = FixedLandscape
>
So to have it working I think you have to modify the CCEGLView interface in order to get the
number of degrees to rotate the projection matrix.
>
I hope this post helps someone.
>
Cheers!

Hi James,

In Marmalade you have a configuration file to set different things on/off
for example to put your device in portrait/landscape mode. The file is app.icf, it contains different sections
but in order to put the device in landscape you have to set:

[s3e]
DispFixRot = Landscape

And if you want to active the retina display you have to put and scale factor only apply when
the program its running on the device ( iPhone, iPad, etc ) the variable to set is

IOSDispScaleFactor = value ( if you put 100 you have normal resolution if you put 200 you have the retina. You could use a value of 150… but for
me it doesn’t any sense)

So when you set DispFixRot = Landscape, and you initialize OpenGL using IwGLInit() ( which is the way to initialize openGL in Marmalade )

Cheers!
it create the frame buffer but rotated. I think this true because calling IwGLGetInt( IW_GL_ROTATE ) it returns 1 which is
the screen has been rotated by 90º ( you’re in landscape mode ) that’s why you have to rotate the projection matrix.

But I don’t know if there is a better way of do it! I think the guy/guys of marmalade who are doing the integration should say something.

Hi Oscar

Your approach is basically the same as the one we use. Here’s what we do:

  • Define a new method on your AppDelegate class:
    // Update the projection, based on an input angle, and store back the new w, h
    // angle - 0, 90, 180 or 270
    // w - the new width of the virtual display
    // h - the new height of the virtual display
    void UpdateProjection(float angle, float& w, float& h);

  • Implement as follows:
    void AppDelegate::UpdateProjection(float angle, float& w, float& h)
    {
    if (IwGLGetInt(IW_GL_VIRTUAL_WIDTH) >= 0)
    {
    w = (float)IwGLGetInt(IW_GL_VIRTUAL_WIDTH);
    h = (float)IwGLGetInt(IW_GL_VIRTUAL_HEIGHT);
    }
    else
    {
    w = (float)s3eSurfaceGetInt(S3E_SURFACE_WIDTH);
    h = (float)s3eSurfaceGetInt(S3E_SURFACE_HEIGHT);
    }
    if ((angle 90.0f) || (angle 270.0f))
    {
    // Swap w and h
    float oh = h;
    h = w;
    w = oh;
    }
    CCEGLView::sharedOpenGLView()>setFrameSize;
    kmGLMatrixMode;
    kmGLLoadIdentity;
    kmGLRotatefangle, 0, 0, 1);
    kmMat4 orthoMatrix;
    kmMat4OrthographicProjection;
    kmGLMultMatrix;
    kmGLMatrixMode;
    kmGLLoadIdentity;
    }
    * Call this in your AppDelegate set-up, as follows:
    bool AppDelegate::applicationDidFinishLaunching
    {
    // initialize director
    CCDirector **pDirector = CCDirector::sharedDirector;
    pDirector
    >setOpenGLView); // MH: Coco2dx 2.0.3 now uses pointer instead of ref
    pDirector~~>setProjection;
    // Set projection
    float w, h;
    float angle = s3eSurfaceGetInt** 90.0f;
    UpdateProjection;
    … etc, rest of method
    * You can also register for a Marmalade orientation event callback, and implement as follows:
    int32 _CallbackOrientation
    {
    s3eSurfaceOrientation* pS3EEvent = systemData;
    if
    {
    float w, h;
    float angle = pS3EEvent~~>m_DeviceBlitDirection * 90.0f;
    (your global AppDelegate object)~~>UpdateProjection;
    }
    return 0;
    }

    Once you’ve done all of this, then the following should work:
    ~~ Use Marmalade Simulator Configuration~~>Surface settings to change surface rotation… the GL projection will get updated in real time.
    Obviously if you want the layout of screen objects to change, then you need to do this yourself.
    ~~ Use Marmalade ICF [GL] settings to set Virtual Resolution, as described here:
    http://docs.madewithmarmalade.com/native/api_reference/iwglapidocumentation/iwglapioverview/iwglvirtualresolution.html
    So you should be able to set stuff like:
    [GL]
    VirtualWidth=320
    VirtualHeight=480
    VirtualLetterbox=1
    …and have all your code assume a screen size of (320x480)… it will scale and letterbox accordingly.
    NOTE THAT THIS SYSTEM PROVIDED BY MARMALADE EFFECTIVELY OVERRIDES THE DISPLAY SCALING SYSTEM PROVIDED BY COCOS2DX ITSELF.

I’d be interested for you to try this and let me know if you see any issues.

Hi Tim,

I’ve tried the solution you post here and it’s working really well. Some points I’ve added.

CCEGLView::sharedOpenGLView()->setViewPortInPoints( 0.0f, 0.0f, w, h );
After
CCEGLView::sharedOpenGLView()->setFrameSize( w, h );
in the method UpdateProjection

And I’ve negated the rotation angle because in landscape mode the screen appears upside down.
kmGLRotatef( static_cast<float>( -angle ), 0.0f, 0.0f, 1.0f );

The Virtual Resolution stuff seems to work properly as well.

I thing there is a better way to implement a new kind of projection. You can use the CCDirectorDelegate
which has an updateProjection() method. And then use kCCDirectorProjectionCustom as the parameter for
CCDirector::setProjection but I think your solution it’s really good.

Thank you for your support!