فهرست منبع

Revert master changes which are specific to 4.0+

Rémi Verschelde 5 سال پیش
والد
کامیت
241887247a

+ 0 - 76
development/cpp/custom_modules_in_cpp.rst

@@ -257,82 +257,6 @@ The output will be ``60``.
              template. See the :ref:`Compiling <toc-devel-compiling>` pages
              for more information.
 
-Customizing module types initialization
----------------------------------------
-
-Modules can interact with other built-in engine classes during runtime and even
-affect the way core types are initialized. So far, we've been using
-``register_summator_types`` as a way to bring in module classes to be available
-within the engine.
-
-A crude order of the engine setup can be summarized as a list of the following
-type registration methods:
-
-.. code-block:: cpp
-
-    preregister_module_types();
-    preregister_server_types();
-    register_core_singletons();
-    register_server_types();
-    register_scene_types();
-    EditorNode::register_editor_types();
-    register_platform_apis();
-    register_module_types();
-    initialize_physics();
-    initialize_navigation_server();
-    register_server_singletons();
-    register_driver_types();
-    ScriptServer::init_languages();
-
-Our ``Summator`` class is initialized during the ``register_module_types()``
-call. Imagine that we need to satisfy some common module run-time dependency
-(like singletons), or allow us to override existing engine method callbacks
-before they can be assigned by the engine itself. In that case, we want to
-ensure that our module classes are registered *before* any other built-in type.
-
-This is where we can define an optional ``preregister_summator_types()``
-method which will be called before anything else during the
-``preregister_module_types()`` engine setup stage.
-
-We now need to add this method to ``register_types`` header and source files:
-
-.. code-block:: cpp
-
-    /* register_types.h */
-
-    #define MODULE_SUMMATOR_HAS_PREREGISTER
-    void preregister_summator_types();
-
-    void register_summator_types();
-    void unregister_summator_types();
-
-.. note:: Unlike other register methods, we have to explicitly define
-          ``MODULE_SUMMATOR_HAS_PREREGISTER`` to let the build system know what
-          relevant method calls to include at compile time. The module's name
-          has to be converted to uppercase as well.
-
-.. code-block:: cpp
-
-    /* register_types.cpp */
-
-    #include "register_types.h"
-
-    #include "core/class_db.h"
-    #include "summator.h"
-
-    void preregister_summator_types() {
-        // Called before any other core types are registered.
-        // Nothing to do here in this example.
-    }
-
-    void register_summator_types() {
-        ClassDB::register_class<Summator>();
-    }
-
-    void unregister_summator_types() {
-       // Nothing to do here in this example.
-    }
-
 Improving the build system for development
 ------------------------------------------
 

+ 226 - 66
tutorials/plugins/android/android_plugin.rst

@@ -1,16 +1,16 @@
 .. _doc_android_plugin:
 
-Creating Android plugins (Godot 4.0+)
-=====================================
+Creating Android plugins
+========================
 
 Introduction
 ------------
 
-Android plugins are powerful tools to extend the capabilities of the Godot engine 
-by tapping into the functionality provided by the Android platform and ecosystem. 
+Making video games portable is all fine and dandy, until mobile
+gaming monetization shows up.
 
-Mobile gaming monetization is one such example since it requires features 
-and capabilities that don't belong to the core feature set of a game engine:
+This area is complex, usually a mobile game that monetizes needs
+special connections to a server for things like:
 
 -  Analytics
 -  In-app purchases
@@ -29,102 +29,246 @@ and capabilities that don't belong to the core feature set of a game engine:
 -  Posting to Facebook, Twitter, etc.
 -  Push notifications
 
-Making modifications to the Android export template is another use-case since using a plugin for that task allows the project
-to remain compatible with newer Godot versions.
+On iOS, you can write a C++ module and take advantage of the C++/ObjC
+intercommunication. Even using GDNative is possible to make it a plug-in.
+
+On Android, interfacing with C++ through JNI (Java Native Interface) isn't as flexible, so writing plugins
+is considerably more work.
+
+It is also possible that you just want to do modifications to the Android export template, and by using a plugin your project
+can remain compatible with newer Godot versions (as the android source template will get updated on each release).
+
+Maybe REST
+----------
+
+Most of these APIs allow communication via REST/JSON APIs. If the API is relatively simple and does not require
+complex authentication, this may be a better idea than writing a specific Android plugin.
+
+Godot has great support for HTTP, HTTPS and JSON, so an API implemented this way
+will work on every platform, too. 
+
+Of course, in most of the cases, it's easier to just write an Android plugin, so keep reading.
 
 Android plugin
 --------------
 
-While introduced in Godot 3.2.0, the Android plugin system got a significant architecture update starting with Godot 3.2.2. In Godot 4.0, the new architecture became
-the default, rendering plugins for Godot 3.2.0 incompatible with Godot 4.0.
+Writing an Android plugin is now possible, beginning with Godot 3.2. It's also pretty easy! Re-compiling the engine is no longer needed.
+
+Before anything, make sure you understand how to set up a :ref:`custom build environment<doc_android_custom_build>` for Android.
+
+Your plugin needs to be in a folder other than *"build/"* inside the *"res://android"* directory (which was created by following the link above). Any name is fine, so name it according to the SDK you will implement (or just your plugin name).
+
+Once created, there are certain rules to follow, but they are simple.
+
+Android directories
+^^^^^^^^^^^^^^^^^^^
+
+Inside your plugin folder, you can use the standard folders as if they were from an Android Gradle project. Examples of this are:
+
+.. code-block:: none
+
+   src/ - For Java source code, same as in your Android project
+   res/ - For resources
+   aidl/ - For interfaces
+   assets/ - For assets that will be included as-is on export
+   libs/debug - For debug JNI libraries
+   libs/release - For release JNI libraries
+
+Gradle will treat them as part of the project automatically when building, same as the default project files.
+
+"Chunk" files
+^^^^^^^^^^^^^
+
+It is now possible to modify *"AndroidManifest.xml"* and *build.gradle* in *"res://android/build"* directly and Godot will keep your
+changes when building. The problem, however, is that if you update Godot, you will also need to update the *build/* folder and your
+changes will be lost.
 
-As a prerequisite, make sure you understand how to set up a :ref:`custom build environment<doc_android_custom_build>` for Android.
+To overcome this, the Godot Android Plugin system lets you create *chunk* files, where you can specify little bits that can be
+inserted in both *"AndroidManifest.xml"* and *build.gradle*. They are inserted every time Godot builds the project for export or deploy.
 
-At its core, a Godot Android plugin is a `Android archive library <https://developer.android.com/studio/projects/android-library#aar-contents>`_ (*aar* archive file) 
-with the following caveats:
+AndroidManifest.conf
+~~~~~~~~~~~~~~~~~~~~
 
--  The library must have a dependency on the Godot engine library (``godot-lib.x.y.aar``). A stable version is made available for each Godot release.
+This file allows to insert bits of chunk into *AndroidManifest.xml*, the following are supported tags and are entirely optional:
 
--  The library must include a specifically configured ``<meta-data>`` tag in its manifest file.
+.. code-block:: none
 
-Building a Android plugin
-^^^^^^^^^^^^^^^^^^^^^^^^^
+   [user_permissions]
 
-**Prerequisite:** `Android Studio <https://developer.android.com/studio>`_ is strongly recommended as the IDE to use to create Android plugins. 
-The instructions below assumes that you're using Android Studio.
+Any bit of text below this tag is inserted inside the <manifest> tag of the file. This is often used for permission tags.
 
-1.  Follow `these instructions <https://developer.android.com/studio/projects/android-library>`__ to create an Android library module for your plugin.
+.. code-block:: none
 
-2.  Add the Godot engine library as a dependency to your plugin module:
+   [application]
 
-    -  Download the Godot engine library (godot-lib.x.y.aar)
+Any bit of text below this tag inside the <application> tag of the file. Many SDKs require this.
 
-    -   Follow `these instructions <https://developer.android.com/studio/projects/android-library#AddDependency>`__ to add
-        the Godot engine library as a dependency for your plugin.
+.. code-block:: none
 
-    -  In the plugin module's ``build.gradle`` file, replace ``implementation`` with ``compileOnly`` for the dependency line for the Godot engine library.
+   [application_attribs]
 
-3.  Create a new class in the plugin module and make sure it extends ``org.godotengine.godot.plugin.GodotPlugin``.
-    At runtime, it will be used to instantiate a singleton object that will be used by the Godot engine to load, initialize and run the plugin.
+These are attributes you can add at the end of the <application> tag. Some SDKs require this.
 
-4.  Update the plugin ``AndroidManifest.xml`` file:
+gradle.conf
+~~~~~~~~~~~
 
-    -   Open the plugin ``AndroidManifest.xml`` file.
+This file allows to insert bits of chunk into *build.gradle*, the following are supported and are entirely optional:
 
-    -   Add the ``<application></application>`` tag if it's missing.
+.. code-block:: none
 
-    -   In the ``<application>`` tag, add a ``<meta-data>`` tag setup as follow::
-        
-            <meta-data 
-                android:name="org.godotengine.plugin.v1.[PluginName]" 
-                android:value="[plugin.init.ClassFullName]" />
+   [buildscript_repositories]
 
-        Where ``PluginName`` is the name of the plugin, and ``plugin.init.ClassFullName`` is the full name (package + class name) of the plugin loading class.
 
-5.  Add the remaining logic for your plugin and run the ``gradlew build`` command to generate the plugin's ``aar`` file. 
-    The build will likely generate both a ``debug`` and ``release`` ``aar`` files. Depending on your need, pick only one version (usually the ``release`` one) which to provide your users with.
+Any bit of text below this tag is inserted inside the buildscript.repositories section of the build file.
 
-**Note:** The plugin's ``aar`` filename must match the following pattern: ``[PluginName]*.aar`` 
-where ``PluginName`` is the name of the plugin in camel case (e.g: ``GodotPayment.release.aar``).
 
-Loading and using a Android plugin
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: none
 
-Once you have access to the plugin ``aar`` file, move it to the Godot project ``res://android/plugins`` directory.
+   [buildscript_dependencies]
 
-From your script:
 
-.. code-block::
+Any bit of text below this tag is inserted inside the buildscript.dependencies section of the build file.
 
-    if Engine.has_singleton("MyPlugin"):
-        var singleton = Engine.get_singleton("MyPlugin")
-        print(singleton.myPluginFunction("World"))
+.. code-block:: none
 
-**When exporting the project**, you need to add the plugin's name to the ``Custom Template`` -> ``Plugins`` section.
-If trying to add multiple plugins, separate their names by a comma (``,``).
+   [allprojects_repositories]
 
-Bundling GDNative resources
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-A Android plugin can define and provide C/C++ GDNative resources, either to provide and/or access functionality from the game logic.
-The GDNative resources can be bundled within the plugin ``aar`` file which simplifies the distribution and deployment process:
 
-    -   The shared libraries (``.so``) for the defined GDNative libraries will be automatically bundled by the ``aar`` build system. 
+Any bit of text below this tag is inserted inside the allprojects.repositories section of the build file.
+
+.. code-block:: none
+
+   [dependencies]
+
+
+Any bit of text below this tag is inserted inside the dependencies section of the build file.
+
+
+.. code-block:: none
+
+   [android_defaultconfig]
+
+
+Any bit of text below this tag is inserted inside the android.defaultconfig section of the build file.
+
+.. code-block:: none
+
+   [global]
+
+
+Any bit of text below this tag is inserted inside the global scope of the build file.
+
+Java singleton
+--------------
 
-    -   Godot ``*.gdnlib`` and ``*.gdns`` resource files must be manually defined in the plugin ``assets`` directory. 
-        The recommended path for these resources relative to the ``assets`` directory should be: ``godot/plugin/v1/[PluginName]/``.
+An Android plugin will usually have a singleton class that will load it,
+this class inherits from ``Godot.SingletonBase``. Resource identifiers for
+any additional resources you have provided for the module will be in the
+``com.godot.game.R`` class, so you'll likely want to import it.
 
-For GDNative libraries, the plugin singleton object must override the ``org.godotengine.godot.plugin.GodotPlugin::getPluginGDNativeLibrariesPaths()`` method, 
-and return the paths to the bundled GDNative libraries config files (``*.gdnlib``). The paths must be relative to the ``assets`` directory.
-At runtime, the plugin will provide these paths to Godot core which will use them to load and initialize the bundled GDNative libraries.
+A singleton object template follows:
 
-Reference implementations
-^^^^^^^^^^^^^^^^^^^^^^^^^
--   `Godot Oculus Mobile plugin <https://github.com/m4gr3d/godot_oculus_mobile/tree/2.0>`_
+.. code-block:: java
 
-    -   `Bundled gdnative resources <https://github.com/m4gr3d/godot_oculus_mobile/tree/2.0/plugin/src/main/assets/addons/godot_ovrmobile>`_
+    package org.godotengine.godot;
 
--   `Godot Payment plugin <https://github.com/m4gr3d/godot/tree/rearch_godot_android_plugin/platform/android/java/plugins/godotpayment>`_
+    import android.app.Activity;
+    import android.content.Intent;
+    import android.content.Context;
+    import com.godot.game.R;
+    import javax.microedition.khronos.opengles.GL10;
 
+    public class MySingleton extends Godot.SingletonBase {
+
+        protected Activity appActivity;
+        protected Context appContext;
+        private Godot activity = null;
+        private int instanceId = 0;
+
+        public String myFunction(String p_str) {
+            // A function to bind.
+            return "Hello " + p_str;
+        }
+
+        public void getInstanceId(int pInstanceId) {
+            // You will need to call this method from Godot and pass in the get_instance_id().
+            instanceId = pInstanceId;
+        }
+
+        static public Godot.SingletonBase initialize(Activity p_activity) {
+            return new MySingleton(p_activity);
+        }
+
+        public MySingleton(Activity p_activity) {
+            // Register class name and functions to bind.
+            registerClass("MySingleton", new String[]
+                {
+                    "myFunction",
+                    "getInstanceId"
+                });
+            this.appActivity = p_activity;
+            this.appContext = appActivity.getApplicationContext();
+            // You might want to try initializing your singleton here, but android
+            // threads are weird and this runs in another thread, so to interact with Godot you usually have to do.
+            this.activity = (Godot)p_activity;
+            this.activity.runOnUiThread(new Runnable() {
+                    public void run() {
+                        // Useful way to get config info from "project.godot".
+                        String key = GodotLib.getGlobal("plugin/api_key");
+                        // SDK.initializeHere();
+                    }
+            });
+
+        }
+
+        // Forwarded callbacks you can reimplement, as SDKs often need them.
+
+        protected void onMainActivityResult(int requestCode, int resultCode, Intent data) {}
+        protected void onMainRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {}
+
+        protected void onMainPause() {}
+        protected void onMainResume() {}
+        protected void onMainDestroy() {}
+
+        protected void onGLDrawFrame(GL10 gl) {}
+        protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // Singletons will always miss first 'onGLSurfaceChanged' call.
+
+    }
+
+Calling back to Godot
+^^^^^^^^^^^^^^^^^^^^^
+
+Calling back to Godot from Java is a little more difficult. The instance
+ID of the script must be known first, this is obtained by calling
+``get_instance_ID()`` on the script. This returns an integer that can be
+passed to Java.
+
+From Java, use the ``calldeferred`` function to communicate back with Godot.
+Java will most likely run in a separate thread, so calls are deferred:
+
+.. code-block:: java
+
+    GodotLib.calldeferred(<instanceid>, "<function>", new Object[]{param1, param2, etc});
+
+
+Godot will detect this singleton and initialize it at the proper time.
+
+Using it from GDScript
+^^^^^^^^^^^^^^^^^^^^^^
+
+First you will need to add your singleton into the android modules to be loaded. Go to "Project > Project Settings".
+Then on the tab "General" go to the "Android" section, and fill the Modules part with your module name. 
+The module should include the full Java path. For our example: ``org/godotengine/godot/MySingleton``.
+
+.. image:: img/android_modules.png
+
+Then, from your script:
+
+::
+
+    if Engine.has_singleton("MySingleton"):
+        var singleton = Engine.get_singleton("MySingleton")
+        print(singleton.myFunction("World"))
 
 Troubleshooting
 ---------------
@@ -134,5 +278,21 @@ Godot crashes upon load
 
 Check ``adb logcat`` for possible problems, then:
 
+-  Make sure libgodot_android.so is in the ``libs/armeabi`` folder
 -  Check that the methods used in the Java singleton only use simple
-   Java datatypes. More complex datatypes are not supported.
+   Java datatypes, more complex ones are not supported.
+
+Future
+------
+
+Godot has an experimental Java API Wrapper that allows to use the
+entire Java API from GDScript.
+
+It's simple to use and it's used like this:
+
+.. code-block:: none
+
+    class = JavaClassWrapper.wrap(<javaclass as text>)
+
+This is most likely not functional yet, if you want to test it and help
+us make it work, contact us on irc.freenode.org:#godotengine-devel.

+ 0 - 68
tutorials/shading/shading_reference/shading_language.rst

@@ -290,74 +290,6 @@ Global constants are useful when you want to have access to a value throughout y
 
     const float PI = 3.14159265358979323846;
 
-
-Structs
--------
-
-Structs are compound types which can be used for better abstaction of shader code. You can declare them at the global scope like:
-
-.. code-block:: glsl
-
-    struct PointLight {
-        vec3 position;
-        vec3 color;
-        float intensity;
-    };
-
-After declaration, you can instantiate and initialize them like:
-
-.. code-block:: glsl
-
-    void fragment()
-    {
-        PointLight light;
-        light.position = vec3(0.0);
-        light.color = vec3(1.0, 0.0, 0.0);
-        light.intensity = 0.5;
-    }
-
-Or use struct constructor for same purpose:
-
-.. code-block:: glsl
-
-    PointLight light = PointLight(vec3(0.0), vec3(1.0, 0.0, 0.0), 0.5);
-
-Structs may contain other struct or array, you can also instance them as global constant:
-
-.. code-block:: glsl
-
-    shader_type spatial;
-
-    ...
-
-    struct Scene {
-        PointLight lights[2];
-    };
-
-    const Scene scene = Scene(PointLight[2](PointLight(vec3(0.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), 1.0), PointLight(vec3(0.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), 1.0)));
-
-    void fragment()
-    {
-        ALBEDO = scene.lights[0].color;
-    }
-
-You can also pass them to functions:
-
-.. code-block:: glsl
-
-    shader_type canvas_item;
-
-    ...
-
-    Scene construct_scene(PointLight light1, PointLight light2) {
-        return Scene({light1, light2});
-    }
-
-    void fragment()
-    { 
-        COLOR.rgb = construct_scene(PointLight(vec3(0.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), 1.0), PointLight(vec3(0.0, 0.0, 0.0), vec3(1.0, 0.0, 1.0), 1.0)).lights[0].color;
-    }
-
 Operators
 ---------