Deprecate ImmediateGeometry

* Removed entirely from RenderingServer.
* Replaced by ImmediateMesh resource.
* ImmediateMesh replaces ImmediateGeometry, but could use more optimization in the future.
* Sprite3D and AnimatedSprite3D work again, ported from Godot 3.x (though a lot of work was needed to adapt them to Godot 4).
* RootMotionView works again.
* Polygon3D editor works again.
This commit is contained in:
reduz 2021-06-29 22:55:11 -03:00
parent bcd1fc832f
commit 85cf99f28e
32 changed files with 1082 additions and 834 deletions

View File

@ -43,7 +43,7 @@
[/csharp] [/csharp]
[/codeblocks] [/codeblocks]
The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown. The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown.
See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for procedural geometry generation. See also [ImmediateMesh], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes. [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description> </description>
<tutorials> <tutorials>
@ -202,7 +202,31 @@
Sets a name for a given surface. Sets a name for a given surface.
</description> </description>
</method> </method>
<method name="surface_update_region"> <method name="surface_update_attribute_region">
<return type="void">
</return>
<argument index="0" name="surf_idx" type="int">
</argument>
<argument index="1" name="offset" type="int">
</argument>
<argument index="2" name="data" type="PackedByteArray">
</argument>
<description>
</description>
</method>
<method name="surface_update_skin_region">
<return type="void">
</return>
<argument index="0" name="surf_idx" type="int">
</argument>
<argument index="1" name="offset" type="int">
</argument>
<argument index="2" name="data" type="PackedByteArray">
</argument>
<description>
</description>
</method>
<method name="surface_update_vertex_region">
<return type="void"> <return type="void">
</return> </return>
<argument index="0" name="surf_idx" type="int"> <argument index="0" name="surf_idx" type="int">
@ -212,8 +236,6 @@
<argument index="2" name="data" type="PackedByteArray"> <argument index="2" name="data" type="PackedByteArray">
</argument> </argument>
<description> <description>
Updates a specified region of mesh arrays on the GPU.
[b]Warning:[/b] Only use if you know what you are doing. You can easily cause crashes by calling this function with improper arguments.
</description> </description>
</method> </method>
</methods> </methods>

View File

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ImmediateGeometry3D" inherits="GeometryInstance3D" version="4.0">
<brief_description>
Draws simple geometry from code.
</brief_description>
<description>
Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x.
See also [ArrayMesh], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
[b]Note:[/b] ImmediateGeometry3D is best suited to small amounts of mesh data that change every frame. It will be slow when handling large amounts of mesh data. If mesh data doesn't change often, use [ArrayMesh], [MeshDataTool] or [SurfaceTool] instead.
[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
</tutorials>
<methods>
<method name="add_sphere">
<return type="void">
</return>
<argument index="0" name="lats" type="int">
</argument>
<argument index="1" name="lons" type="int">
</argument>
<argument index="2" name="radius" type="float">
</argument>
<argument index="3" name="add_uv" type="bool" default="true">
</argument>
<description>
Simple helper to draw an UV sphere with given latitude, longitude and radius.
</description>
</method>
<method name="add_vertex">
<return type="void">
</return>
<argument index="0" name="position" type="Vector3">
</argument>
<description>
Adds a vertex in local coordinate space with the currently set color/uv/etc.
</description>
</method>
<method name="begin">
<return type="void">
</return>
<argument index="0" name="primitive" type="int" enum="Mesh.PrimitiveType">
</argument>
<argument index="1" name="texture" type="Texture2D" default="null">
</argument>
<description>
Begin drawing (and optionally pass a texture override). When done call [method end]. For more information on how this works, search for [code]glBegin()[/code] and [code]glEnd()[/code] references.
For the type of primitive, see the [enum Mesh.PrimitiveType] enum.
</description>
</method>
<method name="clear">
<return type="void">
</return>
<description>
Clears everything that was drawn using begin/end.
</description>
</method>
<method name="end">
<return type="void">
</return>
<description>
Ends a drawing context and displays the results.
</description>
</method>
<method name="set_color">
<return type="void">
</return>
<argument index="0" name="color" type="Color">
</argument>
<description>
The current drawing color.
</description>
</method>
<method name="set_normal">
<return type="void">
</return>
<argument index="0" name="normal" type="Vector3">
</argument>
<description>
The next vertex's normal.
</description>
</method>
<method name="set_tangent">
<return type="void">
</return>
<argument index="0" name="tangent" type="Plane">
</argument>
<description>
The next vertex's tangent (and binormal facing).
</description>
</method>
<method name="set_uv">
<return type="void">
</return>
<argument index="0" name="uv" type="Vector2">
</argument>
<description>
The next vertex's UV.
</description>
</method>
<method name="set_uv2">
<return type="void">
</return>
<argument index="0" name="uv" type="Vector2">
</argument>
<description>
The next vertex's second layer UV.
</description>
</method>
</methods>
<constants>
</constants>
</class>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ImmediateMesh" inherits="Mesh" version="4.0">
<brief_description>
Mesh optimized for creating geometry manually.
</brief_description>
<description>
Mesh optimized for creating geometry manually, similar to OpenGL1.x immediate mode.
</description>
<tutorials>
</tutorials>
<methods>
<method name="clear_surfaces">
<return type="void">
</return>
<description>
Clear all surfaces.
</description>
</method>
<method name="surface_add_vertex">
<return type="void">
</return>
<argument index="0" name="vertex" type="Vector3">
</argument>
<description>
Add a 3D vertex using the current attributes previously set.
</description>
</method>
<method name="surface_add_vertex_2d">
<return type="void">
</return>
<argument index="0" name="vertex" type="Vector2">
</argument>
<description>
Add a 2D vertex using the current attributes previously set.
</description>
</method>
<method name="surface_begin">
<return type="void">
</return>
<argument index="0" name="primitive" type="int" enum="Mesh.PrimitiveType">
</argument>
<argument index="1" name="material" type="Material" default="null">
</argument>
<description>
Begin a new surface.
</description>
</method>
<method name="surface_end">
<return type="void">
</return>
<description>
End and commit current surface. Note that surface being created will not be visible until this function is called.
</description>
</method>
<method name="surface_set_color">
<return type="void">
</return>
<argument index="0" name="color" type="Color">
</argument>
<description>
Set the color attribute that will be pushed with the next vertex.
</description>
</method>
<method name="surface_set_normal">
<return type="void">
</return>
<argument index="0" name="normal" type="Vector3">
</argument>
<description>
Set the normal attribute that will be pushed with the next vertex.
</description>
</method>
<method name="surface_set_tangent">
<return type="void">
</return>
<argument index="0" name="tangent" type="Plane">
</argument>
<description>
Set the tangent attribute that will be pushed with the next vertex.
</description>
</method>
<method name="surface_set_uv">
<return type="void">
</return>
<argument index="0" name="uv" type="Vector2">
</argument>
<description>
Set the UV attribute that will be pushed with the next vertex.
</description>
</method>
<method name="surface_set_uv2">
<return type="void">
</return>
<argument index="0" name="uv2" type="Vector2">
</argument>
<description>
Set the UV2 attribute that will be pushed with the next vertex.
</description>
</method>
</methods>
<constants>
</constants>
</class>

View File

@ -45,7 +45,7 @@
AddChild(mi); AddChild(mi);
[/csharp] [/csharp]
[/codeblocks] [/codeblocks]
See also [ArrayMesh], [ImmediateGeometry3D] and [SurfaceTool] for procedural geometry generation. See also [ArrayMesh], [ImmediateMesh] and [SurfaceTool] for procedural geometry generation.
[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes. [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description> </description>
<tutorials> <tutorials>

View File

@ -988,143 +988,6 @@
Returns [code]true[/code] if the OS supports a certain feature. Features might be [code]s3tc[/code], [code]etc[/code], [code]etc2[/code] and [code]pvrtc[/code]. Returns [code]true[/code] if the OS supports a certain feature. Features might be [code]s3tc[/code], [code]etc[/code], [code]etc2[/code] and [code]pvrtc[/code].
</description> </description>
</method> </method>
<method name="immediate_begin">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="primitive" type="int" enum="RenderingServer.PrimitiveType">
</argument>
<argument index="2" name="texture" type="RID">
</argument>
<description>
Sets up [ImmediateGeometry3D] internals to prepare for drawing. Equivalent to [method ImmediateGeometry3D.begin].
</description>
</method>
<method name="immediate_clear">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<description>
Clears everything that was set up between [method immediate_begin] and [method immediate_end]. Equivalent to [method ImmediateGeometry3D.clear].
</description>
</method>
<method name="immediate_color">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="color" type="Color">
</argument>
<description>
Sets the color to be used with next vertex. Equivalent to [method ImmediateGeometry3D.set_color].
</description>
</method>
<method name="immediate_create">
<return type="RID">
</return>
<description>
Creates an immediate geometry and adds it to the RenderingServer. It can be accessed with the RID that is returned. This RID will be used in all [code]immediate_*[/code] RenderingServer functions.
Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method.
To place in a scene, attach this immediate geometry to an instance using [method instance_set_base] using the returned RID.
</description>
</method>
<method name="immediate_end">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<description>
Ends drawing the [ImmediateGeometry3D] and displays it. Equivalent to [method ImmediateGeometry3D.end].
</description>
</method>
<method name="immediate_get_material" qualifiers="const">
<return type="RID">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<description>
Returns the material assigned to the [ImmediateGeometry3D].
</description>
</method>
<method name="immediate_normal">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="normal" type="Vector3">
</argument>
<description>
Sets the normal to be used with next vertex. Equivalent to [method ImmediateGeometry3D.set_normal].
</description>
</method>
<method name="immediate_set_material">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="material" type="RID">
</argument>
<description>
Sets the material to be used to draw the [ImmediateGeometry3D].
</description>
</method>
<method name="immediate_tangent">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="tangent" type="Plane">
</argument>
<description>
Sets the tangent to be used with next vertex. Equivalent to [method ImmediateGeometry3D.set_tangent].
</description>
</method>
<method name="immediate_uv">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="tex_uv" type="Vector2">
</argument>
<description>
Sets the UV to be used with next vertex. Equivalent to [method ImmediateGeometry3D.set_uv].
</description>
</method>
<method name="immediate_uv2">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="tex_uv" type="Vector2">
</argument>
<description>
Sets the UV2 to be used with next vertex. Equivalent to [method ImmediateGeometry3D.set_uv2].
</description>
</method>
<method name="immediate_vertex">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="vertex" type="Vector3">
</argument>
<description>
Adds the next vertex using the information provided in advance. Equivalent to [method ImmediateGeometry3D.add_vertex].
</description>
</method>
<method name="immediate_vertex_2d">
<return type="void">
</return>
<argument index="0" name="immediate" type="RID">
</argument>
<argument index="1" name="vertex" type="Vector2">
</argument>
<description>
Adds the next vertex using the information provided in advance. This is a helper class that calls [method immediate_vertex] under the hood. Equivalent to [method ImmediateGeometry3D.add_vertex].
</description>
</method>
<method name="init"> <method name="init">
<return type="void"> <return type="void">
</return> </return>
@ -1787,21 +1650,6 @@
Sets a mesh's surface's material. Sets a mesh's surface's material.
</description> </description>
</method> </method>
<method name="mesh_surface_update_region">
<return type="void">
</return>
<argument index="0" name="mesh" type="RID">
</argument>
<argument index="1" name="surface" type="int">
</argument>
<argument index="2" name="offset" type="int">
</argument>
<argument index="3" name="data" type="PackedByteArray">
</argument>
<description>
Updates a specific region of a vertex buffer for the specified surface. Warning: this function alters the vertex buffer directly with no safety mechanisms, you can easily corrupt your mesh.
</description>
</method>
<method name="multimesh_allocate_data"> <method name="multimesh_allocate_data">
<return type="void"> <return type="void">
</return> </return>
@ -3677,35 +3525,32 @@
<constant name="INSTANCE_MULTIMESH" value="2" enum="InstanceType"> <constant name="INSTANCE_MULTIMESH" value="2" enum="InstanceType">
The instance is a multimesh. The instance is a multimesh.
</constant> </constant>
<constant name="INSTANCE_IMMEDIATE" value="3" enum="InstanceType"> <constant name="INSTANCE_PARTICLES" value="3" enum="InstanceType">
The instance is an immediate geometry.
</constant>
<constant name="INSTANCE_PARTICLES" value="4" enum="InstanceType">
The instance is a particle emitter. The instance is a particle emitter.
</constant> </constant>
<constant name="INSTANCE_PARTICLES_COLLISION" value="5" enum="InstanceType"> <constant name="INSTANCE_PARTICLES_COLLISION" value="4" enum="InstanceType">
</constant> </constant>
<constant name="INSTANCE_LIGHT" value="6" enum="InstanceType"> <constant name="INSTANCE_LIGHT" value="5" enum="InstanceType">
The instance is a light. The instance is a light.
</constant> </constant>
<constant name="INSTANCE_REFLECTION_PROBE" value="7" enum="InstanceType"> <constant name="INSTANCE_REFLECTION_PROBE" value="6" enum="InstanceType">
The instance is a reflection probe. The instance is a reflection probe.
</constant> </constant>
<constant name="INSTANCE_DECAL" value="8" enum="InstanceType"> <constant name="INSTANCE_DECAL" value="7" enum="InstanceType">
The instance is a decal. The instance is a decal.
</constant> </constant>
<constant name="INSTANCE_VOXEL_GI" value="9" enum="InstanceType"> <constant name="INSTANCE_VOXEL_GI" value="8" enum="InstanceType">
The instance is a VoxelGI. The instance is a VoxelGI.
</constant> </constant>
<constant name="INSTANCE_LIGHTMAP" value="10" enum="InstanceType"> <constant name="INSTANCE_LIGHTMAP" value="9" enum="InstanceType">
The instance is a lightmap. The instance is a lightmap.
</constant> </constant>
<constant name="INSTANCE_OCCLUDER" value="11" enum="InstanceType"> <constant name="INSTANCE_OCCLUDER" value="10" enum="InstanceType">
</constant> </constant>
<constant name="INSTANCE_MAX" value="13" enum="InstanceType"> <constant name="INSTANCE_MAX" value="12" enum="InstanceType">
Represents the size of the [enum InstanceType] enum. Represents the size of the [enum InstanceType] enum.
</constant> </constant>
<constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType"> <constant name="INSTANCE_GEOMETRY_MASK" value="14" enum="InstanceType">
A combination of the flags of geometry instances (mesh, multimesh, immediate and particles). A combination of the flags of geometry instances (mesh, multimesh, immediate and particles).
</constant> </constant>
<constant name="INSTANCE_FLAG_USE_BAKED_LIGHT" value="0" enum="InstanceFlags"> <constant name="INSTANCE_FLAG_USE_BAKED_LIGHT" value="0" enum="InstanceFlags">

View File

@ -21,7 +21,6 @@
The number of columns in the sprite sheet. The number of columns in the sprite sheet.
</member> </member>
<member name="region_enabled" type="bool" setter="set_region_enabled" getter="is_region_enabled" default="false"> <member name="region_enabled" type="bool" setter="set_region_enabled" getter="is_region_enabled" default="false">
If [code]true[/code], texture will be cut from a larger atlas texture. See [member region_rect].
</member> </member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2(0, 0, 0, 0)"> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2(0, 0, 0, 0)">
The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. The region of the atlas texture to display. [member region_enabled] must be [code]true[/code].
@ -39,11 +38,6 @@
Emitted when the [member frame] changes. Emitted when the [member frame] changes.
</description> </description>
</signal> </signal>
<signal name="texture_changed">
<description>
Emitted when the [member texture] changes.
</description>
</signal>
</signals> </signals>
<constants> <constants>
</constants> </constants>

View File

@ -24,7 +24,7 @@
The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method set_uv] or [method set_color], then the last values would be used. The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method set_uv] or [method set_color], then the last values would be used.
Vertex attributes must be passed [b]before[/b] calling [method add_vertex]. Failure to do so will result in an error when committing the vertex information to a mesh. Vertex attributes must be passed [b]before[/b] calling [method add_vertex]. Failure to do so will result in an error when committing the vertex information to a mesh.
Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices. Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices.
See also [ArrayMesh], [ImmediateGeometry3D] and [MeshDataTool] for procedural geometry generation. See also [ArrayMesh], [ImmediateMesh] and [MeshDataTool] for procedural geometry generation.
[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes. [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description> </description>
<tutorials> <tutorials>

View File

@ -358,9 +358,9 @@ void CollisionPolygon3DEditor::_polygon_draw() {
float depth = _get_depth() * 0.5; float depth = _get_depth() * 0.5;
imgeom->clear(); imesh->clear_surfaces();
imgeom->set_material_override(line_material); imgeom->set_material_override(line_material);
imgeom->begin(Mesh::PRIMITIVE_LINES, Ref<Texture2D>()); imesh->surface_begin(Mesh::PRIMITIVE_LINES);
Rect2 rect; Rect2 rect;
@ -382,10 +382,10 @@ void CollisionPolygon3DEditor::_polygon_draw() {
Vector3 point = Vector3(p.x, p.y, depth); Vector3 point = Vector3(p.x, p.y, depth);
Vector3 next_point = Vector3(p2.x, p2.y, depth); Vector3 next_point = Vector3(p2.x, p2.y, depth);
imgeom->set_color(Color(1, 0.3, 0.1, 0.8)); imesh->surface_set_color(Color(1, 0.3, 0.1, 0.8));
imgeom->add_vertex(point); imesh->surface_add_vertex(point);
imgeom->set_color(Color(1, 0.3, 0.1, 0.8)); imesh->surface_set_color(Color(1, 0.3, 0.1, 0.8));
imgeom->add_vertex(next_point); imesh->surface_add_vertex(next_point);
//Color col=Color(1,0.3,0.1,0.8); //Color col=Color(1,0.3,0.1,0.8);
//vpc->draw_line(point,next_point,col,2); //vpc->draw_line(point,next_point,col,2);
@ -402,45 +402,43 @@ void CollisionPolygon3DEditor::_polygon_draw() {
r.size.y = rect.size.y; r.size.y = rect.size.y;
r.size.z = 0; r.size.z = 0;
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position); imesh->surface_add_vertex(r.position);
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(0.3, 0, 0)); imesh->surface_add_vertex(r.position + Vector3(0.3, 0, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position); imesh->surface_add_vertex(r.position);
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(0.0, 0.3, 0)); imesh->surface_add_vertex(r.position + Vector3(0.0, 0.3, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0)); imesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0) - Vector3(0.3, 0, 0)); imesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0) - Vector3(0.3, 0, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0)); imesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0) + Vector3(0, 0.3, 0)); imesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0) + Vector3(0, 0.3, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0)); imesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0) - Vector3(0, 0.3, 0)); imesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0) - Vector3(0, 0.3, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0)); imesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0) + Vector3(0.3, 0, 0)); imesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0) + Vector3(0.3, 0, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + r.size); imesh->surface_add_vertex(r.position + r.size);
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + r.size - Vector3(0.3, 0, 0)); imesh->surface_add_vertex(r.position + r.size - Vector3(0.3, 0, 0));
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + r.size); imesh->surface_add_vertex(r.position + r.size);
imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); imesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2));
imgeom->add_vertex(r.position + r.size - Vector3(0.0, 0.3, 0)); imesh->surface_add_vertex(r.position + r.size - Vector3(0.0, 0.3, 0));
imgeom->end(); imesh->surface_end();
m->clear_surfaces();
if (poly.size() == 0) { if (poly.size() == 0) {
return; return;
@ -515,7 +513,9 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) {
mode = MODE_EDIT; mode = MODE_EDIT;
wip_active = false; wip_active = false;
imgeom = memnew(ImmediateGeometry3D); imgeom = memnew(MeshInstance3D);
imesh.instantiate();
imgeom->set_mesh(imesh);
imgeom->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); imgeom->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001)));
line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));

View File

@ -34,8 +34,8 @@
#include "editor/editor_node.h" #include "editor/editor_node.h"
#include "editor/editor_plugin.h" #include "editor/editor_plugin.h"
#include "scene/3d/collision_polygon_3d.h" #include "scene/3d/collision_polygon_3d.h"
#include "scene/3d/immediate_geometry_3d.h"
#include "scene/3d/mesh_instance_3d.h" #include "scene/3d/mesh_instance_3d.h"
#include "scene/resources/immediate_mesh.h"
class CanvasItemEditor; class CanvasItemEditor;
@ -60,7 +60,8 @@ class CollisionPolygon3DEditor : public HBoxContainer {
EditorNode *editor; EditorNode *editor;
Panel *panel; Panel *panel;
Node3D *node; Node3D *node;
ImmediateGeometry3D *imgeom; Ref<ImmediateMesh> imesh;
MeshInstance3D *imgeom;
MeshInstance3D *pointsm; MeshInstance3D *pointsm;
Ref<ArrayMesh> m; Ref<ArrayMesh> m;

View File

@ -34,7 +34,6 @@
#include "editor/editor_node.h" #include "editor/editor_node.h"
#include "editor/editor_plugin.h" #include "editor/editor_plugin.h"
#include "editor/editor_scale.h" #include "editor/editor_scale.h"
#include "scene/3d/immediate_geometry_3d.h"
#include "scene/3d/light_3d.h" #include "scene/3d/light_3d.h"
#include "scene/3d/visual_instance_3d.h" #include "scene/3d/visual_instance_3d.h"
#include "scene/3d/world_environment.h" #include "scene/3d/world_environment.h"

View File

@ -1,157 +0,0 @@
/*************************************************************************/
/* immediate_geometry_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "immediate_geometry_3d.h"
void ImmediateGeometry3D::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture) {
RS::get_singleton()->immediate_begin(im, (RS::PrimitiveType)p_primitive, p_texture.is_valid() ? p_texture->get_rid() : RID());
if (p_texture.is_valid()) {
cached_textures.push_back(p_texture);
}
}
void ImmediateGeometry3D::set_normal(const Vector3 &p_normal) {
RS::get_singleton()->immediate_normal(im, p_normal);
}
void ImmediateGeometry3D::set_tangent(const Plane &p_tangent) {
RS::get_singleton()->immediate_tangent(im, p_tangent);
}
void ImmediateGeometry3D::set_color(const Color &p_color) {
RS::get_singleton()->immediate_color(im, p_color);
}
void ImmediateGeometry3D::set_uv(const Vector2 &p_uv) {
RS::get_singleton()->immediate_uv(im, p_uv);
}
void ImmediateGeometry3D::set_uv2(const Vector2 &p_uv2) {
RS::get_singleton()->immediate_uv2(im, p_uv2);
}
void ImmediateGeometry3D::add_vertex(const Vector3 &p_vertex) {
RS::get_singleton()->immediate_vertex(im, p_vertex);
if (empty) {
aabb.position = p_vertex;
aabb.size = Vector3();
empty = false;
} else {
aabb.expand_to(p_vertex);
}
}
void ImmediateGeometry3D::end() {
RS::get_singleton()->immediate_end(im);
}
void ImmediateGeometry3D::clear() {
RS::get_singleton()->immediate_clear(im);
empty = true;
cached_textures.clear();
}
AABB ImmediateGeometry3D::get_aabb() const {
return aabb;
}
Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) {
const double lat_step = Math_TAU / p_lats;
const double lon_step = Math_TAU / p_lons;
for (int i = 1; i <= p_lats; i++) {
double lat0 = lat_step * (i - 1) - Math_TAU / 4;
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
double lat1 = lat_step * i - Math_TAU / 4;
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
for (int j = p_lons; j >= 1; j--) {
double lng0 = lon_step * (j - 1);
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
double lng1 = lon_step * j;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
Vector3 v[4] = {
Vector3(x1 * zr0, z0, y1 * zr0),
Vector3(x1 * zr1, z1, y1 * zr1),
Vector3(x0 * zr1, z1, y0 * zr1),
Vector3(x0 * zr0, z0, y0 * zr0)
};
#define ADD_POINT(m_idx) \
if (p_add_uv) { \
set_uv(Vector2(Math::atan2(v[m_idx].x, v[m_idx].z) / Math_PI * 0.5 + 0.5, v[m_idx].y * 0.5 + 0.5)); \
set_tangent(Plane(Vector3(-v[m_idx].z, v[m_idx].y, v[m_idx].x), 1)); \
} \
set_normal(v[m_idx]); \
add_vertex(v[m_idx] * p_radius);
ADD_POINT(0);
ADD_POINT(1);
ADD_POINT(2);
ADD_POINT(2);
ADD_POINT(3);
ADD_POINT(0);
}
}
}
void ImmediateGeometry3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry3D::begin, DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_normal", "normal"), &ImmediateGeometry3D::set_normal);
ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &ImmediateGeometry3D::set_tangent);
ClassDB::bind_method(D_METHOD("set_color", "color"), &ImmediateGeometry3D::set_color);
ClassDB::bind_method(D_METHOD("set_uv", "uv"), &ImmediateGeometry3D::set_uv);
ClassDB::bind_method(D_METHOD("set_uv2", "uv"), &ImmediateGeometry3D::set_uv2);
ClassDB::bind_method(D_METHOD("add_vertex", "position"), &ImmediateGeometry3D::add_vertex);
ClassDB::bind_method(D_METHOD("add_sphere", "lats", "lons", "radius", "add_uv"), &ImmediateGeometry3D::add_sphere, DEFVAL(true));
ClassDB::bind_method(D_METHOD("end"), &ImmediateGeometry3D::end);
ClassDB::bind_method(D_METHOD("clear"), &ImmediateGeometry3D::clear);
}
ImmediateGeometry3D::ImmediateGeometry3D() {
im = RenderingServer::get_singleton()->immediate_create();
set_base(im);
}
ImmediateGeometry3D::~ImmediateGeometry3D() {
RenderingServer::get_singleton()->free(im);
}

View File

@ -1,72 +0,0 @@
/*************************************************************************/
/* immediate_geometry_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef IMMEDIATE_GEOMETRY_3D_H
#define IMMEDIATE_GEOMETRY_3D_H
#include "scene/3d/visual_instance_3d.h"
#include "scene/resources/mesh.h"
class ImmediateGeometry3D : public GeometryInstance3D {
GDCLASS(ImmediateGeometry3D, GeometryInstance3D);
RID im;
//a list of textures drawn need to be kept, to avoid references
// in RenderingServer from becoming invalid if the texture is no longer used
List<Ref<Texture2D>> cached_textures;
bool empty = true;
AABB aabb;
protected:
static void _bind_methods();
public:
void begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture = Ref<Texture2D>());
void set_normal(const Vector3 &p_normal);
void set_tangent(const Plane &p_tangent);
void set_color(const Color &p_color);
void set_uv(const Vector2 &p_uv);
void set_uv2(const Vector2 &p_uv2);
void add_vertex(const Vector3 &p_vertex);
void end();
void clear();
void add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv = true);
virtual AABB get_aabb() const override;
virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
ImmediateGeometry3D();
~ImmediateGeometry3D();
};
#endif // IMMEDIATE_GEOMETRY_H

View File

@ -81,7 +81,7 @@ void SoftBodyRenderingServerHandler::close() {
} }
void SoftBodyRenderingServerHandler::commit_changes() { void SoftBodyRenderingServerHandler::commit_changes() {
RS::get_singleton()->mesh_surface_update_region(mesh, surface, 0, buffer); RS::get_singleton()->mesh_surface_update_vertex_region(mesh, surface, 0, buffer);
} }
void SoftBodyRenderingServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) { void SoftBodyRenderingServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) {

View File

@ -164,6 +164,8 @@ void SpriteBase3D::_im_update() {
_draw(); _draw();
pending_update = false; pending_update = false;
//texture->draw_rect_region(ci,dst_rect,src_rect,modulate);
} }
void SpriteBase3D::_queue_update() { void SpriteBase3D::_queue_update() {
@ -204,6 +206,7 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const {
float pixel_size = get_pixel_size(); float pixel_size = get_pixel_size();
Vector2 vertices[4] = { Vector2 vertices[4] = {
(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size, (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
(final_rect.position + final_rect.size) * pixel_size, (final_rect.position + final_rect.size) * pixel_size,
(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size, (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
@ -313,6 +316,9 @@ void SpriteBase3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_rect"), &SpriteBase3D::get_item_rect); ClassDB::bind_method(D_METHOD("get_item_rect"), &SpriteBase3D::get_item_rect);
ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &SpriteBase3D::generate_triangle_mesh); ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &SpriteBase3D::generate_triangle_mesh);
ClassDB::bind_method(D_METHOD("_queue_update"), &SpriteBase3D::_queue_update);
ClassDB::bind_method(D_METHOD("_im_update"), &SpriteBase3D::_im_update);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h");
@ -343,21 +349,89 @@ SpriteBase3D::SpriteBase3D() {
flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED; flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED;
} }
immediate = RenderingServer::get_singleton()->immediate_create(); material = RenderingServer::get_singleton()->material_create();
set_base(immediate); // Set defaults for material, names need to match up those in StandardMaterial3D
RS::get_singleton()->material_set_param(material, "albedo", Color(1, 1, 1, 1));
RS::get_singleton()->material_set_param(material, "specular", 0.5);
RS::get_singleton()->material_set_param(material, "metallic", 0.0);
RS::get_singleton()->material_set_param(material, "roughness", 1.0);
RS::get_singleton()->material_set_param(material, "uv1_offset", Vector3(0, 0, 0));
RS::get_singleton()->material_set_param(material, "uv1_scale", Vector3(1, 1, 1));
RS::get_singleton()->material_set_param(material, "uv2_offset", Vector3(0, 0, 0));
RS::get_singleton()->material_set_param(material, "uv2_scale", Vector3(1, 1, 1));
RS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.98);
mesh = RenderingServer::get_singleton()->mesh_create();
PackedVector3Array mesh_vertices;
PackedVector3Array mesh_normals;
PackedFloat32Array mesh_tangents;
PackedColorArray mesh_colors;
PackedVector2Array mesh_uvs;
PackedInt32Array indices;
mesh_vertices.resize(4);
mesh_normals.resize(4);
mesh_tangents.resize(16);
mesh_colors.resize(4);
mesh_uvs.resize(4);
// create basic mesh and store format information
for (int i = 0; i < 4; i++) {
mesh_normals.write[i] = Vector3(0.0, 0.0, 0.0);
mesh_tangents.write[i * 4 + 0] = 0.0;
mesh_tangents.write[i * 4 + 1] = 0.0;
mesh_tangents.write[i * 4 + 2] = 0.0;
mesh_tangents.write[i * 4 + 3] = 0.0;
mesh_colors.write[i] = Color(1.0, 1.0, 1.0, 1.0);
mesh_uvs.write[i] = Vector2(0.0, 0.0);
mesh_vertices.write[i] = Vector3(0.0, 0.0, 0.0);
}
indices.resize(6);
indices.write[0] = 0;
indices.write[1] = 1;
indices.write[2] = 2;
indices.write[3] = 0;
indices.write[4] = 2;
indices.write[5] = 3;
Array mesh_array;
mesh_array.resize(RS::ARRAY_MAX);
mesh_array[RS::ARRAY_VERTEX] = mesh_vertices;
mesh_array[RS::ARRAY_NORMAL] = mesh_normals;
mesh_array[RS::ARRAY_TANGENT] = mesh_tangents;
mesh_array[RS::ARRAY_COLOR] = mesh_colors;
mesh_array[RS::ARRAY_TEX_UV] = mesh_uvs;
mesh_array[RS::ARRAY_INDEX] = indices;
RS::SurfaceData sd;
RS::get_singleton()->mesh_create_surface_data_from_arrays(&sd, RS::PRIMITIVE_TRIANGLES, mesh_array);
mesh_surface_format = sd.format;
vertex_buffer = sd.vertex_data;
attribute_buffer = sd.attribute_data;
sd.material = material;
RS::get_singleton()->mesh_surface_make_offsets_from_format(sd.format, sd.vertex_count, sd.index_count, mesh_surface_offsets, vertex_stride, attrib_stride, skin_stride);
RS::get_singleton()->mesh_add_surface(mesh, sd);
set_base(mesh);
} }
SpriteBase3D::~SpriteBase3D() { SpriteBase3D::~SpriteBase3D() {
RenderingServer::get_singleton()->free(immediate); RenderingServer::get_singleton()->free(mesh);
RenderingServer::get_singleton()->free(material);
} }
/////////////////////////////////////////// ///////////////////////////////////////////
void Sprite3D::_draw() { void Sprite3D::_draw() {
RID immediate = get_immediate(); if (get_base() != get_mesh()) {
set_base(get_mesh());
RS::get_singleton()->immediate_clear(immediate); }
if (!texture.is_valid()) { if (!texture.is_valid()) {
set_base(RID());
return; return;
} }
Vector2 tsize = texture->get_size(); Vector2 tsize = texture->get_size();
@ -366,7 +440,7 @@ void Sprite3D::_draw() {
} }
Rect2 base_rect; Rect2 base_rect;
if (region_enabled) { if (region) {
base_rect = region_rect; base_rect = region_rect;
} else { } else {
base_rect = Rect2(0, 0, texture->get_width(), texture->get_height()); base_rect = Rect2(0, 0, texture->get_width(), texture->get_height());
@ -399,6 +473,7 @@ void Sprite3D::_draw() {
float pixel_size = get_pixel_size(); float pixel_size = get_pixel_size();
Vector2 vertices[4] = { Vector2 vertices[4] = {
(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size, (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
(final_rect.position + final_rect.size) * pixel_size, (final_rect.position + final_rect.size) * pixel_size,
(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size, (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
@ -426,6 +501,7 @@ void Sprite3D::_draw() {
SWAP(uvs[0], uvs[1]); SWAP(uvs[0], uvs[1]);
SWAP(uvs[2], uvs[3]); SWAP(uvs[2], uvs[3]);
} }
if (is_flipped_v()) { if (is_flipped_v()) {
SWAP(uvs[0], uvs[3]); SWAP(uvs[0], uvs[3]);
SWAP(uvs[1], uvs[2]); SWAP(uvs[1], uvs[2]);
@ -442,11 +518,6 @@ void Sprite3D::_draw() {
tangent = Plane(1, 0, 0, 1); tangent = Plane(1, 0, 0, 1);
} }
RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y);
RS::get_singleton()->immediate_set_material(immediate, mat);
RS::get_singleton()->immediate_begin(immediate, RS::PRIMITIVE_TRIANGLES, texture->get_rid());
int x_axis = ((axis + 1) % 3); int x_axis = ((axis + 1) % 3);
int y_axis = ((axis + 2) % 3); int y_axis = ((axis + 2) % 3);
@ -466,31 +537,80 @@ void Sprite3D::_draw() {
AABB aabb; AABB aabb;
for (int i = 0; i < 6; i++) { // Everything except position and UV is compressed
static const int index[6] = { 0, 1, 2, 0, 2, 3 }; uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
RS::get_singleton()->immediate_normal(immediate, normal); uint32_t v_normal;
RS::get_singleton()->immediate_tangent(immediate, tangent); {
RS::get_singleton()->immediate_color(immediate, color); Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
RS::get_singleton()->immediate_uv(immediate, uvs[index[i]]);
uint32_t value = 0;
value |= CLAMP(int(n.x * 1023.0), 0, 1023);
value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10;
value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20;
v_normal = value;
}
uint32_t v_tangent;
{
Plane t = tangent;
uint32_t value = 0;
value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023);
value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10;
value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20;
if (t.d > 0) {
value |= 3 << 30;
}
v_tangent = value;
}
uint16_t v_color[4] = {
Math::make_half_float(color.r),
Math::make_half_float(color.g),
Math::make_half_float(color.b),
Math::make_half_float(color.a),
};
for (int i = 0; i < 4; i++) {
Vector3 vtx; Vector3 vtx;
vtx[x_axis] = vertices[index[i]][0]; vtx[x_axis] = vertices[i][0];
vtx[y_axis] = vertices[index[i]][1]; vtx[y_axis] = vertices[i][1];
RS::get_singleton()->immediate_vertex(immediate, vtx);
if (i == 0) { if (i == 0) {
aabb.position = vtx; aabb.position = vtx;
aabb.size = Vector3(); aabb.size = Vector3();
} else { } else {
aabb.expand_to(vtx); aabb.expand_to(vtx);
} }
}
set_aabb(aabb);
RS::get_singleton()->immediate_end(immediate);
}
void Sprite3D::_texture_changed() { float v_uv[2] = { uvs[i].x, uvs[i].y };
_queue_update(); memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_TEX_UV]], v_uv, 8);
float v_vertex[3] = { vtx.x, vtx.y, vtx.z };
memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3);
memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_NORMAL]], &v_normal, 4);
memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_TANGENT]], &v_tangent, 4);
memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_COLOR]], v_color, 8);
}
RID mesh = get_mesh();
RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb);
set_aabb(aabb);
RID shader_rid;
StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, &shader_rid);
if (last_shader != shader_rid) {
RS::get_singleton()->material_set_shader(get_material(), shader_rid);
last_shader = shader_rid;
}
if (last_texture != texture->get_rid()) {
RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid());
last_texture = texture->get_rid();
}
} }
void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) { void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
@ -498,38 +618,36 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
return; return;
} }
if (texture.is_valid()) { if (texture.is_valid()) {
texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite3D::_texture_changed)); texture->disconnect(CoreStringNames::get_singleton()->changed, Callable(this, "_queue_update"));
} }
texture = p_texture; texture = p_texture;
if (texture.is_valid()) { if (texture.is_valid()) {
texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite3D::_texture_changed)); texture->connect(CoreStringNames::get_singleton()->changed, Callable(this, "_queue_update"));
} }
_queue_update(); _queue_update();
emit_signal(SceneStringNames::get_singleton()->texture_changed);
} }
Ref<Texture2D> Sprite3D::get_texture() const { Ref<Texture2D> Sprite3D::get_texture() const {
return texture; return texture;
} }
void Sprite3D::set_region_enabled(bool p_region_enabled) { void Sprite3D::set_region_enabled(bool p_region) {
if (p_region_enabled == region_enabled) { if (p_region == region) {
return; return;
} }
region_enabled = p_region_enabled; region = p_region;
_queue_update(); _queue_update();
notify_property_list_changed();
} }
bool Sprite3D::is_region_enabled() const { bool Sprite3D::is_region_enabled() const {
return region_enabled; return region;
} }
void Sprite3D::set_region_rect(const Rect2 &p_region_rect) { void Sprite3D::set_region_rect(const Rect2 &p_region_rect) {
bool changed = region_rect != p_region_rect; bool changed = region_rect != p_region_rect;
region_rect = p_region_rect; region_rect = p_region_rect;
if (region_enabled && changed) { if (region && changed) {
_queue_update(); _queue_update();
} }
} }
@ -596,7 +714,7 @@ Rect2 Sprite3D::get_item_rect() const {
Size2i s; Size2i s;
if (region_enabled) { if (region) {
s = region_rect.size; s = region_rect.size;
} else { } else {
s = texture->get_size(); s = texture->get_size();
@ -625,10 +743,6 @@ void Sprite3D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame_coords") { if (property.name == "frame_coords") {
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS; property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
} }
if (!region_enabled && property.name == "region_rect") {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
} }
void Sprite3D::_bind_methods() { void Sprite3D::_bind_methods() {
@ -653,32 +767,28 @@ void Sprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite3D::set_hframes); ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite3D::set_hframes);
ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite3D::get_hframes); ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite3D::get_hframes);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
ADD_GROUP("Animation", ""); ADD_GROUP("Animation", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_"); ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("frame_changed"));
ADD_SIGNAL(MethodInfo("texture_changed"));
} }
Sprite3D::Sprite3D() { Sprite3D::Sprite3D() {
region_enabled = false;
frame = 0;
vframes = 1;
hframes = 1;
} }
//////////////////////////////////////// ////////////////////////////////////////
void AnimatedSprite3D::_draw() { void AnimatedSprite3D::_draw() {
RID immediate = get_immediate(); if (get_base() != get_mesh()) {
RS::get_singleton()->immediate_clear(immediate); set_base(get_mesh());
}
if (frames.is_null()) { if (frames.is_null()) {
return; return;
@ -694,7 +804,8 @@ void AnimatedSprite3D::_draw() {
Ref<Texture2D> texture = frames->get_frame(animation, frame); Ref<Texture2D> texture = frames->get_frame(animation, frame);
if (!texture.is_valid()) { if (!texture.is_valid()) {
return; //no texture no life set_base(RID());
return; //no texuture no life
} }
Vector2 tsize = texture->get_size(); Vector2 tsize = texture->get_size();
if (tsize.x == 0 || tsize.y == 0) { if (tsize.x == 0 || tsize.y == 0) {
@ -729,6 +840,7 @@ void AnimatedSprite3D::_draw() {
float pixel_size = get_pixel_size(); float pixel_size = get_pixel_size();
Vector2 vertices[4] = { Vector2 vertices[4] = {
(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size, (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
(final_rect.position + final_rect.size) * pixel_size, (final_rect.position + final_rect.size) * pixel_size,
(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size, (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
@ -772,12 +884,6 @@ void AnimatedSprite3D::_draw() {
tangent = Plane(1, 0, 0, -1); tangent = Plane(1, 0, 0, -1);
} }
RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y);
RS::get_singleton()->immediate_set_material(immediate, mat);
RS::get_singleton()->immediate_begin(immediate, RS::PRIMITIVE_TRIANGLES, texture->get_rid());
int x_axis = ((axis + 1) % 3); int x_axis = ((axis + 1) % 3);
int y_axis = ((axis + 2) % 3); int y_axis = ((axis + 2) % 3);
@ -797,30 +903,79 @@ void AnimatedSprite3D::_draw() {
AABB aabb; AABB aabb;
for (int i = 0; i < 6; i++) { // Everything except position and UV is compressed
static const int indices[6] = { uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
0, 1, 2, uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
0, 2, 3
uint32_t v_normal;
{
Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
uint32_t value = 0;
value |= CLAMP(int(n.x * 1023.0), 0, 1023);
value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10;
value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20;
v_normal = value;
}
uint32_t v_tangent;
{
Plane t = tangent;
uint32_t value = 0;
value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023);
value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10;
value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20;
if (t.d > 0) {
value |= 3 << 30;
}
v_tangent = value;
}
uint16_t v_color[4] = {
Math::make_half_float(color.r),
Math::make_half_float(color.g),
Math::make_half_float(color.b),
Math::make_half_float(color.a),
}; };
RS::get_singleton()->immediate_normal(immediate, normal); for (int i = 0; i < 4; i++) {
RS::get_singleton()->immediate_tangent(immediate, tangent);
RS::get_singleton()->immediate_color(immediate, color);
RS::get_singleton()->immediate_uv(immediate, uvs[indices[i]]);
Vector3 vtx; Vector3 vtx;
vtx[x_axis] = vertices[indices[i]][0]; vtx[x_axis] = vertices[i][0];
vtx[y_axis] = vertices[indices[i]][1]; vtx[y_axis] = vertices[i][1];
RS::get_singleton()->immediate_vertex(immediate, vtx);
if (i == 0) { if (i == 0) {
aabb.position = vtx; aabb.position = vtx;
aabb.size = Vector3(); aabb.size = Vector3();
} else { } else {
aabb.expand_to(vtx); aabb.expand_to(vtx);
} }
float v_uv[2] = { uvs[i].x, uvs[i].y };
memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_TEX_UV]], v_uv, 8);
float v_vertex[3] = { vtx.x, vtx.y, vtx.z };
memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3);
memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_NORMAL]], &v_normal, 4);
memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_TANGENT]], &v_tangent, 4);
memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_COLOR]], v_color, 8);
} }
RID mesh = get_mesh();
RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb);
set_aabb(aabb); set_aabb(aabb);
RS::get_singleton()->immediate_end(immediate);
RID shader_rid;
StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, &shader_rid);
if (last_shader != shader_rid) {
RS::get_singleton()->material_set_shader(get_material(), shader_rid);
last_shader = shader_rid;
}
if (last_texture != texture->get_rid()) {
RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid());
last_texture = texture->get_rid();
}
} }
void AnimatedSprite3D::_validate_property(PropertyInfo &property) const { void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
@ -914,11 +1069,11 @@ void AnimatedSprite3D::_notification(int p_what) {
void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
if (frames.is_valid()) { if (frames.is_valid()) {
frames->disconnect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed)); frames->disconnect("changed", Callable(this, "_res_changed"));
} }
frames = p_frames; frames = p_frames;
if (frames.is_valid()) { if (frames.is_valid()) {
frames->connect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed)); frames->connect("changed", Callable(this, "_res_changed"));
} }
if (!frames.is_valid()) { if (!frames.is_valid()) {
@ -944,10 +1099,9 @@ void AnimatedSprite3D::set_frame(int p_frame) {
if (frames->has_animation(animation)) { if (frames->has_animation(animation)) {
int limit = frames->get_frame_count(animation); int limit = frames->get_frame_count(animation);
if (p_frame >= limit) { if (p_frame >= limit)
p_frame = limit - 1; p_frame = limit - 1;
} }
}
if (p_frame < 0) { if (p_frame < 0) {
p_frame = 0; p_frame = 0;
@ -960,7 +1114,6 @@ void AnimatedSprite3D::set_frame(int p_frame) {
frame = p_frame; frame = p_frame;
_reset_timeout(); _reset_timeout();
_queue_update(); _queue_update();
emit_signal(SceneStringNames::get_singleton()->frame_changed); emit_signal(SceneStringNames::get_singleton()->frame_changed);
} }
@ -1061,8 +1214,7 @@ StringName AnimatedSprite3D::get_animation() const {
} }
TypedArray<String> AnimatedSprite3D::get_configuration_warnings() const { TypedArray<String> AnimatedSprite3D::get_configuration_warnings() const {
TypedArray<String> warnings = Node::get_configuration_warnings(); TypedArray<String> warnings = SpriteBase3D::get_configuration_warnings();
if (frames.is_null()) { if (frames.is_null()) {
warnings.push_back(TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames.")); warnings.push_back(TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames."));
} }
@ -1087,11 +1239,13 @@ void AnimatedSprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite3D::set_frame); ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite3D::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame); ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame);
ClassDB::bind_method(D_METHOD("_res_changed"), &AnimatedSprite3D::_res_changed);
ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("frame_changed"));
ADD_SIGNAL(MethodInfo("animation_finished")); ADD_SIGNAL(MethodInfo("animation_finished"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing");
} }

View File

@ -31,8 +31,8 @@
#ifndef SPRITE_3D_H #ifndef SPRITE_3D_H
#define SPRITE_3D_H #define SPRITE_3D_H
#include "scene/2d/animated_sprite_2d.h"
#include "scene/3d/visual_instance_3d.h" #include "scene/3d/visual_instance_3d.h"
#include "scene/resources/sprite_frames.h"
class SpriteBase3D : public GeometryInstance3D { class SpriteBase3D : public GeometryInstance3D {
GDCLASS(SpriteBase3D, GeometryInstance3D); GDCLASS(SpriteBase3D, GeometryInstance3D);
@ -75,9 +75,10 @@ private:
float pixel_size = 0.01; float pixel_size = 0.01;
AABB aabb; AABB aabb;
RID immediate; RID mesh;
RID material;
bool flags[FLAG_MAX]; bool flags[FLAG_MAX] = {};
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED; AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
bool pending_update = false; bool pending_update = false;
@ -91,7 +92,17 @@ protected:
static void _bind_methods(); static void _bind_methods();
virtual void _draw() = 0; virtual void _draw() = 0;
_FORCE_INLINE_ void set_aabb(const AABB &p_aabb) { aabb = p_aabb; } _FORCE_INLINE_ void set_aabb(const AABB &p_aabb) { aabb = p_aabb; }
_FORCE_INLINE_ RID &get_immediate() { return immediate; } _FORCE_INLINE_ RID &get_mesh() { return mesh; }
_FORCE_INLINE_ RID &get_material() { return material; }
uint32_t mesh_surface_offsets[RS::ARRAY_MAX];
PackedByteArray vertex_buffer;
PackedByteArray attribute_buffer;
uint32_t vertex_stride;
uint32_t attrib_stride;
uint32_t skin_stride;
uint32_t mesh_surface_format;
void _queue_update(); void _queue_update();
public: public:
@ -107,7 +118,7 @@ public:
void set_flip_v(bool p_flip); void set_flip_v(bool p_flip);
bool is_flipped_v() const; bool is_flipped_v() const;
void set_region_enabled(bool p_region_enabled); void set_region_enabled(bool p_region);
bool is_region_enabled() const; bool is_region_enabled() const;
void set_region_rect(const Rect2 &p_region_rect); void set_region_rect(const Rect2 &p_region_rect);
@ -147,15 +158,16 @@ class Sprite3D : public SpriteBase3D {
GDCLASS(Sprite3D, SpriteBase3D); GDCLASS(Sprite3D, SpriteBase3D);
Ref<Texture2D> texture; Ref<Texture2D> texture;
bool region_enabled; bool region = false;
Rect2 region_rect; Rect2 region_rect;
int frame; int frame = 0;
int vframes; int vframes = 1;
int hframes; int hframes = 1;
void _texture_changed(); RID last_shader;
RID last_texture;
protected: protected:
virtual void _draw() override; virtual void _draw() override;
@ -167,7 +179,7 @@ public:
void set_texture(const Ref<Texture2D> &p_texture); void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const; Ref<Texture2D> get_texture() const;
void set_region_enabled(bool p_region_enabled); void set_region_enabled(bool p_region);
bool is_region_enabled() const; bool is_region_enabled() const;
void set_region_rect(const Rect2 &p_region_rect); void set_region_rect(const Rect2 &p_region_rect);
@ -199,14 +211,9 @@ class AnimatedSprite3D : public SpriteBase3D {
StringName animation = "default"; StringName animation = "default";
int frame = 0; int frame = 0;
bool centered = true; bool centered = false;
float timeout = 0.0; float timeout = 0;
bool hflip = true;
bool vflip = true;
Color modulate;
void _res_changed(); void _res_changed();
@ -214,6 +221,9 @@ class AnimatedSprite3D : public SpriteBase3D {
void _set_playing(bool p_playing); void _set_playing(bool p_playing);
bool _is_playing() const; bool _is_playing() const;
RID last_shader;
RID last_texture;
protected: protected:
virtual void _draw() override; virtual void _draw() override;
static void _bind_methods(); static void _bind_methods();
@ -236,10 +246,11 @@ public:
virtual Rect2 get_item_rect() const override; virtual Rect2 get_item_rect() const override;
TypedArray<String> get_configuration_warnings() const override; virtual TypedArray<String> get_configuration_warnings() const override;
AnimatedSprite3D(); AnimatedSprite3D();
}; };
VARIANT_ENUM_CAST(SpriteBase3D::DrawFlags); VARIANT_ENUM_CAST(SpriteBase3D::DrawFlags);
VARIANT_ENUM_CAST(SpriteBase3D::AlphaCutMode); VARIANT_ENUM_CAST(SpriteBase3D::AlphaCutMode);
#endif // SPRITE_3D_H #endif // SPRITE_3D_H

View File

@ -77,7 +77,7 @@ bool RootMotionView::get_zero_y() const {
void RootMotionView::_notification(int p_what) { void RootMotionView::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) { if (p_what == NOTIFICATION_ENTER_TREE) {
RS::get_singleton()->immediate_set_material(immediate, StandardMaterial3D::get_material_rid_for_2d(false, true, false, false, false)); immediate_material = StandardMaterial3D::get_material_for_2d(false, true, false, false, false);
first = true; first = true;
} }
@ -119,11 +119,12 @@ void RootMotionView::_notification(int p_what) {
} }
accumulated.origin.z = Math::fposmod(accumulated.origin.z, cell_size); accumulated.origin.z = Math::fposmod(accumulated.origin.z, cell_size);
RS::get_singleton()->immediate_clear(immediate); immediate->clear_surfaces();
int cells_in_radius = int((radius / cell_size) + 1.0); int cells_in_radius = int((radius / cell_size) + 1.0);
RS::get_singleton()->immediate_begin(immediate, RS::PRIMITIVE_LINES); immediate->surface_begin(Mesh::PRIMITIVE_LINES, immediate_material);
for (int i = -cells_in_radius; i < cells_in_radius; i++) { for (int i = -cells_in_radius; i < cells_in_radius; i++) {
for (int j = -cells_in_radius; j < cells_in_radius; j++) { for (int j = -cells_in_radius; j < cells_in_radius; j++) {
Vector3 from(i * cell_size, 0, j * cell_size); Vector3 from(i * cell_size, 0, j * cell_size);
@ -138,21 +139,21 @@ void RootMotionView::_notification(int p_what) {
c_i.a *= MAX(0, 1.0 - from_i.length() / radius); c_i.a *= MAX(0, 1.0 - from_i.length() / radius);
c_j.a *= MAX(0, 1.0 - from_j.length() / radius); c_j.a *= MAX(0, 1.0 - from_j.length() / radius);
RS::get_singleton()->immediate_color(immediate, c); immediate->surface_set_color(c);
RS::get_singleton()->immediate_vertex(immediate, from); immediate->surface_add_vertex(from);
RS::get_singleton()->immediate_color(immediate, c_i); immediate->surface_set_color(c_i);
RS::get_singleton()->immediate_vertex(immediate, from_i); immediate->surface_add_vertex(from_i);
RS::get_singleton()->immediate_color(immediate, c); immediate->surface_set_color(c);
RS::get_singleton()->immediate_vertex(immediate, from); immediate->surface_add_vertex(from);
RS::get_singleton()->immediate_color(immediate, c_j); immediate->surface_set_color(c_j);
RS::get_singleton()->immediate_vertex(immediate, from_j); immediate->surface_add_vertex(from_j);
} }
} }
RS::get_singleton()->immediate_end(immediate); immediate->surface_end();
} }
} }
@ -188,12 +189,13 @@ void RootMotionView::_bind_methods() {
} }
RootMotionView::RootMotionView() { RootMotionView::RootMotionView() {
if (Engine::get_singleton()->is_editor_hint()) {
set_process_internal(true); set_process_internal(true);
immediate = RenderingServer::get_singleton()->immediate_create(); }
set_base(immediate); immediate.instantiate();
set_base(immediate->get_rid());
} }
RootMotionView::~RootMotionView() { RootMotionView::~RootMotionView() {
set_base(RID()); set_base(RID());
RenderingServer::get_singleton()->free(immediate);
} }

View File

@ -32,12 +32,12 @@
#define ROOT_MOTION_VIEW_H #define ROOT_MOTION_VIEW_H
#include "scene/3d/visual_instance_3d.h" #include "scene/3d/visual_instance_3d.h"
#include "scene/resources/immediate_mesh.h"
class RootMotionView : public VisualInstance3D { class RootMotionView : public VisualInstance3D {
GDCLASS(RootMotionView, VisualInstance3D); GDCLASS(RootMotionView, VisualInstance3D);
public: public:
RID immediate; Ref<ImmediateMesh> immediate;
NodePath path; NodePath path;
float cell_size = 1.0; float cell_size = 1.0;
float radius = 10.0; float radius = 10.0;
@ -46,6 +46,8 @@ public:
bool first = true; bool first = true;
bool zero_y = true; bool zero_y = true;
Ref<Material> immediate_material;
Transform3D accumulated; Transform3D accumulated;
private: private:

View File

@ -147,6 +147,7 @@
#include "scene/resources/font.h" #include "scene/resources/font.h"
#include "scene/resources/gradient.h" #include "scene/resources/gradient.h"
#include "scene/resources/height_map_shape_3d.h" #include "scene/resources/height_map_shape_3d.h"
#include "scene/resources/immediate_mesh.h"
#include "scene/resources/line_shape_2d.h" #include "scene/resources/line_shape_2d.h"
#include "scene/resources/material.h" #include "scene/resources/material.h"
#include "scene/resources/mesh.h" #include "scene/resources/mesh.h"
@ -204,7 +205,6 @@
#include "scene/3d/decal.h" #include "scene/3d/decal.h"
#include "scene/3d/gpu_particles_3d.h" #include "scene/3d/gpu_particles_3d.h"
#include "scene/3d/gpu_particles_collision_3d.h" #include "scene/3d/gpu_particles_collision_3d.h"
#include "scene/3d/immediate_geometry_3d.h"
#include "scene/3d/light_3d.h" #include "scene/3d/light_3d.h"
#include "scene/3d/lightmap_gi.h" #include "scene/3d/lightmap_gi.h"
#include "scene/3d/lightmap_probe.h" #include "scene/3d/lightmap_probe.h"
@ -459,7 +459,6 @@ void register_scene_types() {
ClassDB::register_class<MeshInstance3D>(); ClassDB::register_class<MeshInstance3D>();
ClassDB::register_class<OccluderInstance3D>(); ClassDB::register_class<OccluderInstance3D>();
ClassDB::register_class<Occluder3D>(); ClassDB::register_class<Occluder3D>();
ClassDB::register_class<ImmediateGeometry3D>();
ClassDB::register_virtual_class<SpriteBase3D>(); ClassDB::register_virtual_class<SpriteBase3D>();
ClassDB::register_class<Sprite3D>(); ClassDB::register_class<Sprite3D>();
ClassDB::register_class<AnimatedSprite3D>(); ClassDB::register_class<AnimatedSprite3D>();
@ -718,6 +717,7 @@ void register_scene_types() {
ClassDB::register_virtual_class<Mesh>(); ClassDB::register_virtual_class<Mesh>();
ClassDB::register_class<ArrayMesh>(); ClassDB::register_class<ArrayMesh>();
ClassDB::register_class<ImmediateMesh>();
ClassDB::register_class<MultiMesh>(); ClassDB::register_class<MultiMesh>();
ClassDB::register_class<SurfaceTool>(); ClassDB::register_class<SurfaceTool>();
ClassDB::register_class<MeshDataTool>(); ClassDB::register_class<MeshDataTool>();

View File

@ -0,0 +1,416 @@
/*************************************************************************/
/* immediate_mesh.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "immediate_mesh.h"
void ImmediateMesh::surface_begin(PrimitiveType p_primitive, const Ref<Material> &p_material) {
ERR_FAIL_COND_MSG(surface_active, "Already creating a new surface.");
active_surface_data.primitive = p_primitive;
active_surface_data.material = p_material;
surface_active = true;
}
void ImmediateMesh::surface_set_color(const Color &p_color) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_colors) {
colors.resize(vertices.size());
for (uint32_t i = 0; i < colors.size(); i++) {
colors[i] = p_color;
}
uses_colors = true;
}
current_color = p_color;
}
void ImmediateMesh::surface_set_normal(const Vector3 &p_normal) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_normals) {
normals.resize(vertices.size());
for (uint32_t i = 0; i < normals.size(); i++) {
normals[i] = p_normal;
}
uses_normals = true;
}
current_normal = p_normal;
}
void ImmediateMesh::surface_set_tangent(const Plane &p_tangent) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_tangents) {
tangents.resize(vertices.size());
for (uint32_t i = 0; i < tangents.size(); i++) {
tangents[i] = p_tangent;
}
uses_tangents = true;
}
current_tangent = p_tangent;
}
void ImmediateMesh::surface_set_uv(const Vector2 &p_uv) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_uvs) {
uvs.resize(vertices.size());
for (uint32_t i = 0; i < uvs.size(); i++) {
uvs[i] = p_uv;
}
uses_uvs = true;
}
current_uv = p_uv;
}
void ImmediateMesh::surface_set_uv2(const Vector2 &p_uv2) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_uv2s) {
uv2s.resize(vertices.size());
for (uint32_t i = 0; i < uv2s.size(); i++) {
uv2s[i] = p_uv2;
}
uses_uv2s = true;
}
current_uv2 = p_uv2;
}
void ImmediateMesh::surface_add_vertex(const Vector3 &p_vertex) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
ERR_FAIL_COND_MSG(vertices.size() && active_surface_data.vertex_2d, "Can't mix 2D and 3D vertices in a surface.");
if (uses_colors) {
colors.push_back(current_color);
}
if (uses_normals) {
normals.push_back(current_normal);
}
if (uses_tangents) {
tangents.push_back(current_tangent);
}
if (uses_uvs) {
uvs.push_back(current_uv);
}
if (uses_uv2s) {
uv2s.push_back(current_uv2);
}
vertices.push_back(p_vertex);
}
void ImmediateMesh::surface_add_vertex_2d(const Vector2 &p_vertex) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
ERR_FAIL_COND_MSG(vertices.size() && !active_surface_data.vertex_2d, "Can't mix 2D and 3D vertices in a surface.");
if (uses_colors) {
colors.push_back(current_color);
}
if (uses_normals) {
normals.push_back(current_normal);
}
if (uses_tangents) {
tangents.push_back(current_tangent);
}
if (uses_uvs) {
uvs.push_back(current_uv);
}
if (uses_uv2s) {
uv2s.push_back(current_uv2);
}
Vector3 v(p_vertex.x, p_vertex.y, 0);
vertices.push_back(v);
active_surface_data.vertex_2d = true;
}
void ImmediateMesh::surface_end() {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
ERR_FAIL_COND_MSG(!vertices.size(), "No vertices were added, surface cant be created.");
uint32_t format = ARRAY_FORMAT_VERTEX;
uint32_t vertex_stride = 0;
if (active_surface_data.vertex_2d) {
format |= ARRAY_FLAG_USE_2D_VERTICES;
vertex_stride = sizeof(float) * 2;
} else {
vertex_stride = sizeof(float) * 3;
}
uint32_t normal_offset = 0;
if (uses_normals) {
format |= ARRAY_FORMAT_NORMAL;
normal_offset = vertex_stride;
vertex_stride += sizeof(uint32_t);
}
uint32_t tangent_offset = 0;
if (uses_tangents) {
format |= ARRAY_FORMAT_TANGENT;
tangent_offset += vertex_stride;
vertex_stride += sizeof(uint32_t);
}
AABB aabb;
{
surface_vertex_create_cache.resize(vertex_stride * vertices.size());
uint8_t *surface_vertex_ptr = surface_vertex_create_cache.ptrw();
for (uint32_t i = 0; i < vertices.size(); i++) {
{
float *vtx = (float *)&surface_vertex_ptr[i * vertex_stride];
vtx[0] = vertices[i].x;
vtx[1] = vertices[i].y;
if (!active_surface_data.vertex_2d) {
vtx[2] = vertices[i].z;
}
if (i == 0) {
aabb.position = vertices[i];
} else {
aabb.expand_to(vertices[i]);
}
}
if (uses_normals) {
uint32_t *normal = (uint32_t *)&surface_vertex_ptr[i * vertex_stride + normal_offset];
Vector3 n = normals[i] * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
uint32_t value = 0;
value |= CLAMP(int(n.x * 1023.0), 0, 1023);
value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10;
value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20;
*normal = value;
}
if (uses_tangents) {
uint32_t *tangent = (uint32_t *)&surface_vertex_ptr[i * vertex_stride + tangent_offset];
Plane t = tangents[i];
uint32_t value = 0;
value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023);
value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10;
value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20;
if (t.d > 0) {
value |= 3 << 30;
}
*tangent = value;
}
}
}
if (uses_colors || uses_uvs || uses_uv2s) {
uint32_t attribute_stride = 0;
if (uses_colors) {
format |= ARRAY_FORMAT_COLOR;
attribute_stride += sizeof(uint16_t) * 4;
}
uint32_t uv_offset = 0;
if (uses_uvs) {
format |= ARRAY_FORMAT_TEX_UV;
uv_offset = attribute_stride;
attribute_stride += sizeof(float) * 2;
}
uint32_t uv2_offset = 0;
if (uses_uv2s) {
format |= ARRAY_FORMAT_TEX_UV2;
uv2_offset = attribute_stride;
attribute_stride += sizeof(float) * 2;
}
surface_attribute_create_cache.resize(vertices.size() * attribute_stride);
uint8_t *surface_attribute_ptr = surface_attribute_create_cache.ptrw();
for (uint32_t i = 0; i < vertices.size(); i++) {
if (uses_colors) {
uint16_t *color16 = (uint16_t *)&surface_attribute_ptr[i * attribute_stride];
color16[0] = Math::make_half_float(colors[i].r);
color16[1] = Math::make_half_float(colors[i].g);
color16[2] = Math::make_half_float(colors[i].b);
color16[3] = Math::make_half_float(colors[i].a);
}
if (uses_uvs) {
float *uv = (float *)&surface_attribute_ptr[i * attribute_stride + uv_offset];
uv[0] = uvs[i].x;
uv[0] = uvs[i].y;
}
if (uses_uv2s) {
float *uv2 = (float *)&surface_attribute_ptr[i * attribute_stride + uv2_offset];
uv2[0] = uv2s[i].x;
uv2[0] = uv2s[i].y;
}
}
}
RS::SurfaceData sd;
sd.primitive = RS::PrimitiveType(active_surface_data.primitive);
sd.format = format;
sd.vertex_data = surface_vertex_create_cache;
if (uses_colors || uses_uvs || uses_uv2s) {
sd.attribute_data = surface_attribute_create_cache;
}
sd.vertex_count = vertices.size();
sd.aabb = aabb;
if (active_surface_data.material.is_valid()) {
sd.material = active_surface_data.material->get_rid();
}
RS::get_singleton()->mesh_add_surface(mesh, sd);
active_surface_data.aabb = aabb;
active_surface_data.format = format;
active_surface_data.array_len = vertices.size();
surfaces.push_back(active_surface_data);
colors.clear();
normals.clear();
tangents.clear();
uvs.clear();
uv2s.clear();
vertices.clear();
uses_colors = false;
uses_normals = false;
uses_tangents = false;
uses_uvs = false;
uses_uv2s = false;
surface_active = false;
}
void ImmediateMesh::clear_surfaces() {
RS::get_singleton()->mesh_clear(mesh);
surfaces.clear();
surface_active = false;
colors.clear();
normals.clear();
tangents.clear();
uvs.clear();
uv2s.clear();
vertices.clear();
uses_colors = false;
uses_normals = false;
uses_tangents = false;
uses_uvs = false;
uses_uv2s = false;
}
int ImmediateMesh::get_surface_count() const {
return surfaces.size();
}
int ImmediateMesh::surface_get_array_len(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, int(surfaces.size()), -1);
return surfaces[p_idx].array_len;
}
int ImmediateMesh::surface_get_array_index_len(int p_idx) const {
return 0;
}
bool ImmediateMesh::surface_is_softbody_friendly(int p_idx) const {
return false;
}
Array ImmediateMesh::surface_get_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, int(surfaces.size()), Array());
return RS::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
}
Array ImmediateMesh::surface_get_blend_shape_arrays(int p_surface) const {
return Array();
}
Dictionary ImmediateMesh::surface_get_lods(int p_surface) const {
return Dictionary();
}
uint32_t ImmediateMesh::surface_get_format(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, int(surfaces.size()), 0);
return surfaces[p_idx].format;
}
Mesh::PrimitiveType ImmediateMesh::surface_get_primitive_type(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, int(surfaces.size()), PRIMITIVE_MAX);
return surfaces[p_idx].primitive;
}
void ImmediateMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
ERR_FAIL_INDEX(p_idx, int(surfaces.size()));
surfaces[p_idx].material = p_material;
RID mat;
if (p_material.is_valid()) {
mat = p_material->get_rid();
}
RS::get_singleton()->mesh_surface_set_material(mesh, p_idx, mat);
}
Ref<Material> ImmediateMesh::surface_get_material(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, int(surfaces.size()), Ref<Material>());
return surfaces[p_idx].material;
}
int ImmediateMesh::get_blend_shape_count() const {
return 0;
}
StringName ImmediateMesh::get_blend_shape_name(int p_index) const {
return StringName();
}
void ImmediateMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
}
AABB ImmediateMesh::get_aabb() const {
AABB aabb;
for (uint32_t i = 0; i < surfaces.size(); i++) {
if (i == 0) {
aabb = surfaces[i].aabb;
} else {
aabb.merge(surfaces[i].aabb);
}
}
return aabb;
}
void ImmediateMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("surface_begin", "primitive", "material"), &ImmediateMesh::surface_begin, DEFVAL(Ref<Material>()));
ClassDB::bind_method(D_METHOD("surface_set_color", "color"), &ImmediateMesh::surface_set_color);
ClassDB::bind_method(D_METHOD("surface_set_normal", "normal"), &ImmediateMesh::surface_set_normal);
ClassDB::bind_method(D_METHOD("surface_set_tangent", "tangent"), &ImmediateMesh::surface_set_tangent);
ClassDB::bind_method(D_METHOD("surface_set_uv", "uv"), &ImmediateMesh::surface_set_uv);
ClassDB::bind_method(D_METHOD("surface_set_uv2", "uv2"), &ImmediateMesh::surface_set_uv2);
ClassDB::bind_method(D_METHOD("surface_add_vertex", "vertex"), &ImmediateMesh::surface_add_vertex);
ClassDB::bind_method(D_METHOD("surface_add_vertex_2d", "vertex"), &ImmediateMesh::surface_add_vertex_2d);
ClassDB::bind_method(D_METHOD("surface_end"), &ImmediateMesh::surface_end);
ClassDB::bind_method(D_METHOD("clear_surfaces"), &ImmediateMesh::clear_surfaces);
}
RID ImmediateMesh::get_rid() const {
return mesh;
}
ImmediateMesh::ImmediateMesh() {
mesh = RS::get_singleton()->mesh_create();
}
ImmediateMesh::~ImmediateMesh() {
RS::get_singleton()->free(mesh);
}

View File

@ -0,0 +1,117 @@
/*************************************************************************/
/* immediate_mesh.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef IMMEDIATE_MESH_H
#define IMMEDIATE_MESH_H
#include "core/templates/local_vector.h"
#include "scene/resources/mesh.h"
class ImmediateMesh : public Mesh {
GDCLASS(ImmediateMesh, Mesh)
RID mesh;
bool uses_colors = false;
bool uses_normals = false;
bool uses_tangents = false;
bool uses_uvs = false;
bool uses_uv2s = false;
Color current_color;
Vector3 current_normal;
Plane current_tangent;
Vector2 current_uv;
Vector2 current_uv2;
LocalVector<Color> colors;
LocalVector<Vector3> normals;
LocalVector<Plane> tangents;
LocalVector<Vector2> uvs;
LocalVector<Vector2> uv2s;
LocalVector<Vector3> vertices;
struct Surface {
PrimitiveType primitive;
Ref<Material> material;
bool vertex_2d = false;
int array_len = 0;
uint32_t format = 0;
AABB aabb;
};
LocalVector<Surface> surfaces;
bool surface_active = false;
Surface active_surface_data;
Vector<uint8_t> surface_vertex_create_cache;
Vector<uint8_t> surface_attribute_create_cache;
protected:
static void _bind_methods();
public:
void surface_begin(PrimitiveType p_primitive, const Ref<Material> &p_material = Ref<Material>());
void surface_set_color(const Color &p_color);
void surface_set_normal(const Vector3 &p_normal);
void surface_set_tangent(const Plane &p_tangent);
void surface_set_uv(const Vector2 &p_uv);
void surface_set_uv2(const Vector2 &p_uv2);
void surface_add_vertex(const Vector3 &p_vertex);
void surface_add_vertex_2d(const Vector2 &p_vertex);
void surface_end();
void clear_surfaces();
virtual int get_surface_count() const override;
virtual int surface_get_array_len(int p_idx) const override;
virtual int surface_get_array_index_len(int p_idx) const override;
virtual bool surface_is_softbody_friendly(int p_idx) const override;
virtual Array surface_get_arrays(int p_surface) const override;
virtual Array surface_get_blend_shape_arrays(int p_surface) const override;
virtual Dictionary surface_get_lods(int p_surface) const override;
virtual uint32_t surface_get_format(int p_idx) const override;
virtual PrimitiveType surface_get_primitive_type(int p_idx) const override;
virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) override;
virtual Ref<Material> surface_get_material(int p_idx) const override;
virtual int get_blend_shape_count() const override;
virtual StringName get_blend_shape_name(int p_index) const override;
virtual void set_blend_shape_name(int p_index, const StringName &p_name) override;
virtual AABB get_aabb() const override;
virtual RID get_rid() const override;
ImmediateMesh();
~ImmediateMesh();
};
#endif // IMMEDIATEMESH_H

View File

@ -2077,7 +2077,7 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel()
return refraction_texture_channel; return refraction_texture_channel;
} }
RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) { Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y, RID *r_shader_rid) {
int version = 0; int version = 0;
if (p_shaded) { if (p_shaded) {
version = 1; version = 1;
@ -2102,7 +2102,10 @@ RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, b
} }
if (materials_for_2d[version].is_valid()) { if (materials_for_2d[version].is_valid()) {
return materials_for_2d[version]->get_rid(); if (r_shader_rid) {
*r_shader_rid = materials_for_2d[version]->get_shader_rid();
}
return materials_for_2d[version];
} }
Ref<StandardMaterial3D> material; Ref<StandardMaterial3D> material;
@ -2120,7 +2123,11 @@ RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, b
materials_for_2d[version] = material; materials_for_2d[version] = material;
return materials_for_2d[version]->get_rid(); if (r_shader_rid) {
*r_shader_rid = materials_for_2d[version]->get_shader_rid();
}
return materials_for_2d[version];
} }
void BaseMaterial3D::set_on_top_of_alpha() { void BaseMaterial3D::set_on_top_of_alpha() {
@ -2189,6 +2196,8 @@ BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
} }
RID BaseMaterial3D::get_shader_rid() const { RID BaseMaterial3D::get_shader_rid() const {
MutexLock lock(material_mutex);
((BaseMaterial3D *)this)->_update_shader();
ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader; return shader_map[current_key].shader;
} }

View File

@ -738,7 +738,7 @@ public:
static void finish_shaders(); static void finish_shaders();
static void flush_changes(); static void flush_changes();
static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false); static Ref<Material> get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false, RID *r_shader_rid = nullptr);
virtual RID get_shader_rid() const override; virtual RID get_shader_rid() const override;

View File

@ -1335,9 +1335,21 @@ String ArrayMesh::surface_get_name(int p_idx) const {
return surfaces[p_idx].name; return surfaces[p_idx].name;
} }
void ArrayMesh::surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) { void ArrayMesh::surface_update_vertex_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
ERR_FAIL_INDEX(p_surface, surfaces.size()); ERR_FAIL_INDEX(p_surface, surfaces.size());
RS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data); RS::get_singleton()->mesh_surface_update_vertex_region(mesh, p_surface, p_offset, p_data);
emit_changed();
}
void ArrayMesh::surface_update_attribute_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
ERR_FAIL_INDEX(p_surface, surfaces.size());
RS::get_singleton()->mesh_surface_update_attribute_region(mesh, p_surface, p_offset, p_data);
emit_changed();
}
void ArrayMesh::surface_update_skin_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
ERR_FAIL_INDEX(p_surface, surfaces.size());
RS::get_singleton()->mesh_surface_update_skin_region(mesh, p_surface, p_offset, p_data);
emit_changed(); emit_changed();
} }
@ -1635,7 +1647,9 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0));
ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces); ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces);
ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region); ClassDB::bind_method(D_METHOD("surface_update_vertex_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_vertex_region);
ClassDB::bind_method(D_METHOD("surface_update_attribute_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_attribute_region);
ClassDB::bind_method(D_METHOD("surface_update_skin_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_skin_region);
ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len);
ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len); ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len);
ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format); ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format);

View File

@ -233,7 +233,9 @@ public:
void set_blend_shape_mode(BlendShapeMode p_mode); void set_blend_shape_mode(BlendShapeMode p_mode);
BlendShapeMode get_blend_shape_mode() const; BlendShapeMode get_blend_shape_mode() const;
void surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data); void surface_update_vertex_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data);
void surface_update_attribute_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data);
void surface_update_skin_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data);
int get_surface_count() const override; int get_surface_count() const override;

View File

@ -324,7 +324,9 @@ public:
void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {} void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {}
RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { return RS::BLEND_SHAPE_MODE_NORMALIZED; } RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { return RS::BLEND_SHAPE_MODE_NORMALIZED; }
void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {} void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {}
void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {}
void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {}
void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {} void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {}
RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); } RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); }
@ -365,23 +367,6 @@ public:
void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override {} void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override {}
int multimesh_get_visible_instances(RID p_multimesh) const override { return 0; } int multimesh_get_visible_instances(RID p_multimesh) const override { return 0; }
/* IMMEDIATE API */
RID immediate_allocate() override { return RID(); }
void immediate_initialize(RID p_rid) override {}
void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) override {}
void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) override {}
void immediate_normal(RID p_immediate, const Vector3 &p_normal) override {}
void immediate_tangent(RID p_immediate, const Plane &p_tangent) override {}
void immediate_color(RID p_immediate, const Color &p_color) override {}
void immediate_uv(RID p_immediate, const Vector2 &tex_uv) override {}
void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) override {}
void immediate_end(RID p_immediate) override {}
void immediate_clear(RID p_immediate) override {}
void immediate_set_material(RID p_immediate, RID p_material) override {}
RID immediate_get_material(RID p_immediate) const override { return RID(); }
AABB immediate_get_aabb(RID p_immediate) const override { return AABB(); }
/* SKELETON API */ /* SKELETON API */
RID skeleton_allocate() override { return RID(); } RID skeleton_allocate() override { return RID(); }

View File

@ -2655,7 +2655,7 @@ RS::BlendShapeMode RendererStorageRD::mesh_get_blend_shape_mode(RID p_mesh) cons
return mesh->blend_shape_mode; return mesh->blend_shape_mode;
} }
void RendererStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { void RendererStorageRD::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
Mesh *mesh = mesh_owner.getornull(p_mesh); Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh); ERR_FAIL_COND(!mesh);
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
@ -2666,6 +2666,30 @@ void RendererStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, in
RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->vertex_buffer, p_offset, data_size, r); RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->vertex_buffer, p_offset, data_size, r);
} }
void RendererStorageRD::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
ERR_FAIL_COND(p_data.size() == 0);
ERR_FAIL_COND(mesh->surfaces[p_surface]->attribute_buffer.is_null());
uint64_t data_size = p_data.size();
const uint8_t *r = p_data.ptr();
RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->attribute_buffer, p_offset, data_size, r);
}
void RendererStorageRD::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
ERR_FAIL_COND(p_data.size() == 0);
ERR_FAIL_COND(mesh->surfaces[p_surface]->skin_buffer.is_null());
uint64_t data_size = p_data.size();
const uint8_t *r = p_data.ptr();
RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->skin_buffer, p_offset, data_size, r);
}
void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
Mesh *mesh = mesh_owner.getornull(p_mesh); Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh); ERR_FAIL_COND(!mesh);

View File

@ -1457,7 +1457,9 @@ public:
virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode); virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode);
virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const; virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const;
virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data); virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data);
virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data);
virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data);
virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material); virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material);
virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const;
@ -1746,24 +1748,6 @@ public:
return multimesh->uniform_set_2d; return multimesh->uniform_set_2d;
} }
/* IMMEDIATE API */
RID immediate_allocate() { return RID(); }
void immediate_initialize(RID p_immediate) {}
virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {}
virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {}
virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) {}
virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) {}
virtual void immediate_color(RID p_immediate, const Color &p_color) {}
virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {}
virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {}
virtual void immediate_end(RID p_immediate) {}
virtual void immediate_clear(RID p_immediate) {}
virtual void immediate_set_material(RID p_immediate, RID p_material) {}
virtual RID immediate_get_material(RID p_immediate) const { return RID(); }
virtual AABB immediate_get_aabb(RID p_immediate) const { return AABB(); }
/* SKELETON API */ /* SKELETON API */
RID skeleton_allocate(); RID skeleton_allocate();

View File

@ -478,7 +478,6 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
switch (instance->base_type) { switch (instance->base_type) {
case RS::INSTANCE_MESH: case RS::INSTANCE_MESH:
case RS::INSTANCE_MULTIMESH: case RS::INSTANCE_MULTIMESH:
case RS::INSTANCE_IMMEDIATE:
case RS::INSTANCE_PARTICLES: { case RS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_free(geom->geometry_instance); scene_render->geometry_instance_free(geom->geometry_instance);
@ -590,7 +589,6 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
} break; } break;
case RS::INSTANCE_MESH: case RS::INSTANCE_MESH:
case RS::INSTANCE_MULTIMESH: case RS::INSTANCE_MULTIMESH:
case RS::INSTANCE_IMMEDIATE:
case RS::INSTANCE_PARTICLES: { case RS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = memnew(InstanceGeometryData); InstanceGeometryData *geom = memnew(InstanceGeometryData);
instance->base_data = geom; instance->base_data = geom;
@ -888,7 +886,7 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
} }
inline bool is_geometry_instance(RenderingServer::InstanceType p_type) { inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES || p_type == RS::INSTANCE_IMMEDIATE; return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES;
} }
void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
@ -1529,7 +1527,6 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
switch (p_instance->base_type) { switch (p_instance->base_type) {
case RS::INSTANCE_MESH: case RS::INSTANCE_MESH:
case RS::INSTANCE_MULTIMESH: case RS::INSTANCE_MULTIMESH:
case RS::INSTANCE_IMMEDIATE:
case RS::INSTANCE_PARTICLES: { case RS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
idata.instance_geometry = geom->geometry_instance; idata.instance_geometry = geom->geometry_instance;
@ -1747,14 +1744,6 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base); new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base);
} }
} break;
case RenderingServer::INSTANCE_IMMEDIATE: {
if (p_instance->custom_aabb) {
new_aabb = *p_instance->custom_aabb;
} else {
new_aabb = RSG::storage->immediate_get_aabb(p_instance->base);
}
} break; } break;
case RenderingServer::INSTANCE_PARTICLES: { case RenderingServer::INSTANCE_PARTICLES: {
if (p_instance->custom_aabb) { if (p_instance->custom_aabb) {
@ -3681,25 +3670,6 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
RSG::storage->base_update_dependency(mesh, &p_instance->dependency_tracker); RSG::storage->base_update_dependency(mesh, &p_instance->dependency_tracker);
} }
} else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) {
RID mat = RSG::storage->immediate_get_material(p_instance->base);
if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) {
can_cast_shadows = false;
}
if (mat.is_valid() && RSG::storage->material_is_animated(mat)) {
is_animated = true;
}
if (mat.is_valid()) {
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
}
if (mat.is_valid()) {
RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES) { } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
bool cast_shadows = false; bool cast_shadows = false;

View File

@ -230,7 +230,9 @@ public:
virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) = 0; virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) = 0;
virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0;
virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0; virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0;
virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0;
@ -288,24 +290,6 @@ public:
virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0;
/* IMMEDIATE API */
virtual RID immediate_allocate() = 0;
virtual void immediate_initialize(RID p_rid) = 0;
virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0;
virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0;
virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0;
virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) = 0;
virtual void immediate_color(RID p_immediate, const Color &p_color) = 0;
virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) = 0;
virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) = 0;
virtual void immediate_end(RID p_immediate) = 0;
virtual void immediate_clear(RID p_immediate) = 0;
virtual void immediate_set_material(RID p_immediate, RID p_material) = 0;
virtual RID immediate_get_material(RID p_immediate) const = 0;
virtual AABB immediate_get_aabb(RID p_immediate) const = 0;
/* SKELETON API */ /* SKELETON API */
virtual RID skeleton_allocate() = 0; virtual RID skeleton_allocate() = 0;

View File

@ -290,7 +290,9 @@ public:
FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode) FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode)
FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID)
FUNC4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &) FUNC4(mesh_surface_update_vertex_region, RID, int, int, const Vector<uint8_t> &)
FUNC4(mesh_surface_update_attribute_region, RID, int, int, const Vector<uint8_t> &)
FUNC4(mesh_surface_update_skin_region, RID, int, int, const Vector<uint8_t> &)
FUNC3(mesh_surface_set_material, RID, int, RID) FUNC3(mesh_surface_set_material, RID, int, RID)
FUNC2RC(RID, mesh_surface_get_material, RID, int) FUNC2RC(RID, mesh_surface_get_material, RID, int)
@ -333,21 +335,6 @@ public:
FUNC2(multimesh_set_visible_instances, RID, int) FUNC2(multimesh_set_visible_instances, RID, int)
FUNC1RC(int, multimesh_get_visible_instances, RID) FUNC1RC(int, multimesh_get_visible_instances, RID)
/* IMMEDIATE API */
FUNCRIDSPLIT(immediate)
FUNC3(immediate_begin, RID, PrimitiveType, RID)
FUNC2(immediate_vertex, RID, const Vector3 &)
FUNC2(immediate_normal, RID, const Vector3 &)
FUNC2(immediate_tangent, RID, const Plane &)
FUNC2(immediate_color, RID, const Color &)
FUNC2(immediate_uv, RID, const Vector2 &)
FUNC2(immediate_uv2, RID, const Vector2 &)
FUNC1(immediate_end, RID)
FUNC1(immediate_clear, RID)
FUNC2(immediate_set_material, RID, RID)
FUNC1RC(RID, immediate_get_material, RID)
/* SKELETON API */ /* SKELETON API */
FUNCRIDSPLIT(skeleton) FUNCRIDSPLIT(skeleton)

View File

@ -1482,7 +1482,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &RenderingServer::mesh_get_blend_shape_count); ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &RenderingServer::mesh_get_blend_shape_count);
ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_mode", "mesh", "mode"), &RenderingServer::mesh_set_blend_shape_mode); ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_mode", "mesh", "mode"), &RenderingServer::mesh_set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_mode", "mesh"), &RenderingServer::mesh_get_blend_shape_mode); ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_mode", "mesh"), &RenderingServer::mesh_get_blend_shape_mode);
ClassDB::bind_method(D_METHOD("mesh_surface_update_region", "mesh", "surface", "offset", "data"), &RenderingServer::mesh_surface_update_region);
ClassDB::bind_method(D_METHOD("mesh_surface_set_material", "mesh", "surface", "material"), &RenderingServer::mesh_surface_set_material); ClassDB::bind_method(D_METHOD("mesh_surface_set_material", "mesh", "surface", "material"), &RenderingServer::mesh_surface_set_material);
ClassDB::bind_method(D_METHOD("mesh_surface_get_material", "mesh", "surface"), &RenderingServer::mesh_surface_get_material); ClassDB::bind_method(D_METHOD("mesh_surface_get_material", "mesh", "surface"), &RenderingServer::mesh_surface_get_material);
ClassDB::bind_method(D_METHOD("mesh_surface_get_arrays", "mesh", "surface"), &RenderingServer::mesh_surface_get_arrays); ClassDB::bind_method(D_METHOD("mesh_surface_get_arrays", "mesh", "surface"), &RenderingServer::mesh_surface_get_arrays);
@ -1510,21 +1510,6 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("multimesh_get_visible_instances", "multimesh"), &RenderingServer::multimesh_get_visible_instances); ClassDB::bind_method(D_METHOD("multimesh_get_visible_instances", "multimesh"), &RenderingServer::multimesh_get_visible_instances);
ClassDB::bind_method(D_METHOD("multimesh_set_buffer", "multimesh", "buffer"), &RenderingServer::multimesh_set_buffer); ClassDB::bind_method(D_METHOD("multimesh_set_buffer", "multimesh", "buffer"), &RenderingServer::multimesh_set_buffer);
ClassDB::bind_method(D_METHOD("multimesh_get_buffer", "multimesh"), &RenderingServer::multimesh_get_buffer); ClassDB::bind_method(D_METHOD("multimesh_get_buffer", "multimesh"), &RenderingServer::multimesh_get_buffer);
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("immediate_create"), &RenderingServer::immediate_create);
ClassDB::bind_method(D_METHOD("immediate_begin", "immediate", "primitive", "texture"), &RenderingServer::immediate_begin, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("immediate_vertex", "immediate", "vertex"), &RenderingServer::immediate_vertex);
ClassDB::bind_method(D_METHOD("immediate_vertex_2d", "immediate", "vertex"), &RenderingServer::immediate_vertex_2d);
ClassDB::bind_method(D_METHOD("immediate_normal", "immediate", "normal"), &RenderingServer::immediate_normal);
ClassDB::bind_method(D_METHOD("immediate_tangent", "immediate", "tangent"), &RenderingServer::immediate_tangent);
ClassDB::bind_method(D_METHOD("immediate_color", "immediate", "color"), &RenderingServer::immediate_color);
ClassDB::bind_method(D_METHOD("immediate_uv", "immediate", "tex_uv"), &RenderingServer::immediate_uv);
ClassDB::bind_method(D_METHOD("immediate_uv2", "immediate", "tex_uv"), &RenderingServer::immediate_uv2);
ClassDB::bind_method(D_METHOD("immediate_end", "immediate"), &RenderingServer::immediate_end);
ClassDB::bind_method(D_METHOD("immediate_clear", "immediate"), &RenderingServer::immediate_clear);
ClassDB::bind_method(D_METHOD("immediate_set_material", "immediate", "material"), &RenderingServer::immediate_set_material);
ClassDB::bind_method(D_METHOD("immediate_get_material", "immediate"), &RenderingServer::immediate_get_material);
#endif
ClassDB::bind_method(D_METHOD("skeleton_create"), &RenderingServer::skeleton_create); ClassDB::bind_method(D_METHOD("skeleton_create"), &RenderingServer::skeleton_create);
ClassDB::bind_method(D_METHOD("skeleton_allocate_data", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate_data, DEFVAL(false)); ClassDB::bind_method(D_METHOD("skeleton_allocate_data", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate_data, DEFVAL(false));
@ -2113,7 +2098,6 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(INSTANCE_NONE); BIND_ENUM_CONSTANT(INSTANCE_NONE);
BIND_ENUM_CONSTANT(INSTANCE_MESH); BIND_ENUM_CONSTANT(INSTANCE_MESH);
BIND_ENUM_CONSTANT(INSTANCE_MULTIMESH); BIND_ENUM_CONSTANT(INSTANCE_MULTIMESH);
BIND_ENUM_CONSTANT(INSTANCE_IMMEDIATE);
BIND_ENUM_CONSTANT(INSTANCE_PARTICLES); BIND_ENUM_CONSTANT(INSTANCE_PARTICLES);
BIND_ENUM_CONSTANT(INSTANCE_PARTICLES_COLLISION); BIND_ENUM_CONSTANT(INSTANCE_PARTICLES_COLLISION);
BIND_ENUM_CONSTANT(INSTANCE_LIGHT); BIND_ENUM_CONSTANT(INSTANCE_LIGHT);
@ -2253,10 +2237,6 @@ void RenderingServer::mesh_add_surface_from_planes(RID p_mesh, const Vector<Plan
mesh_add_surface_from_mesh_data(p_mesh, mdata); mesh_add_surface_from_mesh_data(p_mesh, mdata);
} }
void RenderingServer::immediate_vertex_2d(RID p_immediate, const Vector2 &p_vertex) {
immediate_vertex(p_immediate, Vector3(p_vertex.x, p_vertex.y, 0));
}
RID RenderingServer::instance_create2(RID p_base, RID p_scenario) { RID RenderingServer::instance_create2(RID p_base, RID p_scenario) {
RID instance = instance_create(); RID instance = instance_create();
instance_set_base(instance, p_base); instance_set_base(instance, p_base);

View File

@ -342,7 +342,9 @@ public:
virtual void mesh_set_blend_shape_mode(RID p_mesh, BlendShapeMode p_mode) = 0; virtual void mesh_set_blend_shape_mode(RID p_mesh, BlendShapeMode p_mode) = 0;
virtual BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; virtual BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0;
virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0; virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0;
virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0;
@ -390,22 +392,6 @@ public:
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0; virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0; virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
/* IMMEDIATE API */
virtual RID immediate_create() = 0;
virtual void immediate_begin(RID p_immediate, PrimitiveType p_rimitive, RID p_texture = RID()) = 0;
virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0;
virtual void immediate_vertex_2d(RID p_immediate, const Vector2 &p_vertex);
virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0;
virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) = 0;
virtual void immediate_color(RID p_immediate, const Color &p_color) = 0;
virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) = 0;
virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) = 0;
virtual void immediate_end(RID p_immediate) = 0;
virtual void immediate_clear(RID p_immediate) = 0;
virtual void immediate_set_material(RID p_immediate, RID p_material) = 0;
virtual RID immediate_get_material(RID p_immediate) const = 0;
/* SKELETON API */ /* SKELETON API */
virtual RID skeleton_create() = 0; virtual RID skeleton_create() = 0;
@ -1146,7 +1132,6 @@ public:
INSTANCE_NONE, INSTANCE_NONE,
INSTANCE_MESH, INSTANCE_MESH,
INSTANCE_MULTIMESH, INSTANCE_MULTIMESH,
INSTANCE_IMMEDIATE,
INSTANCE_PARTICLES, INSTANCE_PARTICLES,
INSTANCE_PARTICLES_COLLISION, INSTANCE_PARTICLES_COLLISION,
INSTANCE_LIGHT, INSTANCE_LIGHT,
@ -1158,7 +1143,7 @@ public:
INSTANCE_VISIBLITY_NOTIFIER, INSTANCE_VISIBLITY_NOTIFIER,
INSTANCE_MAX, INSTANCE_MAX,
INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE) | (1 << INSTANCE_PARTICLES) INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_PARTICLES)
}; };
virtual RID instance_create2(RID p_base, RID p_scenario); virtual RID instance_create2(RID p_base, RID p_scenario);