Skip to content
Snippets Groups Projects
Commit 0786bd9e authored by sr1g19's avatar sr1g19
Browse files

Upload New File

parent 071b2d6e
Branches
No related tags found
No related merge requests found
#include "rasterize.h"
inline float removeSign(float f){
if(f<0)
return 0;
return f;
}
_2x1Matrix transpose_map(_3x3Matrix m1, _3x1Matrix m2){
_2x1Matrix ma = {
(m1.a11 * m2.a11) + (m1.a12 * m2.a21) + (m1.a13 * m2.a31),
(m1.a21 * m2.a11) + (m1.a22 * m2.a21) + (m1.a23 * m2.a31),
};
return ma;
}
rectangle getXYBound2d(tri2d t){
uint16_t xHigh = (uint16_t)fmax(fmax(t.p0.a11,t.p1.a11),t.p2.a11);
uint16_t xLow = (uint16_t)fmin(fmin(t.p0.a11,t.p1.a11),t.p2.a11);
uint16_t yHigh = (uint16_t)fmax(fmax(t.p0.a21,t.p1.a21),t.p2.a21);
uint16_t yLow = (uint16_t)fmin(fmin(t.p0.a21,t.p1.a21),t.p2.a21);
rectangle r = {xLow, xHigh+1, yLow, yHigh+1};
return r;
}
rectangle getXYBound2dRect(rect2d t){
uint16_t xLow = (uint16_t)fmin(fmin(fmin(removeSign(t.p0.a11),removeSign(t.p1.a11)),
removeSign(t.p2.a11)),removeSign(t.p3.a11));
uint16_t xHigh = (uint16_t)fmax(fmax(fmax(removeSign(t.p0.a11),removeSign(t.p1.a11)),
removeSign(t.p2.a11)),removeSign(t.p3.a11));
uint16_t yLow = (uint16_t)fmin(fmin(fmin(removeSign(t.p0.a21),removeSign(t.p1.a21)),
removeSign(t.p2.a21)),removeSign(t.p3.a21));
uint16_t yHigh = (uint16_t)fmax(fmax(fmax(removeSign(t.p0.a21),removeSign(t.p1.a21)),
removeSign(t.p2.a21)),removeSign(t.p3.a21));
rectangle r = {xLow, xHigh+1, yLow, yHigh+1};
return r;
}
rectangle getXYBound3d(tri3d t){
uint16_t xHigh = (uint16_t)fmax(fmax(removeSign(t.p0.a11),removeSign(t.p1.a11)),removeSign(t.p2.a11));
uint16_t xLow = (uint16_t)fmin(fmin(removeSign(t.p0.a11),removeSign(t.p1.a11)),removeSign(t.p2.a11));
uint16_t yHigh = (uint16_t)fmax(fmax(removeSign(t.p0.a21),removeSign(t.p1.a21)),removeSign(t.p2.a21));
uint16_t yLow = (uint16_t)fmin(fmin(removeSign(t.p0.a21),removeSign(t.p1.a21)),removeSign(t.p2.a21));
rectangle r = {xLow, xHigh+1, yLow, yHigh+1};
return r;
}
void affineRasterize(_2x2Matrix m, PGM_P imgdata, rectangle imgRegion, int16_t dispX, int16_t dispY){ //Rectangle affine without Composites
rect2d t = {{imgRegion.left, imgRegion.top}, {imgRegion.right, imgRegion.top},
{imgRegion.right, imgRegion.bottom}, {imgRegion.left, imgRegion.bottom}};
_2x2Matrix invM = inverse_2x2(m);
rect2d tP = transpose2dRect(t, m);
rectangle r = getXYBound2dRect(tP);
r.bottom = removeSign((((int16_t) r.bottom) + dispY));
r.right = removeSign((((int16_t) r.right) + dispX));
uint16_t imgwidth = imgRegion.right-imgRegion.left;
uint16_t imgheight = imgRegion.bottom-imgRegion.top;
rectangleInRegion(&r);
int16_t width = r.right - r.left;
int16_t height = r.bottom - r.top;
char* targetptr = imgdata;
setupDraw(r);
uint16_t pixVal;
for(int16_t y=-dispY; y<=height-dispY; y++)
for(int16_t x=-dispX; x<=width-dispX; x++){
_2x1Matrix p = {x,y};
_2x1Matrix pT = transpose_2x2(invM, p);
if(pT.a11 >= 0 && pT.a11 <= imgwidth
&& pT.a21 >= 0 && pT.a21 <= imgheight){
uint16_t xComp = (uint16_t) (removeSign(pT.a11));
uint16_t yComp = (uint16_t) (removeSign(pT.a21));
targetptr = imgdata + (2*(xComp+(yComp*(imgwidth+1))));
pixVal = pgm_read_word(targetptr);
} else {
pixVal = 0;
}
write_data16(pixVal);
}
}
void perspectiveRasterize(tri3d t, tri2d tuv, PGM_P imgdata, rectangle imgRegion) {
_3x3Matrix triangleMat = combine(t.p0, t.p1, t.p2);
_3x3Matrix uvMat = combine2d(tuv.p0, tuv.p1, tuv.p2);
_3x3Matrix invMTM = inverse_3x3(triangleMat);
_3x3Matrix mapping = multiply_3x3(uvMat, invMTM);
plane3d pl = getPlane(t);
rectangle r = getXYBound3d(t);
uint16_t imgwidth = imgRegion.right-imgRegion.left;
uint16_t imgheight = imgRegion.bottom-imgRegion.top;
rectangleInRegion(&r);
uint16_t width = r.right - r.left;
uint16_t height = r.bottom - r.top;
tri2d t2d = {{t.p0.a11,t.p0.a21},
{t.p1.a11,t.p1.a21},
{t.p2.a11,t.p2.a21}};
char* targetptr = imgdata;
setupDraw(r);
uint16_t pixVal;
for (uint16_t y = r.top; y <= r.bottom; y++) {
for (uint16_t x = r.left; x <= r.right; x++) {
_2x1Matrix point = {x, y};
_2x1Matrix tPoint = transpose_2x3(mapping, point);
if(inTriangle(tPoint.a11, tPoint.a21, tuv)){
uint16_t xComp = (uint16_t) (removeSign(tPoint.a11));
uint16_t yComp = (uint16_t) (removeSign(tPoint.a21));
targetptr = imgdata + (2*(xComp+(yComp*(imgwidth+1))));
pixVal = pgm_read_word(targetptr);
} else {
pixVal = 12;
}
write_data16(pixVal);
}
}
}
void perspectiveRasterizeComposite(tri3d t, tri2d tuv, PGM_P imgdata, rectangle imgRegion, float composite){
_3x3Matrix triangleMat = combine(t.p0, t.p1, t.p2);
_3x3Matrix uvMat = combine2d(tuv.p0, tuv.p1, tuv.p2);
_3x3Matrix invMTM = inverse_3x3(triangleMat);
_3x3Matrix mapping = multiply_3x3(uvMat, invMTM);
plane3d pl = getPlane(t);
rectangle r = getXYBound3d(t);
uint16_t imgwidth = imgRegion.right-imgRegion.left;
uint16_t imgheight = imgRegion.bottom-imgRegion.top;
rectangleInRegion(&r);
uint16_t width = r.right - r.left;
uint16_t height = r.bottom - r.top;
tri2d t2d = {{t.p0.a11,t.p0.a21},
{t.p1.a11,t.p1.a21},
{t.p2.a11,t.p2.a21}};
char* targetptr = imgdata;
uint16_t pixVal;
if(composite <= 0 || composite > 1.0f)
return;
for (uint16_t y = 0; y <= r.bottom-r.top; y++) {
uint16_t yVal = y + r.top;
rectangle rReg;
uint16_t topR = y + r.top;
write_cmd(COLUMN_ADDRESS_SET);
write_data16(r.left);
write_data16(r.right);
write_cmd(PAGE_ADDRESS_SET);
write_data16(topR);
write_data16(topR);
write_cmd(MEMORY_READ);
uint16_t colorValues[width + 1];
read_data(); //Throw away a byte
for (uint16_t x = 0; x <= r.right-r.left; x++) {
unsigned char r = read_data() >> 2;
unsigned char g = read_data() >> 2;
unsigned char b = read_data() >> 2;
uint16_t value = (((uint16_t)b)>>1) + (((uint16_t)g) << 5) + ((((uint16_t)r)>>1) << 11);
colorValues[x] = value; //It'd be quick to not convert but requires bigger cache, makes this less memory heavy
}
write_cmd(MEMORY_WRITE);
for (uint16_t x = 0; x <= r.right-r.left; x++) {
uint16_t xVal = x + r.left;
_2x1Matrix point = {xVal, yVal};
_2x1Matrix tPoint = transpose_2x3(mapping, point);
if(inTriangle(tPoint.a11, tPoint.a21, tuv)){
uint16_t xComp = (uint16_t) (removeSign(tPoint.a11));
uint16_t yComp = (uint16_t) (removeSign(tPoint.a21));
targetptr = imgdata + (2*(xComp+(yComp*(imgwidth+1))));
pixVal = pgm_read_word(targetptr);
if(pixVal == TRANSPARENTCOLOR){
pixVal = colorValues[x];
} else if(composite != 1.0f){
unsigned char r = ((unsigned char) ((((colorValues[x]>>11) & 31) * (1.0 - composite)) + (((pixVal>>11) & 31) * (composite)))) & 31;
unsigned char g = ((unsigned char) ((((colorValues[x]>>5) & 63) * (1.0 - composite)) + (((pixVal>>5) & 63) * (composite)))) & 63;
unsigned char b = ((unsigned char) (((colorValues[x] & 31) * (1.0 - composite)) + ((pixVal & 31) * (composite)))) & 31;
pixVal = ((uint16_t)b) + (((uint16_t)g) << 5) + ((((uint16_t)r)) << 11);
}
} else {
pixVal = colorValues[x];
}
write_data16(pixVal);
}
}
}
//Credit:Kornel Kisielewicz, https://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle
float triSign (_2x1Matrix p0, _2x1Matrix p1, _2x1Matrix p2){
return ((p0.a11 - p2.a11) * (p1.a21 - p2.a21)) - ((p1.a11 - p2.a11) * (p0.a21 - p2.a21));
}
plane3d getPlane(tri3d t){
_3x1Matrix Vp2p0 = minus_3x1(t.p2, t.p0);
_3x1Matrix Vp1p0 = minus_3x1(t.p1, t.p0);
_3x1Matrix crossVectors = crossProduct(Vp1p0,Vp2p0);
plane3d p = {crossVectors, t.p0};
return p;
}
float getZ(float x, float y, plane3d p){
float z = p.anchor.a31 + ((-(p.gr.a11*(x-p.anchor.a11))-(p.gr.a21*(y-p.anchor.a21)))/p.gr.a31);
return z;
}
unsigned char inTriangle(float x, float y, tri2d t){
_2x1Matrix px = {x, y};
float d1 = triSign(px, t.p0, t.p1);
float d2 = triSign(px, t.p1, t.p2);
float d3 = triSign(px, t.p2, t.p0);
unsigned char hasNegative = (d1 < 0) || (d2 < 0) || (d3 < 0);
unsigned char hasPositive = (d1 > 0) || (d2 > 0) || (d3 > 0);
return !(hasNegative && hasPositive);
}
rect2d transpose2dRect(rect2d t, _2x2Matrix m){
rect2d tP;
tP.p0 = transpose_2x2(m, t.p0);
tP.p1 = transpose_2x2(m, t.p1);
tP.p2 = transpose_2x2(m, t.p2);
tP.p3 = transpose_2x2(m, t.p3);
return tP;
}
tri3d seperate(_3x3Matrix m){
_3x1Matrix p0 = {m.a11, m.a21, m.a31};
_3x1Matrix p1 = {m.a12, m.a22, m.a32};
_3x1Matrix p2 = {m.a13, m.a23, m.a33};
tri3d t = {p0, p1, p2};
return t;
}
tri3d transpose3dTri(tri3d t, _3x3Matrix m) {
_3x3Matrix m1 = combine(t.p0, t.p1, t.p2);
_3x3Matrix tP = multiply_3x3(m, m1);
return seperate(tP);
}
_3x3Matrix combine2d(_2x1Matrix m1, _2x1Matrix m2, _2x1Matrix m3){
_3x3Matrix m = {m1.a11, m2.a11, m3.a11,
m1.a21, m2.a21, m3.a21,
0, 0, 0};
return m;
}
_2x1Matrix transpose_2x3(_3x3Matrix m1, _2x1Matrix m2){
_2x1Matrix ma = {
(m1.a11 * m2.a11) + (m1.a12 * m2.a21) + m1.a13,
(m1.a21 * m2.a11) + (m1.a22 * m2.a21) + m1.a23,
};
return ma;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment