Compare commits

..

9 Commits

Author SHA1 Message Date
Tristan 'Natrist' Cormier
4fadd1f91a
Merge c12a79d6e6 into e5cc9de486 2026-02-18 23:18:42 -05:00
fallenoak
e5cc9de486
feat(ui): add CGWorldFrame::OnFrameSizeChanged
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-18 19:34:52 -06:00
fallenoak
7682dba2c9
feat(ui): add CGCamera 2026-02-18 17:00:56 -06:00
fallenoak
c6e18336de
chore(build): update typhoon 2026-02-18 16:28:19 -06:00
fallenoak
e7bd5968cf
feat(gx): add GxRenderTargetGet
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-18 08:43:11 -06:00
fallenoak
a51e9ba082
feat(gx): add missing initializers to CGxDevice 2026-02-18 08:24:53 -06:00
fallenoak
619bcca778
feat(gx): add CGxDevice::m_textureTarget
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-18 06:19:28 -06:00
fallenoak
4782c554fc
feat(gx): add CGxDevice::TextureTarget 2026-02-18 06:15:53 -06:00
fallenoak
8c518f7e6d
feat(gx): add EGxBuffer 2026-02-18 06:14:31 -06:00
14 changed files with 254 additions and 8 deletions

@ -1 +1 @@
Subproject commit 4ba7e0a6c3836254daf97bab159807fae6cab039 Subproject commit 1e5366bbc6935e3363abf5921f0be12f902e790a

View File

@ -924,6 +924,10 @@ CGxPool* CGxDevice::PoolCreate(EGxPoolTarget target, EGxPoolUsage usage, uint32_
return pool; return pool;
} }
void CGxDevice::RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex) {
gxTex = this->m_textureTarget[buffer].m_texture;
}
void CGxDevice::RsGet(EGxRenderState which, int32_t& value) { void CGxDevice::RsGet(EGxRenderState which, int32_t& value) {
value = static_cast<int32_t>(this->m_appRenderStates[which].m_value); value = static_cast<int32_t>(this->m_appRenderStates[which].m_value);
} }

View File

@ -38,6 +38,13 @@ struct ShaderConstants {
class CGxDevice { class CGxDevice {
public: public:
// Structs
struct TextureTarget {
CGxTex* m_texture;
uint32_t m_plane;
void* m_apiSpecific;
};
// Static variables // Static variables
static uint32_t s_alphaRef[]; static uint32_t s_alphaRef[];
static C3Vector s_pointScaleIdentity; static C3Vector s_pointScaleIdentity;
@ -101,12 +108,12 @@ class CGxDevice {
uint32_t m_appMasterEnables = 0; uint32_t m_appMasterEnables = 0;
uint32_t m_hwMasterEnables = 0; uint32_t m_hwMasterEnables = 0;
TSList<CGxPool, TSGetLink<CGxPool>> m_poolList; TSList<CGxPool, TSGetLink<CGxPool>> m_poolList;
CGxBuf* m_bufLocked[GxPoolTargets_Last]; CGxBuf* m_bufLocked[GxPoolTargets_Last] = {};
CGxPool* m_vertexPool = nullptr; CGxPool* m_vertexPool = nullptr;
CGxPool* m_indexPool = nullptr; CGxPool* m_indexPool = nullptr;
CGxBuf* m_streamBufs[GxPoolTargets_Last]; CGxBuf* m_streamBufs[GxPoolTargets_Last] = {};
CGxVertexAttrib m_primVertexFormatAttrib[GxVertexBufferFormats_Last]; CGxVertexAttrib m_primVertexFormatAttrib[GxVertexBufferFormats_Last];
CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last]; CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last] = {};
uint32_t m_primVertexMask = 0; uint32_t m_primVertexMask = 0;
uint32_t m_primVertexDirty = 0; uint32_t m_primVertexDirty = 0;
EGxVertexBufferFormat m_primVertexFormat = GxVertexBufferFormats_Last; EGxVertexBufferFormat m_primVertexFormat = GxVertexBufferFormats_Last;
@ -116,6 +123,9 @@ class CGxDevice {
int32_t m_primIndexDirty = 0; int32_t m_primIndexDirty = 0;
TSFixedArray<CGxAppRenderState> m_appRenderStates; TSFixedArray<CGxAppRenderState> m_appRenderStates;
TSFixedArray<CGxStateBom> m_hwRenderStates; TSFixedArray<CGxStateBom> m_hwRenderStates;
// TODO
TextureTarget m_textureTarget[GxBuffers_Last] = {};
// TODO
uint32_t m_baseMipLevel = 0; // TODO placeholder uint32_t m_baseMipLevel = 0; // TODO placeholder
// Virtual member functions // Virtual member functions
@ -173,6 +183,7 @@ class CGxDevice {
void PrimVertexFormat(CGxBuf*, CGxVertexAttrib*, uint32_t); void PrimVertexFormat(CGxBuf*, CGxVertexAttrib*, uint32_t);
void PrimVertexMask(uint32_t); void PrimVertexMask(uint32_t);
void PrimVertexPtr(CGxBuf*, EGxVertexBufferFormat); void PrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
void RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex);
void RsGet(EGxRenderState, int32_t&); void RsGet(EGxRenderState, int32_t&);
void RsSet(EGxRenderState, int32_t); void RsSet(EGxRenderState, int32_t);
void RsSet(EGxRenderState, void*); void RsSet(EGxRenderState, void*);

6
src/gx/RenderTarget.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "gx/RenderTarget.hpp"
#include "gx/Device.hpp"
void GxRenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex) {
g_theGxDevicePtr->RenderTargetGet(buffer, gxTex);
}

10
src/gx/RenderTarget.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef GX_RENDER_TARGET_HPP
#define GX_RENDER_TARGET_HPP
#include "gx/Types.hpp"
class CGxTex;
void GxRenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex);
#endif

View File

@ -54,6 +54,12 @@ enum EGxBlend {
GxBlends_Last = 12 GxBlends_Last = 12
}; };
enum EGxBuffer {
GxBuffers_Color = 0,
GxBuffers_Depth = 1,
GxBuffers_Last,
};
enum EGxColorFormat { enum EGxColorFormat {
GxCF_argb = 0, GxCF_argb = 0,
GxCF_rgba = 1, GxCF_rgba = 1,

97
src/ui/game/CGCamera.cpp Normal file
View File

@ -0,0 +1,97 @@
#include "ui/game/CGCamera.hpp"
#include "ui/game/Types.hpp"
#include "console/CVar.hpp"
#include "world/World.hpp"
#include <storm/String.hpp>
#include <tempest/Math.hpp>
#include <algorithm>
static CVar* s_cameraView;
CGCamera::CameraViewData CGCamera::s_cameraViewDataDefault[MAX_CAMERA_VIEWS] = {
{ "0.0", "0.0", "0.0" }, // VIEW_FIRST_PERSON
{ "0.0", "0.0", "0.0" }, // VIEW_THIRD_PERSON_A
{ "5.55", "10.0", "0.0" }, // VIEW_THIRD_PERSON_B
{ "5.55", "20.0", "0.0" }, // VIEW_THIRD_PERSON_C
{ "13.88", "30.0", "0.0" }, // VIEW_THIRD_PERSON_D
{ "13.88", "10.0", "0.0" }, // VIEW_THIRD_PERSON_E
{ "0.0", "0.0", "0.0" }, // VIEW_COMMENTATOR
{ "5.0", "10.0", "0.0" }, // VIEW_BARBER_SHOP
};
namespace {
bool ValidateCameraView(CVar* var, const char* oldValue, const char* value, void* arg) {
auto view = SStrToFloat(value);
auto min = static_cast<float>(VIEW_FIRST_PERSON);
auto max = static_cast<float>(VIEW_BARBER_SHOP);
if (view >= min && view <= max) {
return true;
}
// TODO ConsoleWriteA("Value out of range (%f - %f)\n", DEFAULT_COLOR, min, max);
return false;
}
}
CGCamera::CGCamera() : CSimpleCamera(CWorld::GetNearClip(), CWorld::GetFarClip(), 90.0f * CMath::DEG2RAD) {
this->m_relativeTo = 0;
this->m_view = s_cameraView->GetInt();
this->m_distance = SStrToFloat(CGCamera::s_cameraViewDataDefault[this->m_view].m_distance);
this->m_yaw = 0.0f;
this->m_pitch = SStrToFloat(CGCamera::s_cameraViewDataDefault[this->m_view].m_pitch);
this->m_roll = 0.0f;
this->m_fovOffset = 0.0f;
}
float CGCamera::FOV() const {
// Clamp offset-adjusted FOV between 0pi and 1pi
return std::min(std::max(this->m_fov + this->m_fovOffset, 0.0f), CMath::PI);
}
C3Vector CGCamera::Forward() const {
if (this->m_relativeTo) {
return this->CSimpleCamera::Forward() * this->ParentToWorld();
}
return this->CSimpleCamera::Forward();
}
C33Matrix CGCamera::ParentToWorld() const {
// TODO
return {};
}
C3Vector CGCamera::Right() const {
if (this->m_relativeTo) {
return this->CSimpleCamera::Right() * this->ParentToWorld();
}
return this->CSimpleCamera::Right();
}
void CGCamera::SetupWorldProjection(const CRect& projRect) {
this->SetGxProjectionAndView(projRect);
}
C3Vector CGCamera::Up() const {
if (this->m_relativeTo) {
return this->CSimpleCamera::Up() * this->ParentToWorld();
}
return this->CSimpleCamera::Up();
}
void CameraRegisterCVars() {
// TODO
s_cameraView = CVar::Register("cameraView", nullptr, 0x10, "2", &ValidateCameraView, DEFAULT);
// TODO
}

48
src/ui/game/CGCamera.hpp Normal file
View File

@ -0,0 +1,48 @@
#ifndef UI_GAME_C_G_CAMERA_HPP
#define UI_GAME_C_G_CAMERA_HPP
#include "ui/simple/CSimpleCamera.hpp"
#include "util/GUID.hpp"
class CGCamera : public CSimpleCamera {
public:
// Public structs
struct CameraViewData {
const char* m_distance;
const char* m_pitch;
const char* m_yaw;
};
// Public static variables
static CameraViewData s_cameraViewDataDefault[];
// Virtual public member functions
virtual ~CGCamera() = default;
virtual float FOV() const;
virtual C3Vector Forward() const;
virtual C3Vector Right() const;
virtual C3Vector Up() const;
// Public member functions
CGCamera();
C33Matrix ParentToWorld() const;
void SetupWorldProjection(const CRect& projRect);
private:
// Private member variables
// TODO
WOWGUID m_relativeTo;
// TODO
int32_t m_view;
// TODO
float m_distance;
float m_yaw;
float m_pitch;
float m_roll;
// TODO
float m_fovOffset;
};
void CameraRegisterCVars();
#endif

View File

@ -8,6 +8,7 @@
#include "ui/game/ActionBarScript.hpp" #include "ui/game/ActionBarScript.hpp"
#include "ui/game/BattlefieldInfoScript.hpp" #include "ui/game/BattlefieldInfoScript.hpp"
#include "ui/game/BattlenetUI.hpp" #include "ui/game/BattlenetUI.hpp"
#include "ui/game/CGCamera.hpp"
#include "ui/game/CGCharacterModelBase.hpp" #include "ui/game/CGCharacterModelBase.hpp"
#include "ui/game/CGCooldown.hpp" #include "ui/game/CGCooldown.hpp"
#include "ui/game/CGDressUpModelFrame.hpp" #include "ui/game/CGDressUpModelFrame.hpp"
@ -284,4 +285,8 @@ void CGGameUI::RegisterGameCVars() {
CVar::Register("fullSizeFocusFrame", "Increases the size of the focus frame to that of the target frame", 0x20, "0", nullptr, GAME); CVar::Register("fullSizeFocusFrame", "Increases the size of the focus frame to that of the target frame", 0x20, "0", nullptr, GAME);
// TODO // TODO
CameraRegisterCVars();
// TODO
} }

View File

@ -1,6 +1,8 @@
#include "ui/game/CGWorldFrame.hpp" #include "ui/game/CGWorldFrame.hpp"
#include "gx/Coordinate.hpp"
#include "gx/Shader.hpp" #include "gx/Shader.hpp"
#include "gx/Transform.hpp" #include "gx/Transform.hpp"
#include "ui/game/CGCamera.hpp"
#include "ui/game/PlayerName.hpp" #include "ui/game/PlayerName.hpp"
#include <storm/Memory.hpp> #include <storm/Memory.hpp>
#include <tempest/Matrix.hpp> #include <tempest/Matrix.hpp>
@ -46,6 +48,10 @@ CGWorldFrame::CGWorldFrame(CSimpleFrame* parent) : CSimpleFrame(parent) {
this->EnableEvent(SIMPLE_EVENT_MOUSEWHEEL, -1); this->EnableEvent(SIMPLE_EVENT_MOUSEWHEEL, -1);
// TODO // TODO
this->m_camera = STORM_NEW(CGCamera);
// TODO
} }
void CGWorldFrame::OnFrameRender(CRenderBatch* batch, uint32_t layer) { void CGWorldFrame::OnFrameRender(CRenderBatch* batch, uint32_t layer) {
@ -56,6 +62,29 @@ void CGWorldFrame::OnFrameRender(CRenderBatch* batch, uint32_t layer) {
} }
} }
void CGWorldFrame::OnFrameSizeChanged(const CRect& rect) {
this->CSimpleFrame::OnFrameSizeChanged(rect);
// Screen rect (DDC)
this->m_screenRect.minX = std::max(this->m_rect.minX, 0.0f);
this->m_screenRect.minY = std::max(this->m_rect.minY, 0.0f);
this->m_screenRect.maxX = std::min(this->m_rect.maxX, NDCToDDCWidth(1.0f));
this->m_screenRect.maxY = std::min(this->m_rect.maxY, NDCToDDCHeight(1.0f));
// Camera aspect ratio
if (this->m_camera) {
this->m_camera->SetScreenAspect(this->m_screenRect);
}
// Viewport (NDC)
DDCToNDC(this->m_rect.minX, this->m_rect.minY, &this->m_viewport.minX, &this->m_viewport.minY);
DDCToNDC(this->m_rect.maxX, this->m_rect.maxY, &this->m_viewport.maxX, &this->m_viewport.maxY);
this->m_viewport.minX = std::max(this->m_viewport.minX, 0.0f);
this->m_viewport.minY = std::max(this->m_viewport.minY, 0.0f);
this->m_viewport.maxX = std::min(this->m_viewport.maxX, 1.0f);
this->m_viewport.maxY = std::min(this->m_viewport.maxY, 1.0f);
}
void CGWorldFrame::OnWorldRender() { void CGWorldFrame::OnWorldRender() {
// TODO // TODO
} }

View File

@ -4,6 +4,8 @@
#include "ui/simple/CSimpleFrame.hpp" #include "ui/simple/CSimpleFrame.hpp"
#include <cstdint> #include <cstdint>
class CGCamera;
class CGWorldFrame : public CSimpleFrame { class CGWorldFrame : public CSimpleFrame {
public: public:
// Static variables // Static variables
@ -15,11 +17,22 @@ class CGWorldFrame : public CSimpleFrame {
// Virtual member functions // Virtual member functions
virtual void OnFrameRender(CRenderBatch* batch, uint32_t layer); virtual void OnFrameRender(CRenderBatch* batch, uint32_t layer);
// TODO
virtual void OnFrameSizeChanged(const CRect& rect);
// Member functions // Member functions
CGWorldFrame(CSimpleFrame* parent); CGWorldFrame(CSimpleFrame* parent);
void OnWorldRender(); void OnWorldRender();
void OnWorldUpdate(); void OnWorldUpdate();
private:
// Private member variables
// TODO
CRect m_screenRect;
CRect m_viewport;
// TODO
CGCamera* m_camera;
// TODO
}; };
#endif #endif

View File

@ -13,4 +13,16 @@ enum SCRIPTEVENT {
// TODO // TODO
}; };
enum CAMERA_VIEW {
VIEW_FIRST_PERSON = 0,
VIEW_THIRD_PERSON_A = 1,
VIEW_THIRD_PERSON_B = 2,
VIEW_THIRD_PERSON_C = 3,
VIEW_THIRD_PERSON_D = 4,
VIEW_THIRD_PERSON_E = 5,
VIEW_COMMENTATOR = 6,
VIEW_BARBER_SHOP = 7,
MAX_CAMERA_VIEWS,
};
#endif #endif

View File

@ -104,10 +104,6 @@ void CSimpleCamera::SetFieldOfView(float fov) {
this->m_fov = fov; this->m_fov = fov;
} }
void CSimpleCamera::SetNearZ(float nearZ) {
this->m_nearZ = nearZ;
}
void CSimpleCamera::SetGxProjectionAndView(const CRect& projRect) { void CSimpleCamera::SetGxProjectionAndView(const CRect& projRect) {
// Projection // Projection
@ -127,6 +123,14 @@ void CSimpleCamera::SetGxProjectionAndView(const CRect& projRect) {
GxXformSetView(viewMat); GxXformSetView(viewMat);
} }
void CSimpleCamera::SetNearZ(float nearZ) {
this->m_nearZ = nearZ;
}
void CSimpleCamera::SetScreenAspect(const CRect& screenRect) {
this->m_aspect = (screenRect.maxX - screenRect.minX) / (screenRect.maxY - screenRect.minY);
}
C3Vector CSimpleCamera::Up() const { C3Vector CSimpleCamera::Up() const {
return { this->m_facing.c0, this->m_facing.c1, this->m_facing.c2 }; return { this->m_facing.c0, this->m_facing.c1, this->m_facing.c2 };
} }

View File

@ -25,6 +25,7 @@ class CSimpleCamera {
void SetFieldOfView(float fov); void SetFieldOfView(float fov);
void SetGxProjectionAndView(const CRect& projRect); void SetGxProjectionAndView(const CRect& projRect);
void SetNearZ(float nearZ); void SetNearZ(float nearZ);
void SetScreenAspect(const CRect& screenRect);
protected: protected:
// Protected member variables // Protected member variables