libgui 3.00
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
Texture2DShader.h
1/****************************************************************************
2 * Platform Abstraction Layer (WUT driver)
3 * Daryl Borth 2026
4 * Texture2DShader.h
5 ***************************************************************************/
6#ifndef WUT_TEXTURE_2D_SHADER_H_
7#define WUT_TEXTURE_2D_SHADER_H_
8
9#include "VertexShader.h"
10#include "PixelShader.h"
11#include "FetchShader.h"
12#include <gx2r/buffer.h>
13#include <gx2r/draw.h>
14#include <gx2r/resource.h>
15
19class Texture2DShader : public Shader
20{
21 private:
22 Texture2DShader();
23 virtual ~Texture2DShader();
24
25 static const uint32_t cuAttributeCount = 2;
26 static const uint32_t ciPositionVtxsSize = 4 * cuVertexAttrSize;
27 static const uint32_t ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
28
29 static Texture2DShader * shaderInstance;
30
31 FetchShader * fetchShader;
32 VertexShader vertexShader;
33 PixelShader pixelShader;
34
35 float * posVtxs;
36 float * texCoords;
37
38 // Rotated quads are positioned on the CPU (see WutImageRenderer::drawTexture)
39 // and drawn with an identity transform, because the compiled vertex
40 // shader's rotation assumes a 16:9 canvas and warps on a 4:3 one.
41 // Each rotated draw needs its own vertex slot: GX2 draws are
42 // asynchronous, so a single shared buffer would be overwritten while
43 // an earlier draw this frame is still queued (same reasoning as
44 // ColorShader's per-draw color slots). Slots are padded to
45 // GX2_VERTEX_BUFFER_ALIGNMENT so every slot offset stays aligned.
46 static const uint32_t cuMaxRotatedDraws = 64;
47 static const uint32_t cuRotatedSlotSize = GX2_VERTEX_BUFFER_ALIGNMENT;
48 GX2RBuffer rotatedBuffer;
49 uint32_t rotatedSlot;
50
51 uint32_t angleLocation;
52 uint32_t offsetLocation;
53 uint32_t scaleLocation;
54 uint32_t colorIntensityLocation;
55 uint32_t blurLocation;
56 uint32_t samplerLocation;
57 uint32_t positionLocation;
58 uint32_t texCoordLocation;
59
60 public:
62 static Texture2DShader * instance()
63 {
64 if(!shaderInstance)
65 shaderInstance = new Texture2DShader();
66 return shaderInstance;
67 }
68
70 static void destroyInstance()
71 {
72 delete shaderInstance;
73 shaderInstance = nullptr;
74 }
75
77 void setShaders() const
78 {
79 fetchShader->setShader();
80 vertexShader.setShader();
81 pixelShader.setShader();
82 }
83
85 void setAttributeBuffer() const
86 {
87 VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
88 VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
89 }
90
94 {
95 rotatedSlot = 0;
96 }
97
104 bool uploadRotatedQuad(const float ndcCorners[8], uint32_t & slotOut)
105 {
106 if(!GX2RBufferExists(&rotatedBuffer) || rotatedSlot >= cuMaxRotatedDraws)
107 return false;
108
109 float * dst = static_cast<float *>(GX2RLockBufferEx(&rotatedBuffer, GX2R_RESOURCE_USAGE_CPU_WRITE));
110 if(!dst)
111 return false;
112
113 slotOut = rotatedSlot++;
114 dst += slotOut * (cuRotatedSlotSize / sizeof(float));
115 for(int i = 0; i < 4; i++)
116 {
117 dst[i * 3 + 0] = ndcCorners[i * 2 + 0];
118 dst[i * 3 + 1] = ndcCorners[i * 2 + 1];
119 dst[i * 3 + 2] = 0.0f;
120 }
121 GX2RUnlockBufferEx(&rotatedBuffer, GX2R_RESOURCE_USAGE_CPU_WRITE);
122 return true;
123 }
124
128 void setRotatedAttributeBuffer(uint32_t slot) const
129 {
130 GX2RSetAttributeBuffer(const_cast<GX2RBuffer *>(&rotatedBuffer), 0, cuVertexAttrSize, slot * cuRotatedSlotSize);
131 VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
132 }
133
137 void setAngle(float angleRadians)
138 {
139 VertexShader::setUniformReg(angleLocation, 4, &angleRadians);
140 }
141
142 void setOffset(const float offset[3])
143 {
144 VertexShader::setUniformReg(offsetLocation, 4, offset);
145 }
146
147 void setScale(const float scale[3])
148 {
149 VertexShader::setUniformReg(scaleLocation, 4, scale);
150 }
151
152 void setColorIntensity(const float colorIntensity[4])
153 {
154 PixelShader::setUniformReg(colorIntensityLocation, 4, colorIntensity);
155 }
156
158 void setTextureAndSampler(const GX2Texture * texture, const GX2Sampler * sampler) const
159 {
160 GX2SetPixelTexture(texture, samplerLocation);
161 GX2SetPixelSampler(sampler, samplerLocation);
162 }
163
169 void clearBlur() const
170 {
171 static const float zero[3] = {0.0f, 0.0f, 0.0f};
172 PixelShader::setUniformReg(blurLocation, 4, zero);
173 }
174};
175
176#endif // WUT_TEXTURE_2D_SHADER_H_
Owns the GX2 fetch shader program that binds vertex attribute streams to a vertex shader.
Definition FetchShader.h:17
Owns a GX2PixelShader's compiled program and uniform/sampler metadata, mirroring VertexShader's role ...
Definition PixelShader.h:17
static void setUniformReg(uint32_t location, uint32_t size, const void *reg)
Writes uniform registers for the bound pixel shader.
static const uint16_t cuVertexAttrSize
Size in bytes of one position vertex (3 floats)
Definition Shader.h:72
static const uint16_t cuTexCoordAttrSize
Size in bytes of one texture coordinate (2 floats)
Definition Shader.h:74
void setOffset(const float offset[3])
void setRotatedAttributeBuffer(uint32_t slot) const
Binds a slot from uploadRotatedQuad() as the position stream (plus the shared texcoords).
void setAttributeBuffer() const
Binds the quad position and texture-coordinate buffers.
void resetFrame()
Call once per frame, before any draws - rewinds the rotated-quad slot counter (see WutVideoDriver::pr...
static Texture2DShader * instance()
void clearBlur() const
The compiled pixel shader reads a per-draw blur-direction uniform that this driver doesn't expose as ...
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const
Binds the texture to sample and the sampler describing its filtering.
void setColorIntensity(const float colorIntensity[4])
static void destroyInstance()
Destroys the shared instance; the next instance() call creates a new one.
void setScale(const float scale[3])
void setAngle(float angleRadians)
bool uploadRotatedQuad(const float ndcCorners[8], uint32_t &slotOut)
Copies a pre-rotated quad into its own vertex slot.
void setShaders() const
Binds the fetch, vertex and pixel shaders for subsequent draws.
Owns a GX2VertexShader's compiled program and uniform/attribute metadata.
static void setUniformReg(uint32_t location, uint32_t size, const void *reg)
Writes uniform registers for the bound vertex shader.
static void setAttributeBuffer(uint32_t bufferIdx, uint32_t bufferSize, uint32_t stride, const void *buffer)
Binds a vertex data buffer to an attribute buffer slot.