libgui 2.01
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
ColorShader.h
1/****************************************************************************
2 * Platform Abstraction Layer (WUT driver)
3 * Daryl Borth 2026
4 * ColorShader.h
5 ***************************************************************************/
6#ifndef WUT_COLOR_SHADER_H_
7#define WUT_COLOR_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 ColorShader : public Shader
20{
21 private:
22 ColorShader();
23 virtual ~ColorShader();
24
25 static const uint32_t cuAttributeCount = 2;
26 static const uint32_t cuPositionVtxsSize = 4 * cuVertexAttrSize;
27
28 static ColorShader * shaderInstance;
29
30 FetchShader * fetchShader;
31 VertexShader vertexShader;
32 PixelShader pixelShader;
33
34 float * positionVtxs;
35
36 // Per-draw color data can't safely share one reused buffer address:
37 // GX2 draw calls are asynchronous, and within a single frame there
38 // can be many colored-rectangle draws in flight before the GPU
39 // catches up. A single shared buffer means draw N+1's memcpy can
40 // stomp on data draw N's GX2DrawEx hasn't been read by the GPU yet.
41 static const uint32_t cuMaxColorDraws = 512;
42 GX2RBuffer colorBuffer;
43 uint32_t colorSlot;
44
45 uint32_t angleLocation;
46 uint32_t offsetLocation;
47 uint32_t scaleLocation;
48 uint32_t colorLocation;
49 uint32_t colorIntensityLocation;
50 uint32_t positionLocation;
51
52 public:
54 static const uint32_t cuColorVtxsSize = 4 * cuColorAttrSize;
55
57 static ColorShader * instance()
58 {
59 if(!shaderInstance)
60 shaderInstance = new ColorShader();
61 return shaderInstance;
62 }
63
65 static void destroyInstance()
66 {
67 delete shaderInstance;
68 shaderInstance = nullptr;
69 }
70
72 void setShaders() const
73 {
74 fetchShader->setShader();
75 vertexShader.setShader();
76 pixelShader.setShader();
77 }
78
87 {
88 colorSlot = 0;
89 }
90
99 void setAttributeBuffer(const uint8_t * colorAttr)
100 {
101 VertexShader::setAttributeBuffer(0, cuPositionVtxsSize, cuVertexAttrSize, positionVtxs);
102
103 // If a single frame ever draws more than cuMaxColorDraws
104 // colored rectangles, keep reusing the last slot rather than
105 // wrapping - wrapping could stomp a slot an earlier draw this
106 // same frame is still relying on.
107 uint32_t slot = colorSlot;
108 if(colorSlot < cuMaxColorDraws - 1)
109 colorSlot++;
110
111 if(GX2RBufferExists(&colorBuffer))
112 {
113 uint8_t * dst = static_cast<uint8_t *>(GX2RLockBufferEx(&colorBuffer, GX2R_RESOURCE_USAGE_CPU_WRITE));
114 if(dst)
115 {
116 memcpy(dst + slot * cuColorVtxsSize, colorAttr, cuColorVtxsSize);
117 GX2RUnlockBufferEx(&colorBuffer, GX2R_RESOURCE_USAGE_CPU_WRITE);
118 }
119 GX2RSetAttributeBuffer(&colorBuffer, 1, cuColorAttrSize, slot * cuColorVtxsSize);
120 }
121 }
122
133 void bindMesh(const float * positions, const uint8_t * colors, uint32_t vertexCapacity, const float * offset = nullptr, const float * scale = nullptr)
134 {
135 static const float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
136 static const float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
137
140 setAngle(0.0f);
141 setOffset(offset ? offset : zero);
142 setScale(scale ? scale : one);
144 }
145
149 static void drawMesh(uint32_t firstVertex, uint32_t vertexCount)
150 {
151 GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLES, vertexCount, firstVertex, 1);
152 }
153
155 void setAngle(float angleRadians)
156 {
157 VertexShader::setUniformReg(angleLocation, 4, &angleRadians);
158 }
159
160 void setOffset(const float offset[3])
161 {
162 VertexShader::setUniformReg(offsetLocation, 4, offset);
163 }
164
165 void setScale(const float scale[3])
166 {
167 VertexShader::setUniformReg(scaleLocation, 4, scale);
168 }
169
170 void setColorIntensity(const float colorIntensity[4])
171 {
172 PixelShader::setUniformReg(colorIntensityLocation, 4, colorIntensity);
173 }
174};
175
176#endif // WUT_COLOR_SHADER_H_
void setOffset(const float offset[3])
Sets the NDC position of the quad's center.
void resetFrame()
Call once per frame, before any draws - rewinds the per-draw color slot counter so this frame starts ...
Definition ColorShader.h:86
static void destroyInstance()
Destroys the shared instance; the next instance() call creates a new one.
Definition ColorShader.h:65
void bindMesh(const float *positions, const uint8_t *colors, uint32_t vertexCapacity, const float *offset=nullptr, const float *scale=nullptr)
Binds caller-owned vertex streams for mesh draws and sets the uniforms so vertices pass through uncha...
void setColorIntensity(const float colorIntensity[4])
Sets the RGBA color the quad is filled with.
void setAttributeBuffer(const uint8_t *colorAttr)
Definition ColorShader.h:99
static void drawMesh(uint32_t firstVertex, uint32_t vertexCount)
Draws triangles from the streams bound with bindMesh().
void setShaders() const
Binds the fetch, vertex and pixel shaders for subsequent draws.
Definition ColorShader.h:72
void setAngle(float angleRadians)
Sets the quad rotation in radians.
static const uint32_t cuColorVtxsSize
Size in bytes of the four per-vertex colors of one quad.
Definition ColorShader.h:54
void setScale(const float scale[3])
Sets the NDC half-extents of the quad.
static ColorShader * instance()
Definition ColorShader.h:57
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 cuColorAttrSize
Size in bytes of one vertex color (4 bytes, RGBA)
Definition Shader.h:76
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.