Map projections' depth like the client's renderer
IMVU's projections give depth from -1 to 1; its Direct3D renderer maps it to 0 to 1, and now so does ours. Without that, the nearer half of the depth range was clipped, the whole 2D overlay (name tags, the frame rate, the room's title) with it. The adapter also draws drawTrianglesFromMemory without indices, and sums up what the client draws in its log. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
299cd8c312
commit
3cdda4c7ed
6 files changed
+78
-43
No files matched your search
+7
-36
@@ -1,13 +1,9 @@
|
||||
#include "scene.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "fixed_function_hlsl.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
namespace t5de {
|
||||
|
||||
@@ -227,6 +223,13 @@ bool Scene::execute(std::span<const std::byte> commands, int offsetX, bool draw)
|
||||
void Scene::setProjection(const protocol::SetProjection& projection)
|
||||
{
|
||||
std::memcpy(constants_.projection, projection.m, sizeof(constants_.projection));
|
||||
// The client's projections give depth from -1 to 1, as OpenGL does; IMVU's Direct3D renderer maps it to 0 to 1
|
||||
// (z' = z / 2 + w / 2) before setting them, and so do we. (It also shifts them half a pixel, which Direct3D 9
|
||||
// needs and Direct3D 11 doesn't.)
|
||||
for (int row = 0; row < 4; ++row) {
|
||||
float* m = constants_.projection + row * 4;
|
||||
m[2] = 0.5f * m[2] + 0.5f * m[3];
|
||||
}
|
||||
constants_.viewport[0] = static_cast<float>(projection.width);
|
||||
constants_.viewport[1] = static_cast<float>(projection.height);
|
||||
if (!onscreen_) {
|
||||
@@ -545,38 +548,6 @@ void Scene::drawPointSprites(const protocol::Command& command)
|
||||
if (!buffer || prepare(0, true) == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (spritesLogged_ < 5) {
|
||||
++spritesLogged_;
|
||||
const Texture* texture = textures_.contains(state_.texture0) ? &textures_[state_.texture0] : nullptr;
|
||||
log::info("particles: {}, texture {} {}x{} flags {}, blending {} mode {}, depth test {} write {}, alpha test {} "
|
||||
"reference {}, lighting {}, fog {}, ambient ({:.2f} {:.2f} {:.2f}), texture transform [{} {} {} {} {} {}]",
|
||||
sprites->count, state_.texture0, texture ? texture->width : 0, texture ? texture->height : 0,
|
||||
texture ? texture->flags : 0, state_.blending, state_.blendMode, state_.depthTest, state_.depthWrite,
|
||||
constants_.flags[1], constants_.flags[2], constants_.flags[0], constants_.fog[2], constants_.ambient[0],
|
||||
constants_.ambient[1], constants_.ambient[2], constants_.texTransform0[0], constants_.texTransform0[1],
|
||||
constants_.texTransform0[2], constants_.texTransform0[4], constants_.texTransform0[5],
|
||||
constants_.texTransform0[6]);
|
||||
// The first sprite: where it is, seen from the camera, and how big it's drawn.
|
||||
float point[4] = {0, 0, 0, 1};
|
||||
std::uint32_t color = 0;
|
||||
std::memcpy(point, payload.data(), 12);
|
||||
std::memcpy(&color, payload.data() + 12, 4);
|
||||
const auto transform = [](const float (&p)[4], const float (&m)[16]) {
|
||||
std::array<float, 4> out{};
|
||||
for (int column = 0; column < 4; ++column) {
|
||||
out[column] = p[0] * m[column] + p[1] * m[4 + column] + p[2] * m[8 + column] + p[3] * m[12 + column];
|
||||
}
|
||||
return out;
|
||||
};
|
||||
const auto world = transform(point, constants_.world);
|
||||
const float worldPoint[4] = {world[0], world[1], world[2], world[3]};
|
||||
const auto view = transform(worldPoint, constants_.view);
|
||||
const float distance = std::sqrt(view[0] * view[0] + view[1] * view[1] + view[2] * view[2]);
|
||||
log::info(" first sprite at ({:.2f} {:.2f} {:.2f}), color {:08x}, from the camera ({:.2f} {:.2f} {:.2f}): "
|
||||
"distance {:.2f}, {:.1f} pixels across (viewport height {})",
|
||||
point[0], point[1], point[2], color, view[0], view[1], view[2], distance,
|
||||
std::clamp(constants_.viewport[1] / std::max(distance, 1e-4f), 1.0f, 2048.0f), constants_.viewport[1]);
|
||||
}
|
||||
IBuffer* buffers[] = {buffer};
|
||||
context_->SetVertexBuffers(0, 1, buffers, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION,
|
||||
SET_VERTEX_BUFFERS_FLAG_RESET);
|
||||
|
||||
Reference in new issue
Block a user