09f7f97e21e36492cf11f3654e346519025aab4e
[retroray] / src / rend.c
1 /*
2 RetroRay - integrated standalone vintage modeller/renderer
3 Copyright (C) 2023  John Tsiombikas <nuclear@mutantstargoat.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18 #include "rend.h"
19 #include "rt.h"
20
21 struct img_pixmap renderbuf;
22 struct img_pixmap dbgimg;
23
24 static int rx, ry, rwidth, rheight;
25 static int roffs;
26 static int xstep, ystep;
27
28 int rend_init(void)
29 {
30         img_init(&renderbuf);
31
32         img_init(&dbgimg);
33         img_load(&dbgimg, "data/foo.jpg");
34         img_convert(&dbgimg, IMG_FMT_RGBA32);
35
36         rx = ry = rwidth = rheight = roffs = 0;
37         return 0;
38 }
39
40 void rend_destroy(void)
41 {
42         img_destroy(&renderbuf);
43 }
44
45 void rend_size(int xsz, int ysz)
46 {
47         if(xsz != renderbuf.width || ysz != renderbuf.height) {
48                 img_set_pixels(&renderbuf, xsz, ysz, IMG_FMT_RGBA32, 0);
49         }
50 }
51
52 void rend_begin(int x, int y, int w, int h)
53 {
54         int i;
55         uint32_t *ptr;
56
57         if(w == 0 || h == 0) {
58                 rx = ry = 0;
59                 rwidth = renderbuf.width;
60                 rheight = renderbuf.height;
61         } else {
62                 rx = x;
63                 ry = y;
64                 rwidth = w;
65                 rheight = h;
66         }
67         roffs = ry * renderbuf.width + rx;
68
69         xstep = rwidth;
70         ystep = rheight;
71
72         ptr = (uint32_t*)renderbuf.pixels + roffs;
73         for(i=0; i<rheight; i++) {
74                 memset(ptr, 0, rwidth * sizeof *ptr);
75                 ptr += renderbuf.width;
76         }
77 }
78
79 static void fillrect(uint32_t *fb, int x, int y, int w, int h, uint32_t c)
80 {
81         int i, j;
82
83         fb += y * renderbuf.width + x;
84         for(i=0; i<h; i++) {
85                 for(j=0; j<w; j++) {
86                         fb[j] = c;
87                 }
88                 fb += renderbuf.width;
89         }
90 }
91
92 int render(uint32_t *fb)
93 {
94         int i, j, offs;
95         uint32_t *src, *dest;
96
97         src = (uint32_t*)dbgimg.pixels + roffs;
98         dest = (uint32_t*)renderbuf.pixels + roffs;
99         if(fb) fb += roffs;
100
101         for(i=0; i<rheight; i+=ystep) {
102                 for(j=0; j<rwidth; j+=xstep) {
103                         offs = i * renderbuf.width + j;
104                         dest[offs] = src[offs];
105                         if(fb) {
106                                 fb[offs] = src[offs];
107                                 fillrect(fb, j, i, xstep, ystep, src[offs]);
108                         }
109                 }
110         }
111
112         xstep >>= 1;
113         ystep >>= 1;
114
115         if((xstep | ystep) >= 1) {
116                 return 1;
117         }
118         return 0;
119 }