Cocos2d-x V4.0 released

I’m making this post incase anyone else is having trouble with this.

I’m currently creating a new project using v4 and setting up everything using cmake and learning as I go.
Project is created fine with cmake and compiles both for mac and iOS, however on iOS project I noticed only iPhone device comes checked by default.Screen Shot 2020-01-10 at 4.03.18 PM .

Obviously you just can’t check iPad from xcode… you have to somehow make cmake set this for you.
From https://github.com/cocos2d/cocos2d-x/blob/v4/cmake/README.md it says:

Bundle Identifier, Version numbers and Device Support

All this information is held in the Info.plist file that is part of the app’s source files and is therefore not generated by cmake . Therefore you can update these values from the General page of the Xcode target and the values will be preserved the next time you regenerate the project from cmake :

However I could see Info.plist wasn’t being edited so after deleting and regenerating the project with cmake I was back to having only iPhone selected.
After trying cmake stuff with no luck I did some googling and found this:

From here I gathered

XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY “1,2”

was what I needed so I added the following line to my CMakeLists.txt:
set_xcode_property(${APP_NAME} TARGETED_DEVICE_FAMILY "1,2")

This works fine, regenerating the project has both iPhone and iPad selected.

1 Like

+1

I think I had a similar issue a while ago which caused issue on ipads

Why does the android studio project come generated? Shouldn’t we generate it using cmake as with the other platforms?

I’m looking around for info why this decision was made but found nothing :frowning:

Also, should we open it as a new project or use import project form android studio?
Screen Shot 2020-01-14 at 11.15.43 AM

@bolin Click the Open an existing Android Studio project and select the proj.android folder.

1 Like

What’s’ the correct/preferred workflow when using cmake and version control when working as a team?

For example: I create some new source files in xcode, add them to CMakeLists.txt and push the changes to a git repo. Someone else fetches the changes, merges and then has to regenerate the project. This has to be done each time someone adds new files to the project… it seems cumbersome. I’m sure there’s some way to automate part of the steps (regenerating project when CMakeLists.txt has changed for example).

Android project isn’t working for me :frowning:

This is after creating a new project with v4 and opening proj.android/ in Android Studio 3.1.3
Gradle project sync fails with error:

org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierImpl.getModuleIdentifier()Lorg/gradle/api/artifacts/ModuleIdentifier;

I noticed in app/build.gradle that the line
import org.gradle.internal.os.OperatingSystem

Is giving error since gradle symbole can’t be resolved.

Your Android Studio version is a little old, and you also don’t state the Gradle Version or Gradle plugin version.

Using Android Studio v3.5.3, Gradle Plugin v3.5.3 and Gradle Version 5.4.1 on Windows 10 builds Cocos2d-x v4 correctly.

@bolin

Why does the android studio project come generated? Shouldn’t we generate it using cmake as with the other platforms?

Android only partly uses cmake, because it mainly uses gradle.
You are quite limited on what cmake can do for you for the Android project.

For example you can handle source files etc with cmake, but copying resources etc is done in gradle.

As far as i know this simply how Android projects in general are setup.

At least this was the case the last time I was researching about this.
If there is something new, I’d be also interested in it

This has to be done each time someone adds new files to the project… it seems cumbersome. I’m sure there’s some way to automate part of the steps (regenerating project when CMakeLists.txt has changed for example).

The way I used cmake so far is everytime you update from git, run cmake / gradle , this updates all the source code, structure or whatever other changes. For file changes,updates it shouldn’t be much of an issue and be even fast. (most of the time it should even work while your IDE is open) You rarely have to delete the cmake cache and completely regenerate the project with cmake.

How do you handle creating new source files?
Right now I’m creating files from xcode then manually editing CMakeLists.txt which is tedious.
And if I’m creating new folders with header files I also ahve to update CMakeLists.txt’s target_include_directories.

Regarding v4 migration and shaders:

I’m not sure what’s the correct way to load and store shaders.
In v3 there’s GLProgramCache which had a method addGLProgram(), however in v4’s ProgramCache the method addProgram() is now protected.

I found this example https://docs.cocos2d-x.org/cocos2d-x/v4/en/upgradeGuide/spriteTutorial.html but it seems to be outdated. It says to use ProgramState(const std::string& vertexShader, const std::string& fragmentShader) to create a ProgramState however this constructor doesn’t exist.
I’ll keep looking in the code but so far I haven’t been able to figure out how to load custom shaders.

edit: found backend::Device which has a method to create programs, however still no clue regarding ProgramCache.

This is the recommended way for CMake

But if you are a lazy developer like me you can use GLOB (GLOB_RECURSE for subfolders)

file(GLOB_RECURSE  GAME_SOURCE Classes/*.cpp)
file(GLOB_RECURSE  GAME_HEADER Classes/*.h)

Even tough the cmake experts advice against it xD
I rarely have issues with this. I think only Android sometimes fails to detect new source file where I then have to delete the cache and recompile due to GLOB (i think)

For shaders hopefully someone else can help, i’m still on 3.17.x

With v4, built-in shaders are cached, but custom shaders are not, so you will need to cache the shaders yourself if required. Also, be mindful of the fact that they no longer have autorelease() called on them, and since you create them via new, so you will either need to either call autorelease() on the custom Program/ProgramState yourself, or just handle them using retain()/release() calls.

For example:

ProgramState* CreateProgramStateFromFragment(const std::string& fragmentShaderPath)
{
    const auto fileUtils = cocos2d::FileUtils::getInstance();
    const auto fragmentFullPath = fileUtils->fullPathForFilename(fragmentShaderPath);
    const auto fragSource = fileUtils->getStringFromFile(fragmentFullPath);
    const auto program = cocos2d::backend::Device::getInstance()->newProgram(cocos2d::positionTextureColor_vert, fragSource);

    const auto programState = new (std::nothrow) ProgramState(program);

    // Program must be released if no longer used, since it is not auto-released
    CC_SAFE_RELEASE(program);

    return programState;
}

// and this is how you use it
const auto programState = CreateProgramStateFromFragment("path/to/example_shader.frag");

// say it has a float as a uniform variable
float myFloat = 1.0f;
auto myUniformLocation = programState->getUniformLocation("u_myUniformVariable");
programState->setUniform(myUniformLocation, &myFloat, sizeof(myFloat));
sprite->setProgramState(programState);
CC_SAFE_RELEASE(programState); // required since Sprite::setProgramState() calls 'retain' on it, so the reference count goes to 2, and since it is not auto-released, we need to release it here to bring it back to reference count of 1.

Now, if you call clone() on a ProgramState, then you would also need to release the object after assigning it to anything that calls retain() on it, like a sprite:

auto clonedProgramState = programState->clone();
sprite->setProgramState(clonedProgramState);
auto uLocation = clonedProgramState->getUniformLocation("u_myUniformVariable");
clonedProgramState->setUniform(uLocation, &myFloat, sizeof(myFloat));
CC_SAFE_RELEASE(clonedProgramState); // required since Sprite::setProgramState() calls 'retain' on it, so the reference count goes to 2, and since it is not auto-released, we need to release it here to bring it back to reference count of 1.

Anyhow, I hope that helps.

EDIT: Fixed up some mistakes in my initial description of the release/retain requirements.

1 Like

Thanks @R101.

I wonder why ProgramState doesn’t follow the usual create()->autorelease() paradigm. Anyone knows the reasoning behind this?

Hi, i have a Metal related question,

I am using a third-party library to render effects in cocos2d-x. It is working fine on Opengl, but on Metal, it is rendering behind the 3d models instead of on top.
after doing a search, i found this is exactly what i’m experiencing, when changing the depth function to always or greater, it renders correctly, but i suppose the correct setting should be less or equal?

So, i’d like to know, as per the answer in the link, is there any special handling of the projection matrix within Cocos2d-x for Metal depth test to be applied correctly?
I’d like to reference the code that cocos2d-x is using, to apply it to the effect renderer so that it will look correct. Thanks!

Hey
i was reading somewhere in one of the posts that has bean closed
is it true that javascript binding is removed ?
that means no more javascript programing using cocos2dx ?
can you confirm and give more details why ?
Thanks

Yes this is true.

Please use Cocos Creator for javascript game development.

and what about lua support ?

I do not use Lua but … I believe removing Lua from next cocos2dx version will significantly simplify code and maintaince.

1 Like

would be sad, I was thinking about adding Lua scripting support to my project at some point :frowning:

Is anyone having problems with EventListenerTouchAllAtOnce?
All my callbacks are receiving only one touch when using multiple fingers.

edit: doh, I forgot by default multitouch isn’t enabled.
In proj.ios_mac/ios/RootViewController.mm do [eaglView setMultipleTouchEnabled:YES];

Just curious why wouldn’t it be enabled by default?

How do you deal with files in Resources/ when working with a team?
Right now we have our project built with cmake on a git repo. I added some assets to a new folder in Resources/ and pushed the changes. When a coworker fetched the changes his xcode project doesn’t recongnize the new project structure and has errors regarding the assets I changed. The only solution we found is delete project and regenerate with cmake which is a lot of trouble specially if you are continuously changing assets since each time the project is regenerated the whole project (including cocos) has to be built again.