diff --git a/include/renderer/ps2gl_renderers/custom_renderer.hpp b/include/renderer/ps2gl_renderers/custom_renderer.hpp new file mode 100644 index 0000000..3e6e4d8 --- /dev/null +++ b/include/renderer/ps2gl_renderers/custom_renderer.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "ps2gl/renderer.h" +#include "ps2gl/linear_renderer.h" + +#define VU_FUNCTIONS(name) \ + void vsm##name##_CodeStart(); \ + void vsm##name##_CodeEnd() + +#define mVsmAddr(name) ((void*)vsm##name##_CodeStart) +#define mVsmSize(name) ((u8*)vsm##name##_CodeEnd - (u8*)vsm##name##_CodeStart) + +static constexpr CRendererProps no_reqs = static_cast(0LL); +static_assert(sizeof(0LL) == sizeof(CRendererProps)); + +// The 31st bit is the custom primitive flag, 1 is the custom renderer type +// static constexpr u32 kVCRPrimType = ((tU32)1 << 31) | 1; +// static constexpr u64 kVCRPrimTypeFlag = ((tU64)1 << 32); + +class CCustomRendererBase: public CLinearRenderer +{ +public: + CCustomRendererBase(void* packet, int packetSize, + int inQuadsPerVert, int outQuadsPerVert, + int inGeomOffset, int inGeomBufSize, + const char* name); + + virtual void InitContext(GLenum primType, tU32 rcChanges, bool userRcChanged) override; + virtual void DrawLinearArrays(CGeometryBlock& block) override; + + // This is the prim type passed to the gs + u32 PrimType = 0x7; // 0x7 = triangle strip + u32 CustomPrimType = 0; + u64 CustomPrimTypeFlag = 0; + + u32 ContextStart = 0; + u32 DoubleBufBase = 0; + u32 DoubleBufOffset = 0; + u32 DoubleBufSize = 0; +}; diff --git a/include/renderer/ps2gl_renderers/vertex_color_renderer.hpp b/include/renderer/ps2gl_renderers/vertex_color_renderer.hpp index e01fe64..33bf647 100644 --- a/include/renderer/ps2gl_renderers/vertex_color_renderer.hpp +++ b/include/renderer/ps2gl_renderers/vertex_color_renderer.hpp @@ -1,24 +1,18 @@ #pragma once -#include "GL/gl.h" -#include "ps2gl/immgmanager.h" -#include "ps2gl/linear_renderer.h" -#include "ps2gl/renderer.h" +#include "renderer/ps2gl_renderers/custom_renderer.hpp" // The 31st bit is the custom primitive flag, 1 is the custom renderer type -static constexpr u32 kVCRPrimType = ((tU32)1 << 31) | 1; -static constexpr u64 kVCRPrimTypeFlag = ((tU64)1 << 32); +static constexpr u32 VCRPrimType = ((tU32)1 << 31) | 1; +static constexpr u64 VCRPrimTypeFlag = ((tU64)1 << 32); //#define kVCRPrimType (((tU32)1 << 31) | 1) //#define kVCRPrimTypeFlag ((tU64)1 << 32) -class CVertexColorRenderer: public CLinearRenderer +class CVertexColorRenderer: public CCustomRendererBase { public: CVertexColorRenderer(); - - static CVertexColorRenderer* Register(); virtual void InitContext(GLenum primType, tU32 rcChanges, bool userRcChanged) override; - //virtual bool GetCachePackets(const CGeometryBlock& geometry) { return true; }; - virtual void DrawLinearArrays(CGeometryBlock& block) override; + static CVertexColorRenderer* Register(); }; \ No newline at end of file diff --git a/include/renderer/ps2gl_renderers/vertex_color_vegetation_renderer.hpp b/include/renderer/ps2gl_renderers/vertex_color_vegetation_renderer.hpp new file mode 100644 index 0000000..aecde33 --- /dev/null +++ b/include/renderer/ps2gl_renderers/vertex_color_vegetation_renderer.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "GL/gl.h" +#include "ps2gl/immgmanager.h" +#include "ps2gl/linear_renderer.h" +#include "ps2gl/renderer.h" +#include "renderer/ps2gl_renderers/custom_renderer.hpp" + +// The 31st bit is the custom primitive flag, 1 is the custom renderer type +static constexpr u32 VCVRPrimType = ((tU32)1 << 31) | 2; +static constexpr u64 VCVRPrimTypeFlag = ((tU64)1 << 33); + +//#define kVCRPrimType (((tU32)1 << 31) | 1) +//#define kVCRPrimTypeFlag ((tU64)1 << 32) + +class CVertexColorVegetationRenderer: public CCustomRendererBase +{ +public: + CVertexColorVegetationRenderer(); + + static CVertexColorVegetationRenderer* Register(); + virtual void InitContext(GLenum primType, tU32 rcChanges, bool userRcChanged) override; +}; \ No newline at end of file diff --git a/src/renderer/gs.cc b/src/renderer/gs.cc index fa58281..77cbb90 100644 --- a/src/renderer/gs.cc +++ b/src/renderer/gs.cc @@ -2,6 +2,7 @@ #include "renderer/gs.hpp" #include "renderer/renderable.hpp" #include "renderer/ps2gl_renderers/vertex_color_renderer.hpp" +#include "renderer/ps2gl_renderers/vertex_color_vegetation_renderer.hpp" #include "stats.hpp" #include "egg/assert.hpp" #include "utils/debuggable.hpp" @@ -109,6 +110,7 @@ static void init_renderer() init_lights(); CVertexColorRenderer::Register(); + CVertexColorVegetationRenderer::Register(); has_initialized = true; diff --git a/src/renderer/ps2gl_renderers/custom_renderer.cc b/src/renderer/ps2gl_renderers/custom_renderer.cc new file mode 100644 index 0000000..04a3173 --- /dev/null +++ b/src/renderer/ps2gl_renderers/custom_renderer.cc @@ -0,0 +1,100 @@ +#include "renderer/ps2gl_renderers/custom_renderer.hpp" + +#include "ps2s/cpu_matrix.h" +#include "ps2s/math.h" +#include "ps2s/packet.h" + +#include "ps2gl/drawcontext.h" +#include "ps2gl/glcontext.h" +#include "ps2gl/immgmanager.h" +#include "ps2gl/lighting.h" +#include "ps2gl/linear_renderer.h" +#include "ps2gl/material.h" +#include "ps2gl/matrix.h" +#include "ps2gl/metrics.h" +#include "ps2gl/texture.h" + +CCustomRendererBase::CCustomRendererBase(void* packet, int packetSize, + int inQuadsPerVert, int outQuadsPerVert, + int inGeomOffset, int inGeomBufSize, + const char* name) + : CLinearRenderer(packet, packetSize, inQuadsPerVert, outQuadsPerVert, + inGeomOffset, + inGeomBufSize, + name) +{ + Requirements = 0; + Capabilities = CustomPrimTypeFlag; +} + +void CCustomRendererBase::InitContext(GLenum, tU32 rcChanges, bool userRcChanged) +{ + CGLContext& glContext = *pGLContext; + CVifSCDmaPacket& packet = glContext.GetVif1Packet(); + CImmDrawContext& drawContext = glContext.GetImmDrawContext(); + + packet.Cnt(); + { + AddVu1RendererContext(packet, PrimType, ContextStart); // kContextStart + + // overwrite the giftag built by CBaseRenderer::AddVu1RendererContext()... + // ..it knows not what it does. + CImmDrawContext& drawContext = glContext.GetImmDrawContext(); + bool smoothShading = drawContext.GetDoSmoothShading(); + bool useTexture = glContext.GetTexManager().GetTexEnabled(); + bool alpha = drawContext.GetBlendEnabled(); + unsigned int nreg = OutputQuadsPerVert; + + GS::tPrim prim = {prim_type : PrimType, iip : smoothShading, tme : useTexture, fge : 0, abe : alpha, aa1 : 0, fst : 0, ctxt : 0, fix : 0}; + tGifTag giftag = {NLOOP : 0, EOP : 1, pad0 : 0, id : 0, PRE : 1, PRIM : *(tU64*)&prim, FLG : 0, NREG : nreg, REGS0 : 2, REGS1 : 1, REGS2 : 4}; + + // packet.Pad96(); + + // packet.OpenUnpack(Vifs::UnpackModes::s_32, kTime, Packet::kSingleBuff); + // packet += std::sin(Engine::get_game_time()) * 4.f; + // packet.CloseUnpack(1); + + packet.Mscal(0); + packet.Flushe(); + + packet.Base(DoubleBufBase); + packet.Offset(DoubleBufOffset); + + packet.Pad128(); + } + packet.CloseTag(); + + CacheRendererState(); +} + +void CCustomRendererBase::DrawLinearArrays(CGeometryBlock& block) +{ + block.SetNumVertsPerPrim(2); + block.SetNumVertsToRestartStrip(2); + + int wordsPerVert = block.GetWordsPerVertex(); + int wordsPerNormal = (block.GetNormalsAreValid()) ? block.GetWordsPerNormal() : 0; + int wordsPerTex = (block.GetTexCoordsAreValid()) ? block.GetWordsPerTexCoord() : 0; + int wordsPerColor = (block.GetColorsAreValid()) ? block.GetWordsPerColor() : 0; + + CVifSCDmaPacket& packet = pGLContext->GetVif1Packet(); + InitXferBlock(packet, wordsPerVert, wordsPerNormal, wordsPerTex, wordsPerColor); + + // get max number of vertices per vu1 buffer + + // let's assume separate unpacks for vertices, normals, tex uvs.. + int maxUnpackVerts = 256; + // max number of vertex data in vu1 memory + int vu1QuadsPerVert = InputQuadsPerVert; + int inputBufSize = InputGeomBufSize; + int maxVu1VertsPerBuffer = inputBufSize / vu1QuadsPerVert; + // max vertices per buffer + int maxVertsPerBuffer = std::min(maxUnpackVerts, maxVu1VertsPerBuffer); + maxVertsPerBuffer -= 3; + // make sure we don't end in the middle of a polygon + maxVertsPerBuffer -= maxVertsPerBuffer % block.GetNumVertsPerPrim(); + + // draw + + DrawBlock(packet, block, maxVertsPerBuffer); +} \ No newline at end of file diff --git a/src/renderer/ps2gl_renderers/vertex_color_renderer.cc b/src/renderer/ps2gl_renderers/vertex_color_renderer.cc index 4522b32..97cd204 100644 --- a/src/renderer/ps2gl_renderers/vertex_color_renderer.cc +++ b/src/renderer/ps2gl_renderers/vertex_color_renderer.cc @@ -14,44 +14,26 @@ #include "engine.hpp" -#define VU_FUNCTIONS(name) \ - void vsm##name##_CodeStart(); \ - void vsm##name##_CodeEnd() - -#define mVsmAddr(name) ((void*)vsm##name##_CodeStart) -#define mVsmSize(name) ((u8*)vsm##name##_CodeEnd - (u8*)vsm##name##_CodeStart) - extern "C" { VU_FUNCTIONS(VertexColorRenderer); } -using namespace RendererProps; - -static constexpr CRendererProps capabilities = { - PrimType : kPtsLinesStripsFans, - Lighting : 1, - NumDirLights : k3DirLights | k8DirLights, - NumPtLights : k1PtLight | k2PtLights | k8PtLights, - Texture : 1, - Specular : 1, - PerVtxMaterial : kDiffuse, - Clipping : kNonClipped | kClipped, - CullFace : 1, - TwoSidedLighting : 0, - ArrayAccess : kLinear -}; - -static constexpr CRendererProps no_reqs = static_cast(0LL); -static_assert(sizeof(0LL) == sizeof(CRendererProps)); - CVertexColorRenderer::CVertexColorRenderer() - : CLinearRenderer(mVsmAddr(VertexColorRenderer), mVsmSize(VertexColorRenderer), 4, 3, - kInputStart, - kInputBufSize - kInputStart, - "Vertex color renderer") + : CCustomRendererBase(mVsmAddr(VertexColorRenderer), mVsmSize(VertexColorRenderer), 4, 3, + kInputStart, + kInputBufSize - kInputStart, + "Vertex color renderer") { + CustomPrimType = VCRPrimType; + CustomPrimTypeFlag = VCRPrimTypeFlag; + Requirements = 0; - Capabilities = kVCRPrimTypeFlag; + Capabilities = CustomPrimTypeFlag; + + ContextStart = kContextStart; + DoubleBufBase = kDoubleBufBase; + DoubleBufOffset = kDoubleBufOffset; + DoubleBufSize = kDoubleBufSize; } CVertexColorRenderer* CVertexColorRenderer::Register() @@ -63,8 +45,8 @@ CVertexColorRenderer* CVertexColorRenderer::Register() // register the prim type - pglRegisterCustomPrimType(kVCRPrimType, // the prim type we will pass to ps2gl (glBegin...) - kVCRPrimTypeFlag, // the corresponding renderer requirement + pglRegisterCustomPrimType(VCRPrimType, // the prim type we will pass to ps2gl (glBegin...) + VCRPrimTypeFlag, // the corresponding renderer requirement ~(tU64)0xffffffff, // we only care about the custom stuff (upper 32 bits) true); // ok to merge multiple calls when possible @@ -98,7 +80,7 @@ void CVertexColorRenderer::InitContext(GLenum primType, tU32 rcChanges, bool use packet.Pad96(); packet.OpenUnpack(Vifs::UnpackModes::s_32, kTime, Packet::kSingleBuff); - packet += std::sin(Engine::get_game_time()) * 4.f; + packet += 0.f; packet.CloseUnpack(1); packet.Mscal(0); @@ -112,36 +94,4 @@ void CVertexColorRenderer::InitContext(GLenum primType, tU32 rcChanges, bool use packet.CloseTag(); CacheRendererState(); -} - -void CVertexColorRenderer::DrawLinearArrays(CGeometryBlock& block) -{ - block.SetNumVertsPerPrim(2); - block.SetNumVertsToRestartStrip(2); - - int wordsPerVert = block.GetWordsPerVertex(); - int wordsPerNormal = (block.GetNormalsAreValid()) ? block.GetWordsPerNormal() : 0; - int wordsPerTex = (block.GetTexCoordsAreValid()) ? block.GetWordsPerTexCoord() : 0; - int wordsPerColor = (block.GetColorsAreValid()) ? block.GetWordsPerColor() : 0; - - CVifSCDmaPacket& packet = pGLContext->GetVif1Packet(); - InitXferBlock(packet, wordsPerVert, wordsPerNormal, wordsPerTex, wordsPerColor); - - // get max number of vertices per vu1 buffer - - // let's assume separate unpacks for vertices, normals, tex uvs.. - int maxUnpackVerts = 256; - // max number of vertex data in vu1 memory - int vu1QuadsPerVert = InputQuadsPerVert; - int inputBufSize = InputGeomBufSize; - int maxVu1VertsPerBuffer = inputBufSize / vu1QuadsPerVert; - // max vertices per buffer - int maxVertsPerBuffer = std::min(maxUnpackVerts, maxVu1VertsPerBuffer); - maxVertsPerBuffer -= 3; - // make sure we don't end in the middle of a polygon - maxVertsPerBuffer -= maxVertsPerBuffer % block.GetNumVertsPerPrim(); - - // draw - - DrawBlock(packet, block, maxVertsPerBuffer); } \ No newline at end of file diff --git a/src/renderer/ps2gl_renderers/vertex_color_vegetation_renderer.cc b/src/renderer/ps2gl_renderers/vertex_color_vegetation_renderer.cc new file mode 100644 index 0000000..cbe5798 --- /dev/null +++ b/src/renderer/ps2gl_renderers/vertex_color_vegetation_renderer.cc @@ -0,0 +1,94 @@ +#include "renderer/ps2gl_renderers/vertex_color_vegetation_renderer.hpp" +#include "vertex_color_renderer_mem_linear.h" + +#include "ps2gl/drawcontext.h" +#include "ps2gl/glcontext.h" +#include "ps2gl/immgmanager.h" +#include "ps2gl/lighting.h" +#include "ps2gl/material.h" +#include "ps2gl/matrix.h" +#include "ps2gl/metrics.h" +#include "ps2gl/texture.h" + +#include "ps2gl/renderer.h" + +#include "engine.hpp" + +extern "C" { +VU_FUNCTIONS(VertexColorRenderer); +} + +CVertexColorVegetationRenderer::CVertexColorVegetationRenderer() + : CCustomRendererBase(mVsmAddr(VertexColorRenderer), mVsmSize(VertexColorRenderer), 4, 3, + kInputStart, + kInputBufSize - kInputStart, + "Vertex color vegetation renderer") +{ + CustomPrimType = VCVRPrimType; + CustomPrimTypeFlag = VCVRPrimTypeFlag; + + ContextStart = kContextStart; + DoubleBufBase = kDoubleBufBase; + DoubleBufOffset = kDoubleBufOffset; + DoubleBufSize = kDoubleBufSize; +} + +CVertexColorVegetationRenderer* CVertexColorVegetationRenderer::Register() +{ + // create a renderer and register it + + CVertexColorVegetationRenderer* renderer = new CVertexColorVegetationRenderer; + pglRegisterRenderer(renderer); + + // register the prim type + + pglRegisterCustomPrimType(VCVRPrimType, // the prim type we will pass to ps2gl (glBegin...) + VCVRPrimTypeFlag, // the corresponding renderer requirement + ~(tU64)0xffffffff, // we only care about the custom stuff (upper 32 bits) + true); // ok to merge multiple calls when possible + + return renderer; +} + +void CVertexColorVegetationRenderer::InitContext(GLenum primType, tU32 rcChanges, bool userRcChanged) +{ + primType = GL_TRIANGLE_STRIP; + + CGLContext& glContext = *pGLContext; + CVifSCDmaPacket& packet = glContext.GetVif1Packet(); + CImmDrawContext& drawContext = glContext.GetImmDrawContext(); + + packet.Cnt(); + { + AddVu1RendererContext(packet, primType, kContextStart); + + // overwrite the giftag built by CBaseRenderer::AddVu1RendererContext()... + // ..it knows not what it does. + primType &= 0x7; // convert from GL #define to gs prim number + CImmDrawContext& drawContext = glContext.GetImmDrawContext(); + bool smoothShading = drawContext.GetDoSmoothShading(); + bool useTexture = glContext.GetTexManager().GetTexEnabled(); + bool alpha = drawContext.GetBlendEnabled(); + unsigned int nreg = OutputQuadsPerVert; + + GS::tPrim prim = {prim_type : primType, iip : smoothShading, tme : useTexture, fge : 0, abe : alpha, aa1 : 0, fst : 0, ctxt : 0, fix : 0}; + tGifTag giftag = {NLOOP : 0, EOP : 1, pad0 : 0, id : 0, PRE : 1, PRIM : *(tU64*)&prim, FLG : 0, NREG : nreg, REGS0 : 2, REGS1 : 1, REGS2 : 4}; + + packet.Pad96(); + + packet.OpenUnpack(Vifs::UnpackModes::s_32, kTime, Packet::kSingleBuff); + packet += std::sin(Engine::get_game_time()) * 4.f; + packet.CloseUnpack(1); + + packet.Mscal(0); + packet.Flushe(); + + packet.Base(kDoubleBufBase); + packet.Offset(kDoubleBufOffset); + + packet.Pad128(); + } + packet.CloseTag(); + + CacheRendererState(); +} \ No newline at end of file