Cocos2d-x V4.0 released

Cocos2d-x V4.0 released
0

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.

Normally it should be enough to just run cmake again without deleting stuff, this should regenerate the structure and copy the resources. Without deleting, you usually also don’t need to rebuild everything and it should be pretty quick.

I have to do this in Windows anyway otherwise it won’t copy the new Resources over to the exe build folder. For me I always run cmake when I pull somth from git (in really rare error cases i delete the cache).

Only issue I ran into when working in a team on other bigger (mainly non cocos) 3d projects is when 2 want to modify the same asset, where you’d need to check if git (mby git lfs) support locking for files like svn.

@Darren You can reference createOrthographicOffCenter and createPerspective in Mat4.cpp in v4 which do a special handling according to this post .

I don’t know if this is the right place to post this, but the v4 documentation about the audio engine speaks about SimpleAudioEngine:
https://docs.cocos2d-x.org/cocos2d-x/v4/en/audio/getting_started.html

Even though it was removed in v4.0.

Yes we need to build out this doc. It’s on my list. I’ll remove the doc for now.

Congratulations on this release and thank you for your hard work!