2 #include "system/stacktrace.h"
6 #include "system/log.h"
8 int draw_triangle(SDL_Renderer *render,
13 if (SDL_RenderDrawLine(render,
17 (int) roundf(t.p2.y)) < 0) {
18 log_fail("SDL_RenderDrawLine: %s\n", SDL_GetError());
22 if (SDL_RenderDrawLine(render,
26 (int) roundf(t.p3.y)) < 0) {
27 log_fail("SDL_RenderDrawLine: %s\n", SDL_GetError());
31 if (SDL_RenderDrawLine(render,
35 (int) roundf(t.p1.y)) < 0) {
36 log_fail("SDL_RenderDrawLine: %s\n", SDL_GetError());
43 static int fill_bottom_flat_triangle(SDL_Renderer *render,
48 const float invslope1 = (t.p2.x - t.p1.x) / (t.p2.y - t.p1.y);
49 const float invslope2 = (t.p3.x - t.p1.x) / (t.p3.y - t.p1.y);
51 const int y0 = (int) roundf(t.p1.y);
52 const int y1 = (int) roundf(t.p2.y);
57 for (int scanline = y0; scanline < y1; scanline++) {
58 if (SDL_RenderDrawLine(render,
72 static int fill_top_flat_triangle(SDL_Renderer *render,
77 const float invslope1 = (t.p3.x - t.p1.x) / (t.p3.y - t.p1.y);
78 const float invslope2 = (t.p3.x - t.p2.x) / (t.p3.y - t.p2.y);
80 const int y0 = (int) roundf(t.p3.y);
81 const int y1 = (int) roundf(t.p1.y);
86 for (int scanline = y0; scanline > y1; --scanline) {
87 if (SDL_RenderDrawLine(render,
102 int fill_triangle(SDL_Renderer *render,
105 t = triangle_sorted_by_y(t);
107 if (fabs(t.p2.y - t.p3.y) < 1e-6) {
108 if (fill_bottom_flat_triangle(render, t) < 0) {
111 } else if (fabs(t.p1.y - t.p2.y) < 1e-6) {
112 if (fill_top_flat_triangle(render, t) < 0) {
116 const Vec2f p4 = vec(t.p1.x + ((t.p2.y - t.p1.y) / (t.p3.y - t.p1.y)) * (t.p3.x - t.p1.x), t.p2.y);
118 if (fill_bottom_flat_triangle(render, triangle(t.p1, t.p2, p4)) < 0) {
122 if (fill_top_flat_triangle(render, triangle(t.p2, p4, t.p3)) < 0) {
126 if (SDL_RenderDrawLine(render,
127 (int) roundf(t.p2.x),
128 (int) roundf(t.p2.y),
130 (int) roundf(p4.y)) < 0) {
138 int fill_rect(SDL_Renderer *render, Rect r, Color c)
140 const SDL_Rect sdl_rect = rect_for_sdl(r);
141 const SDL_Color sdl_color = color_for_sdl(c);
143 if (SDL_SetRenderDrawColor(
145 sdl_color.r, sdl_color.g,
146 sdl_color.b, sdl_color.a) < 0) {
147 log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
151 if (SDL_RenderFillRect(render, &sdl_rect) < 0) {
152 log_fail("SDL_RenderFillRect: %s\n");
160 * Return the pixel value at (x, y)
161 * NOTE: The surface must be locked before calling this!
163 Uint32 getpixel(SDL_Surface *surface, int x, int y)
165 int bpp = surface->format->BytesPerPixel;
166 /* Here p is the address to the pixel we want to retrieve */
167 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
177 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
178 return (Uint32) p[0] << 16 | (Uint32) p[1] << 8 | (Uint32) p[2];
180 return (Uint32) p[0] | (Uint32) p[1] << 8 | (Uint32) p[2] << 16;
186 return 0; /* shouldn't happen, but avoids warnings */
191 * Set the pixel at (x, y) to the given value
192 * NOTE: The surface must be locked before calling this!
194 void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
196 int bpp = surface->format->BytesPerPixel;
197 /* Here p is the address to the pixel we want to set */
198 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
202 *(Uint32*) p = pixel;
206 *(Uint16 *)p = (Uint16) pixel;
210 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
211 p[0] = (pixel >> 16) & 0xff;
212 p[1] = (pixel >> 8) & 0xff;
216 p[1] = (pixel >> 8) & 0xff;
217 p[2] = (pixel >> 16) & 0xff;
222 *(Uint32 *)p = pixel;