3 * CS5600 University of Utah
5 * mcgarvey@eng.utah.edu
21 int left
, right
, bottom
, top
;
28 pixmap_t
* pixmap_alloc(int width
, int height
, color_t fill
)
30 assert(0 < width
&& 0 < height
&& "zero-dimension pixmap not allowed");
31 size_t size
= width
* height
;
33 pixmap_t
* p
= (pixmap_t
*)mem_alloc(sizeof(pixmap_t
));
34 p
->pixels
= (color_t
*)mem_alloc(sizeof(color_t
) * size
);
37 p
->left
= p
->bottom
= 0;
40 pixmap_clear(p
, fill
);
44 void pixmap_destroy(pixmap_t
* p
)
51 void pixmap_clear(pixmap_t
* p
, color_t fill
)
53 size_t size
= p
->w
* p
->h
;
54 for (int i
= 0; i
< size
; ++i
) {
60 static void _pixmap_set_transformation(pixmap_t
* p
)
63 * Just including a viewport transformation in the final transformation.
64 * This could probably be faster by separating this out.
66 mat_t viewport
= MAT_VIEWPORT(p
->left
, p
->bottom
, p
->right
- p
->left
, p
->top
- p
->bottom
);
67 p
->final
= mat_mult(p
->projection
, p
->modelview
);
68 p
->final
= mat_mult(viewport
, p
->final
);
72 void pixmap_viewport(pixmap_t
* p
, int x
, int y
, int width
, int height
)
78 _pixmap_set_transformation(p
);
81 void pixmap_modelview(pixmap_t
* p
, const mat_t
* transform
)
83 p
->modelview
= *transform
;
84 _pixmap_set_transformation(p
);
87 void pixmap_projection(pixmap_t
* p
, const mat_t
* transform
)
89 p
->projection
= *transform
;
90 _pixmap_set_transformation(p
);
94 #define _CHECK_WRITE(X) if ((X) <= 0) goto fail
96 int pixmap_export_ppm(const pixmap_t
* p
, const char* filename
)
98 FILE* file
= fopen(filename
, "w");
100 fail
: fprintf(stderr
, "Cannot write to %s: %s\n", filename
, strerror(errno
));
104 _CHECK_WRITE(fprintf(file
, "P3\n%u %u\n255\n", p
->w
, p
->h
));
105 for (int y
= (int)p
->h
- 1; y
>= 0; --y
) {
106 for (int x
= 0; x
< p
->w
; ++x
) {
108 color_split(p
->pixels
[y
* p
->w
+ x
], &r
, &g
, &b
, NULL
);
109 _CHECK_WRITE(fprintf(file
, "%hhu %hhu %hhu\n", r
, g
, b
));
117 int pixmap_export_bmp(const pixmap_t
* p
, const char* filename
)
120 * This function was adapted from sample code provided with the assignment
123 FILE* file
= fopen(filename
, "wb");
125 fail
: fprintf(stderr
, "Cannot write to %s: %s\n", filename
, strerror(errno
));
129 uint16_t magicNumber
= 0x4D42;
130 uint16_t reserved0
= 0;//0x4D41;
131 uint16_t reserved1
= 0;//0x5454;
132 uint32_t dataOffset
= 54;
133 uint32_t infoHeaderSize
= 40;
134 uint32_t width
= p
->w
;
135 uint32_t height
= p
->h
;
136 uint16_t colorPlanes
= 1;
137 uint16_t bitsPerPixel
= 32;
138 uint32_t compression
= 0;
139 uint32_t dataSize
= width
* height
* bitsPerPixel
/ 8;
140 uint32_t horizontalResolution
= 2835;
141 uint32_t verticalResolution
= 2835;
142 uint32_t paletteColorCount
= 0;
143 uint32_t importantPaletteColorCount
= 0;
144 uint32_t fileSize
= 54 + dataSize
;
147 * Check the return values to avoid loud warnings.
149 _CHECK_WRITE(fwrite(&magicNumber
, sizeof(magicNumber
), 1, file
));
150 _CHECK_WRITE(fwrite(&fileSize
, sizeof(fileSize
), 1, file
));
151 _CHECK_WRITE(fwrite(&reserved0
, sizeof(reserved0
), 1, file
));
152 _CHECK_WRITE(fwrite(&reserved1
, sizeof(reserved1
), 1, file
));
153 _CHECK_WRITE(fwrite(&dataOffset
, sizeof(dataOffset
), 1, file
));
154 _CHECK_WRITE(fwrite(&infoHeaderSize
, sizeof(infoHeaderSize
), 1, file
));
155 _CHECK_WRITE(fwrite(&width
, sizeof(width
), 1, file
));
156 _CHECK_WRITE(fwrite(&height
, sizeof(height
), 1, file
));
157 _CHECK_WRITE(fwrite(&colorPlanes
, sizeof(colorPlanes
), 1, file
));
158 _CHECK_WRITE(fwrite(&bitsPerPixel
, sizeof(bitsPerPixel
), 1, file
));
159 _CHECK_WRITE(fwrite(&compression
, sizeof(compression
), 1, file
));
160 _CHECK_WRITE(fwrite(&dataSize
, sizeof(dataSize
), 1, file
));
161 _CHECK_WRITE(fwrite(&horizontalResolution
, sizeof(horizontalResolution
), 1, file
));
162 _CHECK_WRITE(fwrite(&verticalResolution
, sizeof(verticalResolution
), 1, file
));
163 _CHECK_WRITE(fwrite(&paletteColorCount
, sizeof(paletteColorCount
), 1, file
));
164 _CHECK_WRITE(fwrite(&importantPaletteColorCount
, sizeof(importantPaletteColorCount
), 1, file
));
166 size_t size
= width
* height
;
167 for (int i
= 0; i
< size
; ++i
)
169 rgbachan_t a
, r
, g
, b
;
170 color_split(p
->pixels
[i
], &r
, &g
, &b
, &a
);
171 uint32_t argb
= PACK(argb
, 3, a
);
172 argb
= PACK(argb
, 2, r
);
173 argb
= PACK(argb
, 1, g
);
174 argb
= PACK(argb
, 0, b
);
175 _CHECK_WRITE(fwrite(&argb
, sizeof(argb
), 1, file
));
183 void pixmap_draw_tri(pixmap_t
* p
, const tri_t
* triangle
)
185 tri_t t
= tri_transform(*triangle
, p
->final
);
187 for (int y
= p
->bottom
; y
< p
->top
; ++y
) {
188 for (int x
= p
->left
; x
< p
->right
; ++x
) {
189 vec_t pt
= vec_new((scal_t
)x
, (scal_t
)y
, S(0.0));
190 vec_t b
= tri_barycentric(&t
, pt
);
191 if (vec_is_barycentric(b
)) {
192 color_t
* c
= p
->pixels
+ y
* p
->w
+ x
;
193 color_t color
= color_new(
194 t
.a
.c
.r
* b
.x
+ t
.b
.c
.r
* b
.y
+ t
.c
.c
.r
* b
.z
,
195 t
.a
.c
.g
* b
.x
+ t
.b
.c
.g
* b
.y
+ t
.c
.c
.g
* b
.z
,
196 t
.a
.c
.b
* b
.x
+ t
.b
.c
.b
* b
.y
+ t
.c
.c
.b
* b
.z
,