libgui 2.01
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 static_assert(4 * cuVertexAttrSize <= cuRotatedSlotSize, "rotated quad must fit in one slot");
49 GX2RBuffer rotatedBuffer;
50 uint32_t rotatedSlot;
51
52 uint32_t angleLocation;
53 uint32_t offsetLocation;
54 uint32_t scaleLocation;
55 uint32_t colorIntensityLocation;
56 uint32_t blurLocation;
57 uint32_t samplerLocation;
58 uint32_t positionLocation;
59 uint32_t texCoordLocation;
60
61 public:
63 static Texture2DShader * instance()
64 {
65 if(!shaderInstance)
66 shaderInstance = new Texture2DShader();
67 return shaderInstance;
68 }
69
71 static void destroyInstance()
72 {
73 delete shaderInstance;
74 shaderInstance = nullptr;
75 }
76
78 void setShaders() const
79 {
80 fetchShader->setShader();
81 vertexShader.setShader();
82 pixelShader.setShader();
83 }
84
86 void setAttributeBuffer() const
87 {
88 VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
89 VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
90 }
91
95 {
96 rotatedSlot = 0;
97 }
98
105 bool uploadRotatedQuad(const float ndcCorners[8], uint32_t & slotOut)
106 {
107 if(!GX2RBufferExists(&rotatedBuffer) || rotatedSlot >= cuMaxRotatedDraws)
108 return false;
109
110 float * dst = static_cast<float *>(GX2RLockBufferEx(&rotatedBuffer, GX2R_RESOURCE_USAGE_CPU_WRITE));
111 if(!dst)
112 return false;
113
114 slotOut = rotatedSlot++;
115 dst += slotOut * (cuRotatedSlotSize / sizeof(float));
116 for(int i = 0; i < 4; i++)
117 {
118 dst[i * 3 + 0] = ndcCorners[i * 2 + 0];
119 dst[i * 3 + 1] = ndcCorners[i * 2 + 1];
120 dst[i * 3 + 2] = 0.0f;
121 }
122 GX2RUnlockBufferEx(&rotatedBuffer, GX2R_RESOURCE_USAGE_CPU_WRITE);
123 return true;
124 }
125
129 void setRotatedAttributeBuffer(uint32_t slot) const
130 {
131 GX2RSetAttributeBuffer(const_cast<GX2RBuffer *>(&rotatedBuffer), 0, cuVertexAttrSize, slot * cuRotatedSlotSize);
132 VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
133 }
134
138 void setAngle(float angleRadians)
139 {
140 VertexShader::setUniformReg(angleLocation, 4, &angleRadians);
141 }
142
143 void setOffset(const float offset[3])
144 {
145 VertexShader::setUniformReg(offsetLocation, 4, offset);
146 }
147
148 void setScale(const float scale[3])
149 {
150 VertexShader::setUniformReg(scaleLocation, 4, scale);
151 }
152
153 void setColorIntensity(const float colorIntensity[4])
154 {
155 PixelShader::setUniformReg(colorIntensityLocation, 4, colorIntensity);
156 }
157
159 void setTextureAndSampler(const GX2Texture * texture, const GX2Sampler * sampler) const
160 {
161 GX2SetPixelTexture(texture, samplerLocation);
162 GX2SetPixelSampler(sampler, samplerLocation);
163 }
164
170 void clearBlur() const
171 {
172 static const float zero[3] = {0.0f, 0.0f, 0.0f};
173 PixelShader::setUniformReg(blurLocation, 4, zero);
174 }
175};
176
177#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.