├── 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 | 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SDL2_RenderParty 2 | 3 | ![image](https://github.com/pawbyte/SDL2_RenderParty/blob/main/images/sdl2_renderparty_logo.png?raw=true) 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 | ![image](https://raw.githubusercontent.com/pawbyte/SDL2_Render_Party/main/examples/SDL2_Render_Party_White_Polygon_Test.gif) 25 | 26 | 27 | 28 | Example Project Running on FreeBSD( Thanks high_on_tanor for testing): 29 | ![image](https://github.com/pawbyte/SDL2_RenderParty/blob/main/images/sdl2_renderparty_example_screenshot_freebsd.png) 30 | 31 | Rendered Texture as polygon with sides increasing: 32 | ![image](https://github.com/pawbyte/SDL2_RenderParty/blob/main/examples/sdl2_render_party_mk_spinner_polygon.gif?raw=true) 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 | --------------------------------------------------------------------------------