33#include " PresetFileParser.hpp"
44
55#include < Renderer/TextureManager.hpp>
6- #include < Renderer/RenderItem.hpp>
76
87#include < vector>
98
109namespace libprojectM {
1110namespace MilkdropPreset {
1211
1312CustomShape::CustomShape (PresetState& presetState)
14- : m_presetState(presetState)
13+ : m_outlineMesh(Renderer::VertexBufferUsage::StreamDraw)
14+ , m_fillMesh(Renderer::VertexBufferUsage::StreamDraw, true , false )
15+ , m_presetState(presetState)
1516 , m_perFrameContext(presetState.globalMemory, &presetState.globalRegisters)
1617{
17- std::vector<TexturedPoint> vertexData ;
18- vertexData. resize ( 102 );
18+ m_outlineMesh. SetVertexCount ( 100 ) ;
19+ m_outlineMesh. SetRenderPrimitiveType (Renderer::Mesh::PrimitiveType::LineLoop );
1920
20- glGenVertexArrays (1 , &m_vaoIdTextured);
21- glGenBuffers (1 , &m_vboIdTextured);
22-
23- glGenVertexArrays (1 , &m_vaoIdUntextured);
24- glGenBuffers (1 , &m_vboIdUntextured);
25-
26- glBindVertexArray (m_vaoIdTextured);
27- glBindBuffer (GL_ARRAY_BUFFER, m_vboIdTextured);
28-
29- glEnableVertexAttribArray (0 );
30- glEnableVertexAttribArray (1 );
31- glEnableVertexAttribArray (2 );
32-
33- glVertexAttribPointer (0 , 2 , GL_FLOAT, GL_FALSE, sizeof (TexturedPoint), reinterpret_cast <void *>(offsetof (TexturedPoint, x))); // Position
34- glVertexAttribPointer (1 , 4 , GL_FLOAT, GL_FALSE, sizeof (TexturedPoint), reinterpret_cast <void *>(offsetof (TexturedPoint, r))); // Color
35- glVertexAttribPointer (2 , 2 , GL_FLOAT, GL_FALSE, sizeof (TexturedPoint), reinterpret_cast <void *>(offsetof (TexturedPoint, u))); // Texture coordinate
36-
37- glBufferData (GL_ARRAY_BUFFER, sizeof (TexturedPoint) * vertexData.size (), vertexData.data (), GL_STREAM_DRAW);
38-
39- glBindVertexArray (m_vaoIdUntextured);
40- glBindBuffer (GL_ARRAY_BUFFER, m_vboIdUntextured);
41-
42- glEnableVertexAttribArray (0 );
43- glEnableVertexAttribArray (1 );
44-
45- glVertexAttribPointer (0 , 2 , GL_FLOAT, GL_FALSE, sizeof (TexturedPoint), reinterpret_cast <void *>(offsetof (TexturedPoint, x))); // Position
46- glVertexAttribPointer (1 , 4 , GL_FLOAT, GL_FALSE, sizeof (TexturedPoint), reinterpret_cast <void *>(offsetof (TexturedPoint, r))); // Color
47-
48- glBufferData (GL_ARRAY_BUFFER, sizeof (TexturedPoint) * vertexData.size (), vertexData.data (), GL_STREAM_DRAW);
49-
50- RenderItem::Init ();
21+ m_fillMesh.SetVertexCount (102 );
22+ m_fillMesh.SetRenderPrimitiveType (Renderer::Mesh::PrimitiveType::TriangleFan);
5123
5224 m_perFrameContext.RegisterBuiltinVariables ();
5325}
5426
55- CustomShape::~CustomShape ()
56- {
57- glDeleteBuffers (1 , &m_vboIdTextured);
58- glDeleteVertexArrays (1 , &m_vaoIdTextured);
59-
60- glDeleteBuffers (1 , &m_vboIdUntextured);
61- glDeleteVertexArrays (1 , &m_vaoIdUntextured);
62- }
63-
64- void CustomShape::InitVertexAttrib ()
65- {
66- glEnableVertexAttribArray (0 );
67- glVertexAttribPointer (0 , 2 , GL_FLOAT, GL_FALSE, 0 , nullptr ); // points
68- glDisableVertexAttribArray (1 );
69-
70- std::vector<Point> vertexData;
71- vertexData.resize (100 );
72- glBufferData (GL_ARRAY_BUFFER, sizeof (Point) * vertexData.size (), vertexData.data (), GL_STREAM_DRAW);
73- }
74-
7527void CustomShape::Initialize (::libprojectM::PresetFileParser& parsedFile, int index)
7628{
7729 std::string const shapecodePrefix = " shapecode_" + std::to_string (index) + " _" ;
@@ -148,49 +100,47 @@ void CustomShape::Draw()
148100 // Additive Drawing or Overwrite
149101 glBlendFunc (GL_SRC_ALPHA, static_cast <int >(*m_perFrameContext.additive ) != 0 ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA);
150102
151- std::vector<TexturedPoint> vertexData (sides + 2 );
152-
153- vertexData[0 ].x = static_cast <float >(*m_perFrameContext.x * 2.0 - 1.0 );
154- vertexData[0 ].y = static_cast <float >(*m_perFrameContext.y * -2.0 + 1.0 );
103+ auto & vertexData = m_fillMesh.Vertices ();
104+ auto & colorData = m_fillMesh.Colors ();
155105
156- vertexData[0 ]. u = 0 . 5f ;
157- vertexData[ 0 ]. v = 0 . 5f ;
106+ vertexData[0 ] = Renderer::Point ( static_cast < float >(*m_perFrameContext. x * 2.0 - 1.0 ),
107+ static_cast < float >(*m_perFrameContext. y * - 2.0 + 1.0 )) ;
158108
159109 // x = f*255.0 & 0xFF = (f*255.0) % 256
160110 // f' = x/255.0 = f % (256/255)
161111 // 1.0 -> 255 (0xFF)
162112 // 2.0 -> 254 (0xFE)
163113 // -1.0 -> 0x01
164114
165- vertexData [0 ]. r = Renderer::color_modulo ( *m_perFrameContext.r );
166- vertexData[ 0 ]. g = Renderer::color_modulo (*m_perFrameContext.g );
167- vertexData[ 0 ]. b = Renderer::color_modulo (*m_perFrameContext.b );
168- vertexData[ 0 ]. a = Renderer::color_modulo (*m_perFrameContext.a );
115+ colorData [0 ] = Renderer::Color::Modulo ( Renderer::Color ( static_cast < float >( *m_perFrameContext.r ),
116+ static_cast < float > (*m_perFrameContext.g ),
117+ static_cast < float > (*m_perFrameContext.b ),
118+ static_cast < float > (*m_perFrameContext.a )) );
169119
170- vertexData [1 ]. r = Renderer::color_modulo ( *m_perFrameContext.r2 );
171- vertexData[ 1 ]. g = Renderer::color_modulo (*m_perFrameContext.g2 );
172- vertexData[ 1 ]. b = Renderer::color_modulo (*m_perFrameContext.b2 );
173- vertexData[ 1 ]. a = Renderer::color_modulo (*m_perFrameContext.a2 );
120+ colorData [1 ] = Renderer::Color::Modulo ( Renderer::Color ( static_cast < float >( *m_perFrameContext.r2 ),
121+ static_cast < float > (*m_perFrameContext.g2 ),
122+ static_cast < float > (*m_perFrameContext.b2 ),
123+ static_cast < float > (*m_perFrameContext.a2 )) );
174124
175125 for (int i = 1 ; i < sides + 1 ; i++)
176126 {
177127 const float cornerProgress = static_cast <float >(i - 1 ) / static_cast <float >(sides);
178128 const float angle = cornerProgress * pi * 2 .0f + static_cast <float >(*m_perFrameContext.ang ) + pi * 0 .25f ;
179129
180130 // Todo: There's still some issue with aspect ratio here, as everything gets squashed horizontally if Y > x.
181- vertexData[i]. x = vertexData[0 ].x + static_cast <float >(*m_perFrameContext.rad ) * cosf (angle) * m_presetState.renderContext .aspectY ;
182- vertexData[i]. y = vertexData[0 ].y + static_cast <float >(*m_perFrameContext.rad ) * sinf (angle);
131+ vertexData[i] = Renderer::Point ( vertexData[0 ].X () + static_cast <float >(*m_perFrameContext.rad ) * cosf (angle) * m_presetState.renderContext .aspectY ,
132+ vertexData[0 ].Y () + static_cast <float >(*m_perFrameContext.rad ) * sinf (angle) );
183133
184- vertexData[i].r = vertexData[1 ].r ;
185- vertexData[i].g = vertexData[1 ].g ;
186- vertexData[i].b = vertexData[1 ].b ;
187- vertexData[i].a = vertexData[1 ].a ;
134+ colorData[i] = colorData[1 ];
188135 }
189136
190137 // Duplicate last vertex.
191138 vertexData[sides + 1 ] = vertexData[1 ];
139+ colorData[sides + 1 ] = colorData[1 ];
192140
193- if (static_cast <int >(*m_perFrameContext.textured ) != 0 )
141+ m_fillMesh.SetUseUV (static_cast <int >(*m_perFrameContext.textured ) != 0 );
142+
143+ if (m_fillMesh.UseUV ())
194144 {
195145 auto shader = m_presetState.texturedShader .lock ();
196146 shader->Bind ();
@@ -223,58 +173,55 @@ void CustomShape::Draw()
223173 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
224174 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
225175
176+ auto & uvs = m_fillMesh.UVs ();
177+
178+ uvs[0 ] = Renderer::TextureUV (0 .5f , 0 .5f );
179+
226180 for (int i = 1 ; i < sides + 1 ; i++)
227181 {
228182 const float cornerProgress = static_cast <float >(i - 1 ) / static_cast <float >(sides);
229183 const float angle = cornerProgress * pi * 2 .0f + static_cast <float >(*m_perFrameContext.tex_ang ) + pi * 0 .25f ;
230184
231- vertexData [i]. u = 0 .5f + 0 .5f * cosf (angle) / static_cast <float >(*m_perFrameContext.tex_zoom ) * textureAspectY;
232- vertexData[i]. v = 1 .0f - (0 .5f - 0 .5f * sinf (angle) / static_cast <float >(*m_perFrameContext.tex_zoom )); // Vertical flip required!
185+ uvs [i] = Renderer::TextureUV ( 0 .5f + 0 .5f * cosf (angle) / static_cast <float >(*m_perFrameContext.tex_zoom ) * textureAspectY,
186+ 1 .0f - (0 .5f - 0 .5f * sinf (angle) / static_cast <float >(*m_perFrameContext.tex_zoom ) )); // Vertical flip required!
233187 }
234188
235- vertexData[sides + 1 ] = vertexData[1 ];
236-
237- glBindBuffer (GL_ARRAY_BUFFER, m_vboIdTextured);
238-
239- glBufferSubData (GL_ARRAY_BUFFER, 0 , sizeof (TexturedPoint) * (sides + 2 ), vertexData.data ());
240-
241- glBindVertexArray (m_vaoIdTextured);
242- glDrawArrays (GL_TRIANGLE_FAN, 0 , sides + 2 );
243- glBindVertexArray (0 );
244-
245- glBindTexture (GL_TEXTURE_2D, 0 );
246- Renderer::Sampler::Unbind (0 );
189+ uvs[sides + 1 ] = uvs[1 ];
247190 }
248191 else
249192 {
250193 // Untextured (creates a color gradient: center=r/g/b/a to border=r2/b2/g2/a2)
251- glBindBuffer (GL_ARRAY_BUFFER, m_vboIdUntextured);
252-
253- glBufferSubData (GL_ARRAY_BUFFER, 0 , sizeof (TexturedPoint) * (sides + 2 ), vertexData.data ());
254-
255194 auto shader = m_presetState.untexturedShader .lock ();
256195 shader->Bind ();
257196 shader->SetUniformMat4x4 (" vertex_transformation" , PresetState::orthogonalProjection);
258-
259- glBindVertexArray (m_vaoIdUntextured);
260- glDrawArrays (GL_TRIANGLE_FAN, 0 , sides + 2 );
261- glBindVertexArray (0 );
262197 }
263198
199+ m_fillMesh.Indices ().Resize (sides + 2 );
200+ m_fillMesh.Indices ().MakeContinuous ();
201+ m_fillMesh.Update ();
202+ m_fillMesh.Draw ();
203+
204+ glBindTexture (GL_TEXTURE_2D, 0 );
205+ Renderer::Sampler::Unbind (0 );
206+
264207 if (*m_perFrameContext.border_a > 0 .0001f )
265208 {
266- std::vector<ShapeVertex> points (sides);
209+ m_outlineMesh.Indices ().Resize (sides);
210+ m_outlineMesh.Indices ().MakeContinuous ();
211+
212+ auto & points = m_outlineMesh.Vertices ();
267213
268214 for (int i = 0 ; i < sides; i++)
269215 {
270- points[i].x = vertexData[i + 1 ].x ;
271- points[i].y = vertexData[i + 1 ].y ;
216+ points[i] = m_fillMesh.Vertex (i + 1 );
272217 }
273218
274219 auto shader = m_presetState.untexturedShader .lock ();
275220 shader->Bind ();
276221 shader->SetUniformMat4x4 (" vertex_transformation" , PresetState::orthogonalProjection);
277222
223+ m_outlineMesh.Bind ();
224+
278225 glVertexAttrib4f (1 ,
279226 static_cast <float >(*m_perFrameContext.border_r ),
280227 static_cast <float >(*m_perFrameContext.border_g ),
@@ -285,9 +232,6 @@ void CustomShape::Draw()
285232 glEnable (GL_LINE_SMOOTH);
286233#endif
287234
288- glBindVertexArray (m_vaoID);
289- glBindBuffer (GL_ARRAY_BUFFER, m_vboID);
290-
291235 const auto iterations = m_thickOutline ? 4 : 1 ;
292236
293237 // Need to use +/- 1.0 here instead of 2.0 used in Milkdrop to achieve the same rendering result.
@@ -306,40 +250,38 @@ void CustomShape::Draw()
306250 case 1 :
307251 for (auto j = 0 ; j < sides; j++)
308252 {
309- points[j].x += incrementX;
253+ points[j].SetX (points[j]. X () + incrementX) ;
310254 }
311255 break ;
312256
313257 case 2 :
314258 for (auto j = 0 ; j < sides; j++)
315259 {
316- points[j].y += incrementY;
260+ points[j].SetY (points[j]. Y () + incrementY) ;
317261 }
318262 break ;
319263
320264 case 3 :
321265 for (auto j = 0 ; j < sides; j++)
322266 {
323- points[j].x -= incrementX;
267+ points[j].SetX (points[j]. X () - incrementX) ;
324268 }
325269 break ;
326270 }
327271
328- glBufferSubData (GL_ARRAY_BUFFER, 0 , static_cast <GLsizei>( sizeof (Point) * sides), points. data () );
329- glDrawArrays (GL_LINE_LOOP, 0 , sides );
272+ m_outlineMesh. Update ( );
273+ m_outlineMesh. Draw ( );
330274 }
331275 }
332276 }
333277
334- glBindBuffer (GL_ARRAY_BUFFER, 0 );
335- glBindVertexArray ( 0 );
278+ Renderer::Mesh::Unbind ( );
279+ Renderer::Shader::Unbind ( );
336280
337281#ifndef USE_GLES
338282 glDisable (GL_LINE_SMOOTH);
339283#endif
340284 glDisable (GL_BLEND);
341-
342- Renderer::Shader::Unbind ();
343285}
344286
345287} // namespace MilkdropPreset
0 commit comments