2V2-e.2: Godot consumer of the 3D draw commands, offline screenshot
python_3d_surface.gd turns RenderGame's recorded draws into meshes under a camera read back from SetPerspective; textures come from the 40250 packs. GetFarClip and the CMapManager ctor ported verbatim. Until the environment is ported, lit draws with no light/ambient are shown unshaded (stand-in). script/python_game_render_test.sh runs system.py login -> select -> game against port_fake_login_server (or --live via MT_LIVE_*) and screenshots. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5bfa13c5cc
commit
1fe8a4b643
@@ -9,12 +9,18 @@
|
||||
// unit, which has to stay compilable next to godot-cpp.
|
||||
#include "platform/ScriptLib/PythonBoot.h"
|
||||
#include "platform/EterLib/UIRenderCommands.h"
|
||||
#include "platform/EterLib/RenderCommands3D.h"
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#include <godot_cpp/classes/image.hpp>
|
||||
#include <godot_cpp/variant/dictionary.hpp>
|
||||
#include <godot_cpp/variant/packed_byte_array.hpp>
|
||||
#include <godot_cpp/variant/packed_color_array.hpp>
|
||||
#include <godot_cpp/variant/packed_float32_array.hpp>
|
||||
#include <godot_cpp/variant/packed_int32_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector2_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector3_array.hpp>
|
||||
|
||||
using namespace godot;
|
||||
|
||||
@@ -117,6 +123,107 @@ Ref<Image> Metin2PythonHost::memory_texture(const String &name, int64_t known_re
|
||||
return Image::create_from_data(texture.width, texture.height, false, Image::FORMAT_RGBA8, rgba);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
PackedFloat32Array floats(const float *values, int count) {
|
||||
PackedFloat32Array out;
|
||||
out.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
out[i] = values[i];
|
||||
return out;
|
||||
}
|
||||
|
||||
Color argb_color(std::uint32_t argb) {
|
||||
return Color(((argb >> 16) & 255) / 255.0f, ((argb >> 8) & 255) / 255.0f, (argb & 255) / 255.0f,
|
||||
((argb >> 24) & 255) / 255.0f);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Array Metin2PythonHost::render3d_draws() {
|
||||
Array out;
|
||||
for (const Render3DDraw &draw : Render3DDraws()) {
|
||||
Dictionary item;
|
||||
item["world"] = floats(draw.world, 16);
|
||||
item["view"] = floats(draw.view, 16);
|
||||
item["proj"] = floats(draw.proj, 16);
|
||||
item["texture0"] = String::utf8(draw.texture0.c_str());
|
||||
item["texture1"] = String::utf8(draw.texture1.c_str());
|
||||
item["pretransformed"] = draw.pretransformed;
|
||||
item["lines"] = draw.lines;
|
||||
|
||||
PackedVector3Array positions;
|
||||
positions.resize(static_cast<int64_t>(draw.positions.size() / 3));
|
||||
for (int64_t i = 0; i < positions.size(); ++i)
|
||||
positions[i] = Vector3(draw.positions[i * 3], draw.positions[i * 3 + 1], draw.positions[i * 3 + 2]);
|
||||
item["positions"] = positions;
|
||||
if (!draw.rhw.empty())
|
||||
item["rhw"] = floats(draw.rhw.data(), static_cast<int>(draw.rhw.size()));
|
||||
if (!draw.normals.empty()) {
|
||||
PackedVector3Array normals;
|
||||
normals.resize(static_cast<int64_t>(draw.normals.size() / 3));
|
||||
for (int64_t i = 0; i < normals.size(); ++i)
|
||||
normals[i] = Vector3(draw.normals[i * 3], draw.normals[i * 3 + 1], draw.normals[i * 3 + 2]);
|
||||
item["normals"] = normals;
|
||||
}
|
||||
auto uvs = [](const std::vector<float> &values) {
|
||||
PackedVector2Array out;
|
||||
out.resize(static_cast<int64_t>(values.size() / 2));
|
||||
for (int64_t i = 0; i < out.size(); ++i)
|
||||
out[i] = Vector2(values[i * 2], values[i * 2 + 1]);
|
||||
return out;
|
||||
};
|
||||
if (!draw.uv0.empty())
|
||||
item["uv0"] = uvs(draw.uv0);
|
||||
if (!draw.uv1.empty())
|
||||
item["uv1"] = uvs(draw.uv1);
|
||||
if (!draw.diffuse.empty()) {
|
||||
PackedColorArray colors;
|
||||
colors.resize(static_cast<int64_t>(draw.diffuse.size()));
|
||||
for (int64_t i = 0; i < colors.size(); ++i)
|
||||
colors[i] = argb_color(draw.diffuse[i]);
|
||||
item["diffuse"] = colors;
|
||||
}
|
||||
PackedInt32Array indices;
|
||||
indices.resize(static_cast<int64_t>(draw.indices.size()));
|
||||
for (int64_t i = 0; i < indices.size(); ++i)
|
||||
indices[i] = static_cast<int32_t>(draw.indices[i]);
|
||||
item["indices"] = indices;
|
||||
|
||||
item["alpha_blend"] = static_cast<int64_t>(draw.alpha_blend);
|
||||
item["src_blend"] = static_cast<int64_t>(draw.src_blend);
|
||||
item["dest_blend"] = static_cast<int64_t>(draw.dest_blend);
|
||||
item["alpha_test"] = static_cast<int64_t>(draw.alpha_test);
|
||||
item["alpha_ref"] = static_cast<int64_t>(draw.alpha_ref);
|
||||
item["alpha_func"] = static_cast<int64_t>(draw.alpha_func);
|
||||
item["cull_mode"] = static_cast<int64_t>(draw.cull_mode);
|
||||
item["z_enable"] = static_cast<int64_t>(draw.z_enable);
|
||||
item["z_write"] = static_cast<int64_t>(draw.z_write);
|
||||
item["z_func"] = static_cast<int64_t>(draw.z_func);
|
||||
item["lighting"] = static_cast<int64_t>(draw.lighting);
|
||||
item["texture_factor"] = static_cast<int64_t>(draw.texture_factor);
|
||||
item["fog_enable"] = static_cast<int64_t>(draw.fog_enable);
|
||||
item["color_op"] = static_cast<int64_t>(draw.color_op[0]);
|
||||
item["alpha_op"] = static_cast<int64_t>(draw.alpha_op[0]);
|
||||
item["material_diffuse"] = Color(draw.material_diffuse[0], draw.material_diffuse[1],
|
||||
draw.material_diffuse[2], draw.material_diffuse[3]);
|
||||
item["material_ambient"] = Color(draw.material_ambient[0], draw.material_ambient[1],
|
||||
draw.material_ambient[2], draw.material_ambient[3]);
|
||||
item["material_emissive"] = Color(draw.material_emissive[0], draw.material_emissive[1],
|
||||
draw.material_emissive[2], draw.material_emissive[3]);
|
||||
item["light0"] = draw.light0;
|
||||
item["light0_direction"] = Vector3(draw.light0_direction[0], draw.light0_direction[1],
|
||||
draw.light0_direction[2]);
|
||||
item["light0_diffuse"] = Color(draw.light0_diffuse[0], draw.light0_diffuse[1], draw.light0_diffuse[2],
|
||||
draw.light0_diffuse[3]);
|
||||
item["light0_ambient"] = Color(draw.light0_ambient[0], draw.light0_ambient[1], draw.light0_ambient[2],
|
||||
draw.light0_ambient[3]);
|
||||
item["ambient"] = argb_color(draw.ambient);
|
||||
out.push_back(item);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void Metin2PythonHost::stop() {
|
||||
PythonBoot::Stop();
|
||||
}
|
||||
@@ -149,6 +256,7 @@ void Metin2PythonHost::ui_key(int, bool) {}
|
||||
void Metin2PythonHost::ui_update() {}
|
||||
Array Metin2PythonHost::ui_render_commands() { return Array(); }
|
||||
Ref<Image> Metin2PythonHost::memory_texture(const String &, int64_t) { return Ref<Image>(); }
|
||||
Array Metin2PythonHost::render3d_draws() { return Array(); }
|
||||
|
||||
void Metin2PythonHost::stop() {
|
||||
}
|
||||
@@ -171,6 +279,7 @@ void Metin2PythonHost::_bind_methods() {
|
||||
ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("ui_render_commands"), &Metin2PythonHost::ui_render_commands);
|
||||
ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("memory_texture", "name", "known_revision"),
|
||||
&Metin2PythonHost::memory_texture, DEFVAL(-1));
|
||||
ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("render3d_draws"), &Metin2PythonHost::render3d_draws);
|
||||
ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("stop"), &Metin2PythonHost::stop);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user