├── images
├── readme
├── sdl2_renderparty_logo.png
└── sdl2_renderparty_example_screenshot_freebsd.png
├── examples
├── readme
├── SDL2_Render_Party_White_Polygon_Test.gif
└── sdl2_render_party_mk_spinner_polygon.gif
├── RenderParty_Example_Project_CodeBlocks
├── RenderParty_Example_Project_CodeBlocks.cscope_file_list
├── RenderParty_Example_Project_CodeBlocks.layout
└── RenderParty_Example_Project_CodeBlocks.cbp
├── .gitignore
├── changelog.txt
├── LICENSE
├── README.md
├── sdl2_renderparty_example1.c
└── sdl2_renderparty.h
/images/readme:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Enjoy the show!
4 |
--------------------------------------------------------------------------------
/examples/readme:
--------------------------------------------------------------------------------
1 | MIT License
2 | Developed by PawByte + Nathan Hurde
3 |
--------------------------------------------------------------------------------
/images/sdl2_renderparty_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pawbyte/SDL2_RenderParty/HEAD/images/sdl2_renderparty_logo.png
--------------------------------------------------------------------------------
/examples/SDL2_Render_Party_White_Polygon_Test.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pawbyte/SDL2_RenderParty/HEAD/examples/SDL2_Render_Party_White_Polygon_Test.gif
--------------------------------------------------------------------------------
/examples/sdl2_render_party_mk_spinner_polygon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pawbyte/SDL2_RenderParty/HEAD/examples/sdl2_render_party_mk_spinner_polygon.gif
--------------------------------------------------------------------------------
/images/sdl2_renderparty_example_screenshot_freebsd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pawbyte/SDL2_RenderParty/HEAD/images/sdl2_renderparty_example_screenshot_freebsd.png
--------------------------------------------------------------------------------
/RenderParty_Example_Project_CodeBlocks/RenderParty_Example_Project_CodeBlocks.cscope_file_list:
--------------------------------------------------------------------------------
1 | "../sdl2_renderparty.c"
2 | "../sdl2_renderparty_example1.c"
3 | "../sdl2_renderparty.h"
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # build files
2 | bin/
3 | bin/Release/
4 | bin/Debug/
5 | build/
6 | examples/
7 | obj/
8 | RenderParty_Example_Project/
9 | .vscode/
10 |
11 | # CodeBlocks Depend file
12 | *.depend
13 |
14 | # Prerequisites
15 | *.d
16 |
17 | # Compiled Object files
18 | *.slo
19 | *.lo
20 | *.o
21 | *.obj
22 |
23 | # Precompiled Headers
24 | *.gch
25 | *.pch
26 |
27 | # Compiled Dynamic libraries
28 | *.so
29 | *.dylib
30 | *.dll
31 |
32 | # Fortran module files
33 | *.mod
34 | *.smod
35 |
36 | # Compiled Static libraries
37 | *.lai
38 | *.la
39 | *.a
40 | *.lib
41 |
42 | # Executables
43 | *.exe
44 | *.out
45 | *.app
46 |
--------------------------------------------------------------------------------
/RenderParty_Example_Project_CodeBlocks/RenderParty_Example_Project_CodeBlocks.layout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/changelog.txt:
--------------------------------------------------------------------------------
1 | Changelog Notes 1.1.4:
2 | -Added SDL_RenderParty_Oval() function
3 |
4 |
5 | Changelog Notes 1.1.3:
6 | -Added sdl_partyeffect_texture_mapped enum, not completed for functionality
7 | -Added extern SDL2_Party_Circle_Points for keeping track of how detailed circle render call is.
8 | -Added SDL_RenderParty_Circle and SDL_RenderParty_SetCirclePoints function
9 | -Seperated implementation into sdl_renderparty.c due to issues with single-file-header
10 | -Arranged functions alphabetically
11 | -Corrected define syntax
12 | -Removed default parameter values to maintain C-style syntax
13 | -Renamed sd2_renderparty_ex_h to SDL2_RENDERPARTY_HEADER
14 | -Added SDL2_RENDERPARTY_CIRCLE_POINT_MIN
15 |
16 | Changelog Notes 1.1.2:
17 | -Various bug fixes
18 |
19 | Changelog Notes 1.1.1:
20 | -Various bug fixes
21 |
22 | Changelog Notes 1.1.0:
23 | -Various bug fixes
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 PawByte
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/RenderParty_Example_Project_CodeBlocks/RenderParty_Example_Project_CodeBlocks.cbp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SDL2_RenderParty
2 |
3 | 
4 |
5 | A simple library of extending the current functionality of SDL2 without having to change your includes. Currently supporting RenderQuads, RenderPolygons and more! It's a party a SDL2 Render Party!
6 |
7 | Example Project of adding more sides to a rotating polygon rendered drawn with a white color:
8 |
9 |
10 | # As of V 1.1.3 and higher, SDL2_RenderParty is now a single header library!
11 |
12 | What this means is when including in your projects include in in your .c or .cpp files instead of your .h files for enabling implementation.
13 |
14 | ## These two lines is all you need:
15 |
16 | ```c
17 | #define SDL2_RENDERPARTY_IMPLEMENTATION //Allows the implementation of functions to be executed, withhout this line you may experience many compiler errors!
18 | #include "sdl2_renderparty.h" //Includes the SDL2_RenderParty single file library ( Written in C, compatabile with C++ )
19 | ```
20 |
21 |
22 | ## Screenshots:
23 | Rendered White Polygon with sides increasing:
24 | 
25 |
26 |
27 |
28 | Example Project Running on FreeBSD( Thanks high_on_tanor for testing):
29 | 
30 |
31 | Rendered Texture as polygon with sides increasing:
32 | 
33 |
34 |
35 | ## Functions:
36 |
37 | **bool SDL2_RenderParty_Init**(); //optional
38 |
39 | **bool SDL2_RenderParty_Quit**(); //optional
40 |
41 | //Gets the Directional Length on the X Axis , used in other calls
42 | **float SDL2_RenderParty_LengthdirX**( float length, float angle ); **
43 |
44 | //Gets the Directional Length on the Y Axis , used in other calls
45 | **float SDL2_RenderParty_LengthdirY**( float length, float angle );**
46 |
47 | //Renders a Circle at SDL_point(pos) with circle_radius, circle_colour, alpha(0-255) and starting and ending angle support.
48 | **bool SDL_RenderParty_Circle( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int circle_radius, SDL_Color * circle_colour, int alpha, float start_angle, int texture_effect );**
49 |
50 | //Renders An Oval with an X and Y radius at SDL_point(x,y) pos
51 | **bool SDL_RenderParty_Oval( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int x_radius,int y_radius,SDL_Color * oval_colour, int alpha, float start_angle, int texture_effect )**
52 |
53 |
54 | // Renders a texture or rotated rectangle based on 4 SDL_Vertices, you may toggle colors on or off and correct the inputted texture coordinates
55 | **bool SDL_RenderParty_Quad**( SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex * vertices, bool show_colors , bool update_tex_cords ); **
56 |
57 |
58 | // Renders TriangleStrips based on the inputted SDL_Vertex vertices. You will need at least 3 vertices for this function.
59 | // tex can be left NULL to render colored TriangleStrips. If not left blank, please see the texture_effect which is based on the sdl_partyeffect enums
60 | **int SDL_RenderParty_Strips**(SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex * vertices, int num_vertices, bool is_closed , int texture_effect ); **
61 |
62 |
63 | // Renders TriangleFans based on the inputted SDL_Vertex vertices. You will need at least 3 vertices for this function.
64 | // tex can be left NULL to render colored TriangleStrips. If not left blank, please see the texture_effect which is based on the sdl_partyeffect enums
65 | **int SDL_RenderParty_Fans**( SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex *vertices, int num_vertices, int texture_effect ); **
66 |
67 |
68 | // Renders a Polygon based on the inputted SDL_Vertex vertices. You will need at least 3 vertices for this function.
69 | // tex can be left NULL to render colored TriangleFans. If not left blank, please see the texture_effect which is based on the sdl_partyeffect enums
70 | **bool SDL_RenderParty_Polygon**( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int shape_length , int point_count, SDL_Color * shape_colour, int alpha, float start_angle, int texture_effect ); **
71 |
72 |
73 |
--------------------------------------------------------------------------------
/sdl2_renderparty_example1.c:
--------------------------------------------------------------------------------
1 | /*
2 | sdl2_renderparty_example1.c
3 | This file is part of:
4 | Example for SDL2_RenderParty ( Do not include in projects )
5 | https://www.pawbyte.com/sdl2_renderparty
6 | Copyright (c) 2024 Nathan Hurde, Chase Lee.
7 |
8 | Copyright (c) 2024 PawByte.
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the �Software�), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all
17 | copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED �AS IS�, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
27 | -SDL2_RenderParty
28 |
29 |
30 | */
31 |
32 |
33 | #include "SDL2/SDL.h" //Includes SDL2. Remmeber you need SDL 2.x and SDL 2.0.18 or higher. Not yet tested in SDL3...
34 | #include "sdl2_renderparty.h" //Include the SDL2_RenderParty header
35 | #include //Next we include the sacred time library needed to simulate random number generation
36 |
37 | //Random function for testing
38 | int example_random(int min, int max){
39 | return min + rand() / (RAND_MAX / (max - min + 1) + 1);
40 | }
41 |
42 | int example_random_float(float min, float max){
43 | return min + rand() / (RAND_MAX / (max - min + 1.f) + 1.f);
44 | }
45 |
46 | int main(int argv, char** args)
47 | {
48 | //Initialize the random number generator
49 | srand(time(NULL));
50 |
51 | SDL_SetHint( SDL_HINT_RENDER_LINE_METHOD, "3");
52 | SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "best");
53 | //First we initalize SDL2, your program may have more flags than this, but it should still work
54 | if( SDL_Init( SDL_INIT_VIDEO ) == -1 )
55 | {
56 | return false;
57 | }
58 |
59 | //Let's use the good ole classic size of 640x480
60 | int app_window_width = 640;
61 | int app_window_height = 480;
62 |
63 |
64 | //With SDL2 Initialized, let's make a Window centered on the screen using the dimensions we specified above.
65 | SDL_Window * app_window = SDL_CreateWindow("SDL2_RenderParty - Test Example",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,app_window_width,app_window_height,SDL_WINDOW_SHOWN| SDL_WINDOW_RESIZABLE );
66 |
67 | /*If somehow our window doesnt init, we return -1 and close program.
68 | If this happens, it is likely SDL2 is not initialized or installed properly.
69 | */
70 | if( app_window == NULL )
71 | {
72 | return -1;
73 | }
74 |
75 | //Inits the renderer, the flags can vary, but this is for a SDL Program which has control over the renderer
76 | SDL_Renderer * sdl_apprenderer = SDL_CreateRenderer( app_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE );// | SDL_RENDERER_PRESENTVSYNC );
77 |
78 |
79 | /*If somehow our sdl_apprenderer doesnt init, we return -1 and close program.
80 | If this happens, it is likely SDL2 is not initialized or installed properly.
81 | */
82 | if( sdl_apprenderer == NULL )
83 | {
84 | return -2;
85 | }
86 |
87 |
88 | //Now we initialize the party. This is optional, but advised to keep in codebases in case of updates to library.
89 | SDL2_RenderParty_Init();
90 |
91 | //Yippie, now we have a WHOOLE WINDOW, let's setup the gameloop code.
92 |
93 |
94 | //The power of this boolean will determine if we exit the example gameloop.
95 | bool app_closed = false;
96 |
97 | //Next we initialize the mouse coordinates
98 | int app_mouse_x = 0;
99 | int app_mouse_y = 0;
100 |
101 | //Now let's setup the center screen point
102 | SDL_Point center_point = {};
103 |
104 | //Speaking of points, let's prepare for the SDL_Point which stores the mouse X,Y coordinates.
105 | SDL_Point mouse_point = {};
106 |
107 | //Now we have a random polygon color for rendering
108 | SDL_Color filled_poly_color = {0,0,255,255};
109 | filled_poly_color.r = example_random(0,255);
110 | filled_poly_color.g = example_random(0,255);
111 | filled_poly_color.b = example_random(0,255);
112 |
113 | //More joyful initialization of the amount of points within our polygon.
114 | int shape_point_count = 3;
115 |
116 | //Initializes the angle of the polygonal shape we plan on drawing later.
117 | float shaped_angle = 0;
118 |
119 | //Defaults the radius of this polygon to 32 pixels
120 | int shape_size = 32;
121 |
122 | /*Defaults the texture shape to full ( Feel free to play with this in your code
123 | In this example we are not dealing with textures.
124 | */
125 |
126 | int gfx_effect = sdl_partyeffect_full;
127 |
128 |
129 | //Almost there, let's define a rectangle to compare our polygons against.
130 | SDL_Rect test_red_rect = {0,0,128, 128};
131 |
132 |
133 | //Next initialize the event state
134 | SDL_Event ev;
135 |
136 | //Polygons can also be rendered as triangle-fans or triangle-strips
137 |
138 | //Let's make an enum to keep track of which one we will like to select.
139 | //With only 640x480, the screen can get quite crowded
140 | enum
141 | {
142 | render_triangle_mode_strips = 0,
143 | render_triangle_mode_fans = 1,
144 | render_triangle_mode_quads = 2,
145 | render_triangle_mode_circle = 3,
146 | render_triangle_mode_oval = 4,
147 | render_triangle_mode_off = 5,
148 | };
149 |
150 |
151 | //Our triangle_mode_state is just an int.
152 | int triangle_mode_state = render_triangle_mode_strips;
153 |
154 | //Let's randomly say we have a max of 5000 points in our polygon...
155 | //We only gave ourselves 640x480 pixels to play with remember :-)
156 |
157 | const int max_random_polygon_points = 5000;
158 |
159 | SDL_Vertex random_polygon_vertices[max_random_polygon_points];
160 |
161 | //Ok let's initialize all of those vertices. This may take a lil time... ( Not really, tho)
162 | int i_v = 0;
163 | for( i_v = 0; i_v < max_random_polygon_points; i_v++ )
164 | {
165 | random_polygon_vertices[i_v].position.x = 0; //Defaults to point (0,0)
166 | random_polygon_vertices[i_v].position.y = 0; //Defaults to point (0,0)
167 | random_polygon_vertices[i_v].color.r = random_polygon_vertices[i_v].color.g = 0;
168 | random_polygon_vertices[i_v].color.b = random_polygon_vertices[i_v].color.a = 255;//defaltng to rgba(0,0,255,255) aka pure blue
169 | random_polygon_vertices[i_v].tex_coord.x = random_polygon_vertices[i_v].tex_coord.y = 0; //Defaults to point (0,0)
170 | }
171 |
172 | //Let's keep track of how many vertices we are going to begin with...
173 | //All polygons begin with 3 points, otherwise its a point or line...
174 | int triangle_mode_current_count = 3;
175 |
176 | /*
177 | To make this tutorial short I have not added texture loading.
178 | Feel free to add a texture variable here and load it in from data, file or memory.
179 | */
180 |
181 | //Now our gameloop is here. As long as app_closed is false the game will run until TaskManager closers it or your computer crashes
182 | while( app_closed == false )
183 | {
184 | //Let's get grab the mouse coordinates using SDL2
185 | SDL_GetMouseState( &app_mouse_x, &app_mouse_y );
186 | mouse_point.x = app_mouse_x;
187 | mouse_point.y = app_mouse_y;
188 |
189 | //Next let's get the window size using SDL2
190 | SDL_GetWindowSize(app_window, &app_window_width, &app_window_height);
191 |
192 | center_point.x = app_window_width/2;
193 | center_point.y = app_window_height/2;
194 |
195 | //This while loop is used for checking all input
196 | while (SDL_PollEvent(&ev) != 0)
197 | {
198 | switch(ev.type)
199 | {
200 | //If the Quit button or another program requests app to quit, we end the gameloop by setting app_closed to true
201 | case SDL_QUIT:
202 | app_closed = true;
203 | break;
204 |
205 | //Next let's check all keyboard input
206 | case SDL_KEYDOWN:
207 | //Select surfaces based on key press
208 | switch( ev.key.keysym.sym )
209 | {
210 |
211 | //Let's begin playing with our polygon
212 | case SDLK_w:
213 | //Ok let's initialize all of those vertices. This may take a lil time... ( Not really, tho)
214 |
215 | //Makes use we stay in bounds...
216 | if( triangle_mode_current_count >= max_random_polygon_points )
217 | {
218 | triangle_mode_current_count = max_random_polygon_points;
219 | }
220 |
221 | //Now let's give each value something random to enjoy :-)
222 | random_polygon_vertices[i_v].position.x = app_window_width/2;
223 | random_polygon_vertices[i_v].position.y = app_window_height/2;
224 | for( i_v = 1; i_v < triangle_mode_current_count; i_v++ )
225 | {
226 | random_polygon_vertices[i_v].position.x = example_random(0, app_window_width );
227 | random_polygon_vertices[i_v].position.y = example_random(0, app_window_height );
228 | random_polygon_vertices[i_v].color.r = example_random(0, 255 );
229 | random_polygon_vertices[i_v].color.g = example_random(0, 255 );
230 | random_polygon_vertices[i_v].color.b = example_random(0, 255 );
231 | random_polygon_vertices[i_v].color.a = example_random(0, 255 );
232 | random_polygon_vertices[i_v].tex_coord.x = example_random_float(0, 1);
233 | random_polygon_vertices[i_v].tex_coord.y = example_random_float(0, 1);
234 | }
235 | break;
236 |
237 | case SDLK_a:
238 | triangle_mode_state += 1;
239 | if( triangle_mode_state > render_triangle_mode_off )
240 | {
241 | triangle_mode_state = render_triangle_mode_strips;
242 | }
243 | break;
244 |
245 | case SDLK_s:
246 | triangle_mode_current_count -= example_random(1,4); //Let's add between 1 and 4 random points on next W button press
247 | if( triangle_mode_current_count < 3 )
248 | {
249 | triangle_mode_current_count = 3;
250 | }
251 | break;
252 |
253 |
254 | case SDLK_d:
255 | triangle_mode_current_count += example_random(1,4); //Let's add between 1 and 4 random points on next W button press
256 | break;
257 |
258 | //Ok let's play with the mouse bound polygon now:
259 | //Let's toggle the gfx effect if the space key is hit
260 | case SDLK_SPACE:
261 | gfx_effect++;
262 | if( gfx_effect > sdl_partyeffect_none )
263 | {
264 | gfx_effect = sdl_partyeffect_full;
265 | }
266 | if( gfx_effect < sdl_partyeffect_full )
267 | {
268 | gfx_effect = sdl_partyeffect_none;
269 | }
270 | break;
271 |
272 | //If the Z key is press we remove a point from our polygon
273 | case SDLK_z:
274 | if( shape_point_count > 3)
275 | {
276 | shape_point_count -= 1;
277 | }
278 | break;
279 |
280 | //If the X key is press we add another point to our polygon
281 | case SDLK_x:
282 | if( shape_point_count < sdl_renderparty_math_degrees_multiplier )
283 | {
284 | shape_point_count +=1;
285 | }
286 | break;
287 |
288 | //If the C key is press we DECRASE our polygon's radius by 8
289 | case SDLK_c:
290 | if( shape_size > 32 )
291 | {
292 | shape_size -=8;
293 | }
294 | break;
295 |
296 | //If the V key is press we INCREASE our polygon's radius by 8
297 | case SDLK_v:
298 | if( shape_size < 1024 )
299 | {
300 | shape_size +=8;
301 | }
302 | break;
303 |
304 | //If the B key is press we DECRASE our polygon's angle by 8
305 | case SDLK_b:
306 | shaped_angle -=8;
307 | break;
308 |
309 | //If the N key is press we INCREASE our polygon's angle by 8
310 | case SDLK_n:
311 | shaped_angle +=8;
312 | break;
313 |
314 | //If the M key is press we give our random polygon a new random color
315 | case SDLK_m:
316 | filled_poly_color.r = example_random(0,255);
317 | filled_poly_color.g = example_random(0,255);
318 | filled_poly_color.b = example_random(0,255);
319 | break;
320 |
321 | }
322 | break;
323 |
324 | default:
325 |
326 | break;
327 | }
328 | }
329 |
330 | //Now let's begin the render phase of the example
331 |
332 | //Let's clear the screen to a dark shade of blue
333 | SDL_SetRenderDrawColor(sdl_apprenderer, 0, 0, 96, 255);
334 | SDL_RenderClear(sdl_apprenderer);
335 |
336 | //Then let's draw a little red rectangle using the test_red_rect variable from the start of the program
337 | SDL_SetRenderDrawColor(sdl_apprenderer, 255, 0, 0, 255);
338 | SDL_RenderFillRect( sdl_apprenderer,&test_red_rect );
339 |
340 | //Finally we reset the rendercolor of the program back to white with a 255/255 alpha value
341 | SDL_SetRenderDrawColor(sdl_apprenderer, 255, 255, 255, 255);
342 |
343 | //Ok, our first time rendering with SDL_RenderParty!
344 |
345 | //We render a polygon with 20 points/sides with a radius of 128 pixels
346 | SDL_RenderParty_Polygon( sdl_apprenderer, NULL, center_point, 128, 20, NULL, 255, shaped_angle, gfx_effect, 0 );
347 |
348 | //Ok let's render the super randomized polygon to screen depending on which state we are in...
349 |
350 | if( triangle_mode_state == render_triangle_mode_strips )
351 | {
352 | SDL_RenderParty_Strips( sdl_apprenderer, NULL, random_polygon_vertices, triangle_mode_current_count, false, 0,0 );
353 | }
354 | else if( triangle_mode_state == render_triangle_mode_fans )
355 | {
356 | SDL_RenderParty_Fans( sdl_apprenderer,NULL, random_polygon_vertices, triangle_mode_current_count, 0,0);
357 | }
358 | else if( triangle_mode_state == render_triangle_mode_quads )
359 | {
360 | SDL_RenderParty_Quad( sdl_apprenderer, NULL, random_polygon_vertices, true, false );
361 | }
362 | else if( triangle_mode_state == render_triangle_mode_circle)
363 | {
364 | SDL_RenderParty_Circle( sdl_apprenderer, NULL, center_point, 256, &filled_poly_color, 96, shaped_angle, gfx_effect );
365 | }
366 | else if( triangle_mode_state == render_triangle_mode_oval)
367 | {
368 | SDL_RenderParty_Oval( sdl_apprenderer, NULL, center_point, 256,96, &filled_poly_color, 96, shaped_angle, gfx_effect );
369 | }
370 |
371 | /*Ok lets render our next polygon bound to the mouse coordinates
372 | This polygon uses the shape_size for it's radius, the shape_point_count for it's amount of sides
373 | */
374 | SDL_RenderParty_Polygon( sdl_apprenderer, NULL , mouse_point, shape_size, shape_point_count, &filled_poly_color, 255, shaped_angle, gfx_effect, 0 );
375 |
376 |
377 |
378 |
379 | /*Now your time. Try adding a texture to this example and replacing the second parameter of SDL_RenderParty_Polygon with it.
380 | SDL2_RenderParty has some cool effects for textures, so feel free to Press the Space key a few times until you get your desired effect
381 | */
382 |
383 | SDL_RenderPresent(sdl_apprenderer);
384 | }
385 | SDL2_RenderParty_Quit();
386 |
387 |
388 | if( sdl_apprenderer != NULL )
389 | {
390 | SDL_DestroyRenderer( sdl_apprenderer );
391 | sdl_apprenderer = NULL;
392 | }
393 |
394 | if( app_window != NULL )
395 | {
396 | SDL_DestroyWindow(app_window);
397 | app_window = NULL;
398 | }
399 | SDL_Quit();
400 |
401 | return 0;
402 | }
403 |
--------------------------------------------------------------------------------
/sdl2_renderparty.h:
--------------------------------------------------------------------------------
1 | /*
2 | sdl_rederparty.h
3 | This file is part of:
4 | SDL2_RenderParty
5 | https://www.pawbyte.com/sdl2_renderparty
6 | Copyright (c) 2024 Nathan Hurde, Chase Lee.
7 |
8 | Copyright (c) 2024 PawByte.
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the �Software�), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all
17 | copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED �AS IS�, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
27 | -SDL2_RenderParty
28 |
29 |
30 | */
31 |
32 |
33 | #ifndef SDL2_RENDERPARTY_HEADER
34 | #define SDL2_RENDERPARTY_HEADER
35 |
36 | #define SDL2_RENDERPARTY_IMPLEMENTATION
37 |
38 | #if defined(__cplusplus)
39 | extern "C" {
40 | #endif
41 |
42 | #define SDL2_RENDERPARTY_VERSION_MAJOR 1
43 | #define SDL2_RENDERPARTY_MINOR 1
44 | #define SDL2_RENDERPARTY_PATCH 4
45 |
46 | #define SDL2_RENDERPARTY_CIRCLE_POINT_MIN 4
47 |
48 | #include
49 | #include "SDL2/SDL.h"
50 |
51 | /*
52 | Requires SDL_RenderGeometry, which was introduced in SDL 2.0.18
53 |
54 | SDL_2.0.18 or higher is required!
55 |
56 |
57 |
58 | */
59 |
60 |
61 |
62 | #define sdl_party_max_vertex_count 999999
63 |
64 | extern SDL_Vertex SDL_RenderParty_Vertex_List[sdl_party_max_vertex_count];
65 | extern bool SDL2_Party_WasInitted;
66 | extern int SDL2_Party_Circle_Points; //Detailed enough for smaller screens.
67 |
68 | // Effects for polygon rendering, some are experimental. Toggle to see which effect works best for your game/app.
69 |
70 | enum
71 | {
72 | sdl_partyeffect_full = 0,
73 | sdl_partyeffect_additive = 1,
74 | sdl_partyeffect_subtractive = 2,
75 | sdl_partyeffect_inverted =3,
76 | sdl_partyeffect_bottom_up = 4,
77 | sdl_partyeffect_full_inverted = 5,
78 | sdl_partyeffect_texture_mapped = 6, // W.I.P
79 | sdl_partyeffect_none = 7,
80 | };
81 |
82 |
83 | // Math related variables
84 |
85 | #define sdl_renderparty_math_pi 3.14159265359
86 | const float sdl_renderparty_math_to_radians = 180.f/sdl_renderparty_math_pi;
87 | const float sdl_renderparty_math_degrees_multiplier = 180.f/sdl_renderparty_math_pi;
88 | const float sdl_renderparty_math_radians_multiplier = sdl_renderparty_math_pi/180.f;
89 |
90 |
91 | // Function Declarations
92 |
93 | bool SDL2_RenderParty_Init();
94 | bool SDL2_RenderParty_Quit();
95 | float SDL2_RenderParty_LengthdirX( float length, float angle );
96 | float SDL2_RenderParty_LengthdirY( float length, float angle );
97 | bool SDL_RenderParty_Circle( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int circle_radius, SDL_Color * circle_colour, int alpha, float start_angle, int texture_effect );
98 | bool SDL_RenderParty_Oval( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int x_radius,int y_radius,SDL_Color * oval_colour, int alpha, float start_angle, int texture_effect );
99 |
100 | int SDL_RenderParty_Fans( SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex * vertices, int num_vertices, int texture_effect , int start_vertice_pos);
101 | bool SDL_RenderParty_Polygon( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int shape_length , int point_count, SDL_Color * shape_colour, int alpha, float start_angle, int texture_effect, int start_vertice_pos );
102 | bool SDL_RenderParty_Quad( SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex * vertices, bool show_colors, bool update_tex_cords );
103 | bool SDL_RenderParty_SetCirclePoints( int new_circle_points );
104 | int SDL_RenderParty_Strips(SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex * vertices, int num_vertices, bool is_closed, int texture_effect, int start_vertice_pos );
105 |
106 | #ifdef __cplusplus
107 | }
108 | #endif
109 | #endif // SDL2_RENDERPARTY_HEADER
110 |
111 |
112 | //
113 | //Implementation Phase
114 | //
115 | #if defined(SDL2_RENDERPARTY_IMPLEMENTATION)
116 |
117 | SDL_Vertex SDL_RenderParty_Vertex_List[sdl_party_max_vertex_count];
118 | bool SDL2_Party_WasInitted = false;
119 | int SDL2_Party_Circle_Points = 32; //Detailed enough for smaller screens.
120 |
121 | // Function Implementation
122 |
123 | bool SDL2_RenderParty_Init()
124 | {
125 | SDL2_Party_WasInitted = SDL_WasInit(0);
126 |
127 | if( !SDL2_Party_WasInitted )
128 | {
129 | return false;
130 | }
131 | for( int i = 0; i = sdl_party_max_vertex_count/3 )
194 | {
195 | SDL_RenderParty_Fans( renderer, tex, vertices, sdl_party_max_vertex_count -1, texture_effect, i_vert_place );
196 | num_vertices -= sdl_party_max_vertex_count-1;
197 | i_vert_place += sdl_party_max_vertex_count -1;
198 | }
199 |
200 | int vert_pos_offset = start_vertice_pos;
201 |
202 | float found_max_w = 0;
203 | float found_max_h = 0;
204 |
205 | //Expensive to do a double-loop and comparision perhaps...
206 | if( texture_effect == sdl_partyeffect_texture_mapped )
207 | {
208 | for( int i_tex_vert = 0; i_tex_vert < num_vertices; i_tex_vert+= 1 )
209 | {
210 | if( vertices[vert_pos_offset].position.x > found_max_w )
211 | {
212 | found_max_w = vertices[vert_pos_offset].position.x;
213 | }
214 |
215 | if( vertices[vert_pos_offset].position.y > found_max_h )
216 | {
217 | found_max_h = vertices[vert_pos_offset].position.y;
218 | }
219 | vert_pos_offset+= 1;
220 | }
221 |
222 | }
223 |
224 | vert_pos_offset = start_vertice_pos;
225 | for( int i_vert = 0; i_vert < num_vertices; i_vert+= 1 )
226 | {
227 | SDL_RenderParty_Vertex_List[i_vert].position.x = vertices[vert_pos_offset].position.x;
228 | SDL_RenderParty_Vertex_List[i_vert].position.y = vertices[vert_pos_offset].position.y;
229 |
230 | SDL_RenderParty_Vertex_List[i_vert].color.r = vertices[vert_pos_offset].color.r;
231 | SDL_RenderParty_Vertex_List[i_vert].color.g = vertices[vert_pos_offset].color.g;
232 | SDL_RenderParty_Vertex_List[i_vert].color.b = vertices[vert_pos_offset].color.b;
233 | SDL_RenderParty_Vertex_List[i_vert].color.a = vertices[vert_pos_offset].color.a;
234 |
235 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = vertices[vert_pos_offset].tex_coord.x ;
236 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = vertices[vert_pos_offset].tex_coord.y ;
237 |
238 | //SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 1.f - (float)i_vert/(float)num_vertices;//tex_coords_default[i_vert_place].x ;
239 | //SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 1.f - (float)i_vert/(float)num_vertices;//tex_coords_default[i_vert_place].y ;
240 | if( tex != NULL )
241 | {
242 | switch( texture_effect )
243 | {
244 | case sdl_partyeffect_additive:
245 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = (float)(i_vert)/(float)(num_vertices);
246 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = (float)(i_vert)/(float)(num_vertices);
247 | break;
248 |
249 | case sdl_partyeffect_subtractive:
250 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 1.f - (float)i_vert/(float)num_vertices;
251 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 1.f -(float)i_vert/(float)num_vertices;
252 | break;
253 |
254 | case sdl_partyeffect_bottom_up:
255 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = (float)i_vert/(float)num_vertices;
256 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 1.f -(float)i_vert/(float)num_vertices;
257 | break;
258 |
259 | case sdl_partyeffect_inverted:
260 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 1.f-(float)i_vert/(float)num_vertices;
261 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = (float)i_vert/(float)num_vertices;
262 | break;
263 |
264 | case sdl_partyeffect_full_inverted:
265 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 1.f - tex_coords_default[i_vert_place].x ;
266 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 1.f - tex_coords_default[ i_vert_place].y ;
267 | break;
268 |
269 | case sdl_partyeffect_full:
270 | if( ( num_vertices-2% 4) == 0 )
271 | {
272 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = tex_coords_default[quad_position].x ;
273 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = tex_coords_default[quad_position].y ;
274 | quad_position+= 1;
275 | if( quad_position >= 4 )
276 | {
277 | quad_position = 0;
278 | }
279 | }
280 | else
281 | {
282 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = (float)(i_vert)/(float)(num_vertices);
283 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = (float)(i_vert)/(float)(num_vertices);
284 | }
285 | break;
286 | case sdl_partyeffect_texture_mapped:
287 | if( i_vert_place == 0 )
288 | {
289 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 0.5f;
290 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 0.5f;
291 | }
292 | else
293 | {
294 | if( found_max_w == 0)
295 | {
296 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 0.5f;
297 | }
298 | else
299 | {
300 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = (float)(vertices[i_vert_place].position.x / found_max_w);
301 | }
302 | if( found_max_h == 0)
303 | {
304 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 0.5f;
305 | }
306 | else
307 | {
308 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = (float)(vertices[i_vert_place].position.y / found_max_h);
309 | }
310 | }
311 | break;
312 | default:
313 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = vertices[i_vert].tex_coord.x ;
314 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = vertices[i_vert].tex_coord.y ;
315 | break;
316 | }
317 | }
318 | i_vert_place+= 1;
319 | vert_pos_offset+= 1;
320 | if( i_vert_place >=3 )
321 | {
322 | i_vert_place = 0;
323 | }
324 | }
325 |
326 | if( num_vertices == 3)
327 | {
328 | //if its only 3 vertices save time from doing for loop and just draw the 1 triangle
329 | if( tex != NULL )
330 | {
331 | SDL_RenderGeometry(renderer, tex, SDL_RenderParty_Vertex_List, num_vertices, NULL, 0 );
332 | return 3;
333 | }
334 | SDL_RenderGeometry(renderer, NULL, SDL_RenderParty_Vertex_List, num_vertices, NULL, 0);
335 | return 3;
336 | }
337 | else if( num_vertices == 4 && tex != NULL )
338 | {
339 | if( SDL_RenderParty_Quad( renderer, tex, SDL_RenderParty_Vertex_List, true, false ) )
340 | {
341 | return 4;
342 | }
343 | return 0;
344 | }
345 |
346 | //The following lines are used for vertices of 4 or more and will all connect to the 1st, plus last 2 verts
347 | unsigned int estimated_indices = (num_vertices-2)*3;
348 | int new_indices[ estimated_indices];
349 | new_indices[0] = 0;
350 | new_indices[1] = 1;
351 | new_indices[2] = 2;
352 | int i_vert = 3; //used to loop through remaining vertices
353 | int index_pos = 3; //used to create each 3 indices
354 | while( i_vert < num_vertices )
355 | {
356 | new_indices[index_pos] = 0;
357 | new_indices[index_pos+1] = i_vert -1;
358 | new_indices[index_pos+2] = i_vert;
359 |
360 | i_vert+= 1;
361 | index_pos+= 3;
362 | }
363 | if( tex != NULL )
364 | {
365 | SDL_RenderGeometry(renderer, tex, SDL_RenderParty_Vertex_List, num_vertices, new_indices, estimated_indices );
366 | }
367 | else
368 | {
369 | SDL_RenderGeometry(renderer, NULL, SDL_RenderParty_Vertex_List, num_vertices, new_indices, estimated_indices );
370 | }
371 | return estimated_indices;
372 | }
373 |
374 | bool SDL_RenderParty_Oval( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int x_radius,int y_radius,SDL_Color * oval_colour, int alpha, float start_angle, int texture_effect )
375 | {
376 | int point_count = SDL2_Party_Circle_Points;
377 | if( renderer == NULL || x_radius < 1 || y_radius < 1 || point_count < 3 )
378 | {
379 | return false;
380 | }
381 |
382 | start_angle -= 90.f;
383 | float end_angle = start_angle + 360.f;
384 |
385 | start_angle = start_angle * sdl_renderparty_math_radians_multiplier;
386 | end_angle = end_angle * sdl_renderparty_math_radians_multiplier;
387 |
388 | float step = (end_angle - start_angle) / (float)(point_count);
389 |
390 | float theta = start_angle;
391 |
392 | float vx = 0, vy = 0;
393 |
394 | int arc_i = 0;
395 | point_count+=2;
396 | SDL_Vertex line_render_points[ point_count ];
397 |
398 | vx = pos.x;
399 | vy = pos.y;
400 |
401 | float tex_coord_angle = 0; //0.f;
402 | line_render_points[ 0 ].position.x = pos.x;
403 | line_render_points[ 0 ].position.y = pos.y;
404 |
405 | if( oval_colour != NULL )
406 | {
407 | line_render_points[ 0 ].color.r = oval_colour->r;
408 | line_render_points[ 0 ].color.g = oval_colour->g;
409 | line_render_points[ 0 ].color.b = oval_colour->b;
410 | }
411 | else
412 | {
413 | line_render_points[0].color.r = 255;
414 | line_render_points[0].color.g = 255;
415 | line_render_points[0].color.b = 255;
416 | }
417 |
418 | line_render_points[ 0 ].color.a = alpha;
419 | line_render_points[ 0 ].tex_coord.x = 0.5f;
420 | line_render_points[ 0 ].tex_coord.y = 0.5f;
421 |
422 | theta+=step;
423 | tex_coord_angle += step;
424 |
425 | for( arc_i = 0; arc_i < point_count; arc_i+= 1)
426 | {
427 | vx = pos.x + SDL2_RenderParty_LengthdirX( x_radius/2.f, theta);
428 | vy = pos.y + SDL2_RenderParty_LengthdirY( y_radius/2.f, theta);
429 | line_render_points[arc_i].position.x = vx;
430 | line_render_points[arc_i].position.y = vy;
431 | if( oval_colour != NULL )
432 | {
433 | line_render_points[arc_i].color.r = oval_colour->r;
434 | line_render_points[arc_i].color.g = oval_colour->g;
435 | line_render_points[arc_i].color.b = oval_colour->b;
436 | }
437 | else
438 | {
439 | line_render_points[arc_i].color.r = 255;
440 | line_render_points[arc_i].color.g = 255;
441 | line_render_points[arc_i].color.b = 255;
442 | }
443 | line_render_points[arc_i].color.a = alpha;
444 |
445 | line_render_points[arc_i].tex_coord.x = 0.5f + SDL2_RenderParty_LengthdirX( 0.5f, tex_coord_angle);
446 | line_render_points[arc_i].tex_coord.y = 0.5f + SDL2_RenderParty_LengthdirY( 0.5f, tex_coord_angle);
447 | theta += step;
448 | tex_coord_angle += step;
449 | }
450 | SDL_RenderParty_Fans( renderer, tex, line_render_points, point_count, texture_effect, 0 );
451 | return true;
452 | }
453 |
454 | //This function assumes there are at least 4 vertices
455 | bool SDL_RenderParty_Quad( SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex * vertices, bool show_colors, bool update_tex_cords )
456 | {
457 | //This function assumes there are at least 4 vertices
458 | SDL_Vertex vert[4];
459 |
460 |
461 | vert[0].position.x = vertices[0].position.x;
462 | vert[0].position.y = vertices[0].position.y;
463 |
464 |
465 | vert[1].position.x = vertices[1].position.x;
466 | vert[1].position.y = vertices[1].position.y;
467 |
468 |
469 | vert[2].position.x = vertices[2].position.x;
470 | vert[2].position.y = vertices[2].position.y;
471 |
472 | vert[3].position.x = vertices[3].position.x;
473 | vert[3].position.y = vertices[3].position.y;
474 |
475 | //draw the entire texture, otherwise use previous vertice positions
476 | if( update_tex_cords )
477 | {
478 | vert[0].tex_coord.x = 0;
479 | vert[0].tex_coord.y = 0;
480 | vert[1].tex_coord.x = 1;
481 | vert[1].tex_coord.y = 0;
482 | vert[2].tex_coord.x = 1;
483 | vert[2].tex_coord.y = 1;
484 | vert[3].tex_coord.x = 0;
485 | vert[3].tex_coord.y = 1;
486 | }
487 |
488 | if( show_colors )
489 | {
490 | for( int i_col =0; i_col < 4; i_col+= 1 )
491 | {
492 | vert[i_col].color.r = vertices[i_col].color.r;
493 | vert[i_col].color.g = vertices[i_col].color.g;
494 | vert[i_col].color.b = vertices[i_col].color.b;
495 | vert[i_col].color.a = vertices[i_col].color.a;
496 | }
497 | }
498 |
499 |
500 | int new_indices[ 6];
501 | new_indices[0] = 1;
502 | new_indices[1] = 2;
503 | new_indices[2] = 3;
504 | new_indices[3] = 0;
505 | new_indices[4] = 1;
506 | new_indices[5] = 3;
507 |
508 | if( update_tex_cords )
509 | {
510 | return (SDL_RenderGeometry(renderer, tex, vert, 4, new_indices, 6 ) == 0 );
511 | }
512 | else
513 | {
514 | return (SDL_RenderGeometry(renderer, tex, vertices, 4, new_indices, 6 ) == 0 );
515 | }
516 | }
517 |
518 |
519 |
520 | bool SDL_RenderParty_Polygon( SDL_Renderer * renderer, SDL_Texture * tex, SDL_Point pos, int shape_length , int point_count, SDL_Color * shape_colour, int alpha, float start_angle, int texture_effect, int start_vertice_pos )
521 | {
522 | if( renderer == NULL || shape_length < 1 || point_count < 3 )
523 | {
524 | return false;
525 | }
526 |
527 | start_angle -= 90.f;
528 | float end_angle = start_angle + 360.f;
529 |
530 | start_angle = start_angle * sdl_renderparty_math_radians_multiplier;
531 | end_angle = end_angle * sdl_renderparty_math_radians_multiplier;
532 |
533 | float step = (end_angle - start_angle) / (float)(point_count);
534 |
535 | float theta = start_angle;
536 |
537 | float vx = 0, vy = 0;
538 |
539 | int arc_i = 0;
540 | point_count+=2;
541 | SDL_Vertex line_render_points[ point_count ];
542 |
543 | vx = pos.x;
544 | vy = pos.y;
545 |
546 | float tex_coord_angle = 0; //0.f;
547 | line_render_points[ 0 ].position.x = pos.x;
548 | line_render_points[ 0 ].position.y = pos.y;
549 |
550 | if( shape_colour != NULL )
551 | {
552 | line_render_points[ 0 ].color.r = shape_colour->r;
553 | line_render_points[ 0 ].color.g = shape_colour->g;
554 | line_render_points[ 0 ].color.b = shape_colour->b;
555 | }
556 | else
557 | {
558 | line_render_points[0].color.r = 255;
559 | line_render_points[0].color.g = 255;
560 | line_render_points[0].color.b = 255;
561 | }
562 |
563 | line_render_points[ 0 ].color.a = alpha;
564 | line_render_points[ 0 ].tex_coord.x = 0.5f;
565 | line_render_points[ 0 ].tex_coord.y = 0.5f;
566 |
567 | theta+=step;
568 | tex_coord_angle += step;
569 |
570 | for( arc_i = 0; arc_i < point_count; arc_i+= 1)
571 | {
572 | vx = pos.x + SDL2_RenderParty_LengthdirX( shape_length/2.f, theta);
573 | vy = pos.y + SDL2_RenderParty_LengthdirY( shape_length/2.f, theta);
574 | line_render_points[arc_i].position.x = vx;
575 | line_render_points[arc_i].position.y = vy;
576 | if( shape_colour != NULL )
577 | {
578 | line_render_points[arc_i].color.r = shape_colour->r;
579 | line_render_points[arc_i].color.g = shape_colour->g;
580 | line_render_points[arc_i].color.b = shape_colour->b;
581 | }
582 | else
583 | {
584 | line_render_points[arc_i].color.r = 255;
585 | line_render_points[arc_i].color.g = 255;
586 | line_render_points[arc_i].color.b = 255;
587 | }
588 | line_render_points[arc_i].color.a = alpha;
589 |
590 | line_render_points[arc_i].tex_coord.x = 0.5f + SDL2_RenderParty_LengthdirX( 0.5f, tex_coord_angle);
591 | line_render_points[arc_i].tex_coord.y = 0.5f + SDL2_RenderParty_LengthdirY( 0.5f, tex_coord_angle);
592 | theta += step;
593 | tex_coord_angle += step;
594 | }
595 | SDL_RenderParty_Fans( renderer, tex, line_render_points, point_count, texture_effect, 0 );
596 | return true;
597 | }
598 |
599 | bool SDL_RenderParty_SetCirclePoints( int new_circle_points )
600 | {
601 | if( new_circle_points < SDL2_RENDERPARTY_CIRCLE_POINT_MIN )
602 | {
603 | return false;
604 | }
605 | SDL2_Party_Circle_Points = new_circle_points;
606 | return true;
607 | }
608 |
609 | //int returns the amount of indices were rendered
610 | int SDL_RenderParty_Strips(SDL_Renderer *renderer, SDL_Texture *tex, const SDL_Vertex * vertices, int num_vertices, bool is_closed , int texture_effect, int start_vertice_pos )
611 | {
612 | if( start_vertice_pos < 0 )
613 | {
614 | start_vertice_pos = 0;
615 | }
616 |
617 | if( num_vertices < 3)
618 | {
619 | return 0;
620 | }
621 | else if( num_vertices == 3)
622 | {
623 | SDL_RenderGeometry(renderer, tex, vertices, num_vertices, NULL, 0);
624 | return 3;
625 | }
626 |
627 | unsigned int estimated_indices = 3 + (num_vertices-3)*3;
628 | if( is_closed)
629 | {
630 | //add 3 more indices for connecting triangle
631 | estimated_indices += 3;
632 | }
633 | int new_indices[ estimated_indices];
634 |
635 | SDL_FPoint tex_coords_default[4];
636 | tex_coords_default[0].x = 0;
637 | tex_coords_default[0].y = 0;
638 |
639 |
640 | tex_coords_default[1].x = 1;
641 | tex_coords_default[1].y = 0;
642 |
643 | tex_coords_default[2].x = 1;
644 | tex_coords_default[2].y = 1;
645 |
646 | tex_coords_default[3].x = 0;
647 | tex_coords_default[3].y = 1;
648 |
649 | int i_vert_place = 0;
650 |
651 |
652 |
653 | while(num_vertices >= sdl_party_max_vertex_count/3 )
654 | {
655 | SDL_RenderParty_Strips( renderer, tex, vertices, sdl_party_max_vertex_count -1, is_closed , texture_effect, i_vert_place );
656 | num_vertices -= sdl_party_max_vertex_count-1;
657 | i_vert_place += sdl_party_max_vertex_count -1;
658 | }
659 |
660 | int vert_pos_offset = start_vertice_pos;
661 |
662 |
663 | float found_max_w = 0;
664 | float found_max_h = 0;
665 |
666 | //Expensive to do a double-loop and comparision perhaps...
667 | if( texture_effect == sdl_partyeffect_texture_mapped )
668 | {
669 | for( int i_tex_vert = 0; i_tex_vert < num_vertices; i_tex_vert+= 1 )
670 | {
671 | if( vertices[vert_pos_offset].position.x > found_max_w )
672 | {
673 | found_max_w = vertices[vert_pos_offset].position.x;
674 | }
675 |
676 | if( vertices[vert_pos_offset].position.y > found_max_h )
677 | {
678 | found_max_h = vertices[vert_pos_offset].position.y;
679 | }
680 | vert_pos_offset+= 1;
681 | }
682 |
683 | }
684 |
685 | vert_pos_offset = start_vertice_pos;
686 | for( int i_vert = 0; i_vert < num_vertices; i_vert += 1 )
687 | {
688 | SDL_RenderParty_Vertex_List[i_vert].color.r = vertices[vert_pos_offset].color.r;
689 | SDL_RenderParty_Vertex_List[i_vert].color.g = vertices[vert_pos_offset].color.g;
690 | SDL_RenderParty_Vertex_List[i_vert].color.b = vertices[vert_pos_offset].color.b;
691 | SDL_RenderParty_Vertex_List[i_vert].color.a = vertices[vert_pos_offset].color.a;
692 | SDL_RenderParty_Vertex_List[i_vert].position.x = vertices[vert_pos_offset].position.x;
693 | SDL_RenderParty_Vertex_List[i_vert].position.y = vertices[vert_pos_offset].position.y;
694 |
695 | if( tex != NULL )
696 | {
697 | switch( texture_effect )
698 | {
699 | case sdl_partyeffect_additive:
700 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = (float)i_vert/(float)num_vertices;
701 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = (float)i_vert/(float)num_vertices;
702 | break;
703 |
704 | case sdl_partyeffect_subtractive:
705 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 1.f - (float)i_vert/(float)num_vertices;
706 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 1.f -(float)i_vert/(float)num_vertices;
707 | break;
708 |
709 | case sdl_partyeffect_bottom_up:
710 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = (float)i_vert/(float)num_vertices;
711 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 1.f -(float)i_vert/(float)num_vertices;
712 | break;
713 |
714 | case sdl_partyeffect_inverted:
715 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 1.f-(float)i_vert/(float)num_vertices;
716 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = (float)i_vert/(float)num_vertices;
717 | break;
718 |
719 | case sdl_partyeffect_full_inverted:
720 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = tex_coords_default[ num_vertices - i_vert_place -1].x ;
721 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = tex_coords_default[ num_vertices - i_vert_place -1].y ;
722 | break;
723 |
724 | case sdl_partyeffect_texture_mapped:
725 | if( found_max_w == 0)
726 | {
727 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = tex_coords_default[i_vert_place].x ;
728 |
729 | }
730 | else
731 | {
732 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = vertices[vert_pos_offset].position.x / found_max_w;
733 | }
734 | if( found_max_h == 0)
735 | {
736 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = tex_coords_default[i_vert_place].y ;
737 | }
738 | else
739 | {
740 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = vertices[vert_pos_offset].position.y / found_max_h;
741 | }
742 | break;
743 |
744 | default:
745 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = tex_coords_default[i_vert_place].x ;
746 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = tex_coords_default[i_vert_place].y ;
747 | break;
748 | }
749 | }
750 | else
751 | {
752 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.x = 0;
753 | SDL_RenderParty_Vertex_List[i_vert].tex_coord.y = 0;
754 | }
755 | i_vert_place+= 1;
756 | vert_pos_offset+= 1 ;
757 | if( i_vert_place >=3 )
758 | {
759 | i_vert_place = 0;
760 | }
761 | }
762 |
763 | int i_vert = 3;
764 |
765 |
766 | new_indices[0] = 0;
767 | new_indices[1] = 1;
768 | new_indices[2] = 2;
769 |
770 | int index_pos = 3;
771 | while( i_vert < num_vertices )
772 | {
773 | new_indices[index_pos] = i_vert ;
774 | new_indices[index_pos+1] = i_vert -1;
775 | new_indices[index_pos+2] = i_vert -2;
776 | i_vert+= 1 ;
777 | index_pos += 3;
778 | }
779 | if( is_closed )
780 | {
781 | new_indices[index_pos] = num_vertices -2;
782 | new_indices[index_pos+1] = num_vertices -1;
783 | new_indices[index_pos+2] = 0;
784 | }
785 | if( tex != NULL )
786 | {
787 | SDL_RenderGeometry(renderer, tex, SDL_RenderParty_Vertex_List, num_vertices, new_indices, estimated_indices );
788 | }
789 | else
790 | {
791 | SDL_RenderGeometry(renderer, NULL, SDL_RenderParty_Vertex_List, num_vertices, new_indices, estimated_indices );
792 | }
793 | return estimated_indices;
794 | }
795 |
796 | #endif // SDL2_RENDERPARTY_IMPLEMENTATION
797 |
798 |
799 |
800 |
801 |
--------------------------------------------------------------------------------