Skip to content

Instantly share code, notes, and snippets.

@ronejfourn
Last active August 27, 2023 08:05
Show Gist options
  • Save ronejfourn/307640fb43dba0bb1e1be3b5d75c56be to your computer and use it in GitHub Desktop.
Save ronejfourn/307640fb43dba0bb1e1be3b5d75c56be to your computer and use it in GitHub Desktop.
graphics.h 3D Transformations Demo
#include <dos.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <graphics.h>
typedef struct {
float x, y, z;
} Vec3;
typedef struct {
float m[4][4];
} Mat4;
#define PI 3.1415926535898f
float DegToRad(float d) {
return d * PI / 180.0f;
}
Vec3 Mat4MultiplyVec3(Mat4 m, Vec3 v) {
Vec3 r;
int i, j;
float h[4] = {v.x, v.y, v.z, 1};
float o[4] = { 0, 0, 0, 0};
for (i = 0; i < 4; i ++)
for (j = 0; j < 4; j ++)
o[i] += m.m[i][j] * h[j];
r.x = o[0] / o[3];
r.y = o[1] / o[3];
r.z = o[2] / o[3];
return r;
}
Mat4 Mat4MultiplyMat4(Mat4 m1, Mat4 m2) {
Mat4 out = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
};
int i, j, k;
for (i = 0; i < 4; i ++)
for (j = 0; j < 4; j ++)
for (k = 0; k < 4; k ++)
out.m[i][j] += m1.m[i][k] * m2.m[k][j];
return out;
}
void DrawTriangles(Vec3 *vertices, int nverts, Mat4 translatesform) {
int i = 0;
for (i = 0; i < nverts; i += 3) {
Vec3 v0, v1, v2;
int x0, y0;
int x1, y1;
int x2, y2;
v0 = Mat4MultiplyVec3(translatesform, vertices[i + 0]);
v1 = Mat4MultiplyVec3(translatesform, vertices[i + 1]);
v2 = Mat4MultiplyVec3(translatesform, vertices[i + 2]);
x0 = (v0.x * 0.5f + 0.5f) * getmaxx();
x1 = (v1.x * 0.5f + 0.5f) * getmaxx();
x2 = (v2.x * 0.5f + 0.5f) * getmaxx();
y0 = (v0.y * 0.5f + 0.5f) * getmaxy();
y1 = (v1.y * 0.5f + 0.5f) * getmaxy();
y2 = (v2.y * 0.5f + 0.5f) * getmaxy();
line(x0, y0, x1, y1);
line(x1, y1, x2, y2);
line(x2, y2, x0, y0);
}
}
Mat4 CreateIdentityMatrix() {
Mat4 m = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
};
return m;
}
Mat4 CreatePerspectiveProjectionMatrix(float aspectRatio, float fovRad, float zn, float zf) {
Mat4 m = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
};
float tanHalfFOV = tan(fovRad / 2.0f);
float zr = zn - zf;
float p = - (zn + zf) / zr;
float q = 2 * zn * zf / zr;
m.m[0][0] = 1 / (aspectRatio * tanHalfFOV);
m.m[1][1] = 1 / tanHalfFOV;
m.m[2][2] = p;
m.m[2][3] = q;
m.m[3][2] = 1;
return m;
}
Mat4 CreateRotationMatrixX(float angle) {
float c = cos(angle);
float s = sin(angle);
Mat4 m = {
1, 0, 0, 0,
0, c, -s, 0,
0, s, c, 0,
0, 0, 0, 1,
};
return m;
}
Mat4 CreateRotationMatrixY(float angle) {
float c = cos(angle);
float s = sin(angle);
Mat4 m = {
c, 0, -s, 0,
0, 1, 0, 0,
s, 0, c, 0,
0, 0, 0, 1,
};
return m;
}
Mat4 CreateRotationMatrixZ(float angle) {
float c = cos(angle);
float s = sin(angle);
Mat4 m = {
c, -s, 0, 0,
s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
};
return m;
}
Mat4 CreateTranslationMatrix(float x, float y, float z) {
Mat4 m = {
1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1,
};
return m;
}
Mat4 CreateScalingMatrix(float x, float y, float z) {
Mat4 m = {
x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1,
};
return m;
}
int main() {
int gd = DETECT, gm = DETECT;
Vec3 vertices[] = {
// front
{-0.5f, -0.5f, 0.5f}, { 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f},
{-0.5f, -0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f},
// back
{-0.5f, -0.5f, -0.5f}, { 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, -0.5f},
{-0.5f, -0.5f, -0.5f}, {-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, -0.5f},
// left
{-0.5f, -0.5f, -0.5f}, {-0.5f, 0.5f, -0.5f}, {-0.5f, 0.5f, 0.5f},
{-0.5f, -0.5f, -0.5f}, {-0.5f, -0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f},
// right
{ 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f},
{ 0.5f, -0.5f, -0.5f}, { 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f},
// top
{-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f},
{-0.5f, 0.5f, -0.5f}, {-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f},
// bottom
{-0.5f, -0.5f, -0.5f}, { 0.5f, -0.5f, -0.5f}, { 0.5f, -0.5f, 0.5f},
{-0.5f, -0.5f, -0.5f}, {-0.5f, -0.5f, 0.5f}, { 0.5f, -0.5f, 0.5f},
};
int nverts = sizeof(vertices) / sizeof(Vec3);
int i, j;
float a = 0;
float aspectRatio;
float fov;
Mat4 projection;
initgraph(&gd, &gm, "C:\\TC\\BGI");
aspectRatio = (float)getmaxx() / (float)getmaxy();
fov = DegToRad(90.0f);
projection = CreatePerspectiveProjectionMatrix(aspectRatio, fov, 0.01f, 100.0f);
while (!kbhit()) {
Mat4 composite = CreateIdentityMatrix();
Mat4 translate = CreateTranslationMatrix(0, 0, -3.0f);
Mat4 rotateX = CreateRotationMatrixX(a);
Mat4 rotateY = CreateRotationMatrixY(a);
float f = (sin(a) * 0.5f + 1.0f) * 2.0f;
Mat4 scale = CreateScalingMatrix(f, f, f);
a += 0.02f;
composite = Mat4MultiplyMat4(composite, projection);
composite = Mat4MultiplyMat4(composite, translate);
composite = Mat4MultiplyMat4(composite, scale);
composite = Mat4MultiplyMat4(composite, rotateX);
composite = Mat4MultiplyMat4(composite, rotateY);
cleardevice();
DrawTriangles(vertices, nverts, composite);
delay(16);
}
getch();
closegraph();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment