Fixed a bug where texture coordinates and the coordinate system didnt match the expectations

This commit is contained in:
Krzosa Karol
2022-02-15 20:59:22 +01:00
parent d69180dbe6
commit 2680af2632
2 changed files with 59 additions and 35 deletions

View File

@@ -12,24 +12,37 @@
struct Face { struct Face {
int p[3]; int p[3];
Vec2 tex[3];
}; };
GLOBAL Vec3 cube_vertices[] = { Vec3 cube_vertices[] = {
{-1,1,1}, {1,1,1}, {1,-1,1}, {-1,-1,1}, {-1, -1,-1},
{-1,1,-1}, {1,1,-1}, {1,-1,-1}, {-1,-1,-1}, {-1, 1, -1},
{1, 1, -1},
{1, -1, -1},
{1, 1, 1},
{1, -1, 1},
{-1, 1, 1},
{-1, -1,1},
}; };
GLOBAL Face cube_faces[] = { Face cube_faces[] = {
{4,1,2}, {4,2,3}, {{1, 2, 3}, {{ 0, 0 }, { 0, 1 }, { 1, 1 }}, },
{8,4,3}, {8,3,7}, {{1, 3, 4}, {{ 0, 0 }, { 1, 1 }, { 1, 0 }}, },
{8,5,1}, {8,1,4}, {{4, 3, 5}, {{ 0, 0 }, { 0, 1 }, { 1, 1 }}, },
{3,2,6}, {3,6,7}, {{4, 5, 6}, {{ 0, 0 }, { 1, 1 }, { 1, 0 }}, },
{7,6,5}, {7,5,8}, {{6, 5, 7}, {{ 0, 0 }, { 0, 1 }, { 1, 1 }}, },
{1,5,6}, {1,6,2} {{6, 7, 8}, {{ 0, 0 }, { 1, 1 }, { 1, 0 }}, },
{{8, 7, 2}, {{ 0, 0 }, { 0, 1 }, { 1, 1 }}, },
{{8, 2, 1}, {{ 0, 0 }, { 1, 1 }, { 1, 0 }}, },
{{2, 7, 5}, {{ 0, 0 }, { 0, 1 }, { 1, 1 }}, },
{{2, 5, 3}, {{ 0, 0 }, { 1, 1 }, { 1, 0 }}, },
{{6, 8, 1}, {{ 0, 0 }, { 0, 1 }, { 1, 1 }}, },
{{6, 1, 4}, {{ 0, 0 }, { 1, 1 }, { 1, 0 }}, }
}; };
FUNCTION FUNCTION
void DrawRect(Image* dst, float X, float Y, float w, float h) { void DrawRect(Image* dst, float X, float Y, float w, float h, uint32_t color) {
int max_x = (int)(MIN(X + w, dst->x) + 0.5f); int max_x = (int)(MIN(X + w, dst->x) + 0.5f);
int max_y = (int)(MIN(Y + h, dst->y) + 0.5f); int max_y = (int)(MIN(Y + h, dst->y) + 0.5f);
int min_x = (int)(MAX(0, X) + 0.5f); int min_x = (int)(MAX(0, X) + 0.5f);
@@ -37,7 +50,7 @@ void DrawRect(Image* dst, float X, float Y, float w, float h) {
for (int y = min_y; y < max_y; y++) { for (int y = min_y; y < max_y; y++) {
for (int x = min_x; x < max_x; x++) { for (int x = min_x; x < max_x; x++) {
dst->pixels[x + y * dst->x] = 0xffff0000; dst->pixels[x + (dst->y - 1 - y) * dst->x] = color;
} }
} }
} }
@@ -49,7 +62,8 @@ float EdgeFunction(Vec3 vecp0, Vec3 vecp1, Vec3 p) {
} }
FUNCTION FUNCTION
void DrawTriangle(Image* dst, Vec3 p0, Vec3 p1, Vec3 p2) { void DrawTriangle(Image* dst, Image *src, Vec3 p0, Vec3 p1, Vec3 p2,
Vec2 tex0, Vec2 tex1, Vec2 tex2) {
float min_x = (float)(MIN(p0.x, MIN(p1.x, p2.x)) + 0.5f); float min_x = (float)(MIN(p0.x, MIN(p1.x, p2.x)) + 0.5f);
float min_y = (float)(MIN(p0.y, MIN(p1.y, p2.y)) + 0.5f); float min_y = (float)(MIN(p0.y, MIN(p1.y, p2.y)) + 0.5f);
float max_x = (float)(MAX(p0.x, MAX(p1.x, p2.x)) + 0.5f); float max_x = (float)(MAX(p0.x, MAX(p1.x, p2.x)) + 0.5f);
@@ -66,27 +80,27 @@ void DrawTriangle(Image* dst, Vec3 p0, Vec3 p1, Vec3 p2) {
float edge2 = EdgeFunction(p1, p2, { x,y }); float edge2 = EdgeFunction(p1, p2, { x,y });
float edge3 = EdgeFunction(p2, p0, { x,y }); float edge3 = EdgeFunction(p2, p0, { x,y });
if (edge1 <= 0 && edge2 <= 0 && edge3 <= 0) { if (edge1 >= 0 && edge2 >= 0 && edge3 >= 0) {
int xi = (int)(x + 0.5f); int xi = (int)(x + 0.5f);
int yi = (int)(y + 0.5f); int yi = (int)(y + 0.5f);
float w1 = edge1 / area; float w1 = edge2 / area;
float w2 = edge2 / area; float w2 = edge3 / area;
float w3 = edge3 / area; float w3 = edge1 / area;
float r = 1 * w1 + 0 * w2 + 0 * w3; float u = tex0.x * w1 + tex1.x * w2 + tex2.x * w3;
float g = 0 * w1 + 1 * w2 + 0 * w3; float v = tex0.y * w1 + tex1.y * w2 + tex2.y * w3;
float b = 0 * w1 + 0 * w2 + 1 * w3; int ui = (int)(u * (src->x - 1) + 0.5f);
uint8_t r8 = (uint8_t)((r * 255.f) + 0.5f); int vi = (int)(v * (src->y - 1) + 0.5f);
uint8_t g8 = (uint8_t)((g * 255.f) + 0.5f); uint32_t pixel = src->pixels[ui + (src->y - 1 - vi) * src->x];
uint8_t b8 = (uint8_t)((b * 255.f) + 0.5f); dst->pixels[xi + (dst->y - 1 - yi) * dst->x] = pixel;
dst->pixels[xi + yi * dst->x] = r8 << 16 | g8 << 8 | b8;
} }
} }
} }
DrawRect(dst, p0.x-4, p0.y-4, 8,8); DrawRect(dst, p0.x-4, p0.y-4, 8,8, 0x00ff0000);
DrawRect(dst, p1.x-4, p1.y-4, 8,8); DrawRect(dst, p1.x-4, p1.y-4, 8,8, 0x0000ff00);
DrawRect(dst, p2.x-4, p2.y-4, 8,8); DrawRect(dst, p2.x-4, p2.y-4, 8,8, 0x000000ff);
} }
FUNCTION
void DrawLine(Image *dst, float x0, float y0, float x1, float y1) { void DrawLine(Image *dst, float x0, float y0, float x1, float y1) {
float delta_x = (x1 - x0); float delta_x = (x1 - x0);
float delta_y = (y1 - y0); float delta_y = (y1 - y0);
@@ -98,24 +112,31 @@ void DrawLine(Image *dst, float x0, float y0, float x1, float y1) {
for (int i = 0; i <= longest_side_length; i++) { for (int i = 0; i <= longest_side_length; i++) {
int x = (int)(current_x + 0.5f); int x = (int)(current_x + 0.5f);
int y = (int)(current_y + 0.5f); int y = (int)(current_y + 0.5f);
dst->pixels[x + y * dst->x] = 0xffffffff; dst->pixels[x + (dst->y - 1 - y) * dst->x] = 0xffffffff;
current_x += x_inc; current_x += x_inc;
current_y += y_inc; current_y += y_inc;
} }
} }
int main() { int main() {
OS_Init({.window_x=1280, .window_y=720}); OS_Init({.window_x=1280, .window_y=720});
float rotation = 0; float rotation = 0;
Vec3 camera_pos = {0,0,-5}; Vec3 camera_pos = {0,0,-5};
int x,y,n;
unsigned char *data = stbi_load("assets/cat.png", &x, &y, &n, 4);
Image img = {
(uint32_t *)data, x, y
};
while (OS_GameLoop()) { while (OS_GameLoop()) {
for (int y = 0; y < screen.y; y++) { for (int y = 0; y < screen.y; y++) {
for (int x = 0; x < screen.x; x++) { for (int x = 0; x < screen.x; x++) {
screen.pixels[x + y * screen.x] = 0; screen.pixels[x + y * screen.x] = 0;
} }
} }
#if 0
DrawTriangle(&screen, &img, { 100,100 }, { 100,400 }, { 400,400 }, { 0,0 }, { 0,1 }, { 1,1 });
DrawTriangle(&screen, &img, { 100,100 }, { 400,400 }, { 400,100}, { 0,0 }, { 1,1 }, { 1,0 });
#else
Mat4 transform = Mat4RotationZ(rotation); Mat4 transform = Mat4RotationZ(rotation);
transform = transform * Mat4RotationX(rotation); transform = transform * Mat4RotationX(rotation);
if (keydown_a) rotation += 0.05f; if (keydown_a) rotation += 0.05f;
@@ -137,12 +158,10 @@ int main() {
Vec3 p0_to_p1 = pos[1] - pos[0]; Vec3 p0_to_p1 = pos[1] - pos[0];
Vec3 p0_to_p2 = pos[2] - pos[0]; Vec3 p0_to_p2 = pos[2] - pos[0];
Vec3 normal = Cross(p0_to_p1, p0_to_p2); Vec3 normal = Cross(p0_to_p1, p0_to_p2);
if (Dot(normal, p0_to_camera) < 0) { if (Dot(normal, p0_to_camera) > 0) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
//@Note: Camera //@Note: Camera
pos[j].x -= camera_pos.x; pos[j] = pos[j] - camera_pos;
pos[j].y -= camera_pos.y;
pos[j].z -= camera_pos.z;
//@Note: Perspective //@Note: Perspective
pos[j].x /= pos[j].z; pos[j].x /= pos[j].z;
pos[j].y /= pos[j].z; pos[j].y /= pos[j].z;
@@ -152,11 +171,12 @@ int main() {
pos[j].x += screen.x / 2; pos[j].x += screen.x / 2;
pos[j].y += screen.y / 2; pos[j].y += screen.y / 2;
} }
DrawTriangle(&screen, pos[0], pos[1], pos[2]); DrawTriangle(&screen, &img, pos[0], pos[1], pos[2], face->tex[0], face->tex[1], face->tex[2]);
DrawLine(&screen, pos[0].x, pos[0].y, pos[1].x, pos[1].y); DrawLine(&screen, pos[0].x, pos[0].y, pos[1].x, pos[1].y);
DrawLine(&screen, pos[1].x, pos[1].y, pos[2].x, pos[2].y); DrawLine(&screen, pos[1].x, pos[1].y, pos[2].x, pos[2].y);
DrawLine(&screen, pos[2].x, pos[2].y, pos[0].x, pos[0].y); DrawLine(&screen, pos[2].x, pos[2].y, pos[0].x, pos[0].y);
} }
} }
#endif
} }
} }

4
math.h
View File

@@ -6,6 +6,10 @@ struct Mat4 {
float p[4][4]; float p[4][4];
}; };
struct Vec2 {
float x, y;
};
union Vec3 { union Vec3 {
struct { float x, y, z; }; struct { float x, y, z; };
struct { float r, g, b; }; struct { float r, g, b; };