Add various versions, readme and screenshot
This commit is contained in:
parent
48819cf841
commit
58d457d332
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# render
|
||||||
|
box, tree and teapot dumb software renderer
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
| name | lang | notes |
|
||||||
|
|---------------------|------------------------|---------------------------------------|
|
||||||
|
| `render.fcode` | Flowgorithm pseudocode | original, VT100/PPM output |
|
||||||
|
| `render.lua` | Lua | Lua port, VT100 output |
|
||||||
|
| `render_origo.lua` | Lua | unknown |
|
||||||
|
| `render_cc.lua` | Lua | ComputerCraft version, monitor output, requires processing with `convert_cc.py` and `reduce_cc.py` if too big to store on CC drive |
|
||||||
|
| `render.cpp` | C++ | C++ implementation, different structure, unknown state |
|
||||||
|
| `render_dos.c` | C | DOS, requires 32bit extender, output to VGA mode 13h (256 colors), much faster triangle rasterization alg. |
|
||||||
|
|
||||||
|
|
||||||
7
build_dos.bat
Normal file
7
build_dos.bat
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
set WATCOM=c:\dev\render\wc
|
||||||
|
set EDPATH=%WATCOM%\eddat
|
||||||
|
set INCLUDE=%WATCOM%\h
|
||||||
|
set PATH=%PATH%;%WATCOM%\binnt;%WATCOM%\binw;
|
||||||
|
|
||||||
|
wcl386 -3 -fpi87 -fp3 -os -d0 -mf -bt=dos -l=stub32x -fe=render.exe render_dos.c
|
||||||
|
pause
|
||||||
51
convert_cc.py
Normal file
51
convert_cc.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
def convert(input_filename):
|
||||||
|
with open(input_filename, "r") as f:
|
||||||
|
lines = [line.strip() for line in f if line.strip()]
|
||||||
|
|
||||||
|
# --- Step 1: Parse header ---
|
||||||
|
idx = 0
|
||||||
|
_ignored = int(lines[idx]) # First line, ignored
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
num_vertices = int(lines[idx])
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
# --- Step 2: Extract vertex data ---
|
||||||
|
vertices = []
|
||||||
|
for _ in range(num_vertices):
|
||||||
|
# Each vertex: x y z u v nx ny nz (8 numbers)
|
||||||
|
vertex = [lines[idx + i] for i in range(8)]
|
||||||
|
vertices.append(vertex)
|
||||||
|
idx += 8
|
||||||
|
|
||||||
|
# --- Step 3: Write mesh.txt ---
|
||||||
|
with open("mesh.txt", "w") as mesh_file:
|
||||||
|
mesh_file.write(str(num_vertices) + "\n")
|
||||||
|
for v in vertices:
|
||||||
|
for comp in v:
|
||||||
|
mesh_file.write(comp + "\n")
|
||||||
|
|
||||||
|
# --- Step 4: Parse texture ---
|
||||||
|
width = int(lines[idx]); idx += 1
|
||||||
|
height = int(lines[idx]); idx += 1
|
||||||
|
|
||||||
|
num_pixels = width * height
|
||||||
|
pixels = []
|
||||||
|
for _ in range(num_pixels):
|
||||||
|
r = int(lines[idx]); idx += 1
|
||||||
|
g = int(lines[idx]); idx += 1
|
||||||
|
b = int(lines[idx]); idx += 1
|
||||||
|
pixels.append((r, g, b))
|
||||||
|
|
||||||
|
# --- Step 5: Write texture.bin ---
|
||||||
|
with open("texture.bin", "wb") as tex_file:
|
||||||
|
for r, g, b in pixels:
|
||||||
|
tex_file.write(bytes([r, g, b]))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print(f"Usage: {sys.argv[0]} <input_file>")
|
||||||
|
else:
|
||||||
|
convert(sys.argv[1])
|
||||||
20
reduce_cc.py
Normal file
20
reduce_cc.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
def reduce_precision(input_file, output_file):
|
||||||
|
with open(input_file, "r") as infile, open(output_file, "w") as outfile:
|
||||||
|
for line in infile:
|
||||||
|
line = line.strip()
|
||||||
|
if line: # skip empty lines
|
||||||
|
try:
|
||||||
|
num = float(line)
|
||||||
|
if num.is_integer():
|
||||||
|
outfile.write(f"{int(num)}\n")
|
||||||
|
else:
|
||||||
|
outfile.write(f"{num:.3f}\n")
|
||||||
|
except ValueError:
|
||||||
|
# If not a number, write unchanged
|
||||||
|
outfile.write(line + "\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
input_path = "data.txt" # original file
|
||||||
|
output_path = "data2.txt" # new file
|
||||||
|
reduce_precision(input_path, output_path)
|
||||||
|
|
||||||
400
render.cpp
Normal file
400
render.cpp
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
// render.cpp : This file contains the 'main' function. Program execution begins and ends there.
|
||||||
|
//
|
||||||
|
#pragma comment(lib,"winmm.lib")
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
//#include <omp.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
#define RES_WIDTH 160
|
||||||
|
#define RES_HEIGHT 120
|
||||||
|
#define RES_PIXELS (RES_WIDTH * RES_HEIGHT)
|
||||||
|
|
||||||
|
static glm::vec3 s_colorbuffer[RES_PIXELS];
|
||||||
|
static float s_depthbuffer[RES_PIXELS];
|
||||||
|
static char s_outputbuffer[5000000];
|
||||||
|
|
||||||
|
static float s_fps = 0.0f;
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
glm::vec3 pos;
|
||||||
|
glm::vec2 texcoord;
|
||||||
|
glm::vec3 normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Texture {
|
||||||
|
std::vector<glm::vec<3, uint8_t>> texels;
|
||||||
|
size_t width;
|
||||||
|
size_t height;
|
||||||
|
|
||||||
|
glm::vec3 Sample(const glm::vec2& texcoord) const {
|
||||||
|
auto idx = (int)(texcoord.x * width) + (int)((1.0f - texcoord.y) * height) * width;
|
||||||
|
const auto& t = texels[idx];
|
||||||
|
return glm::vec3((float)t.r / 255.0f, (float)t.g / 255.0f, (float)t.b / 255.0f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ClearBuffers(float depth, const glm::vec3& clear_color) {
|
||||||
|
for (int i = 0; i < RES_PIXELS; ++i) {
|
||||||
|
s_colorbuffer[i] = clear_color;
|
||||||
|
s_depthbuffer[i] = depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using Vec3ui8 = glm::vec<3, uint8_t>;
|
||||||
|
|
||||||
|
static void OutputVT100() {
|
||||||
|
//printf("\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m");
|
||||||
|
//printf("\x1b[1;1H");
|
||||||
|
//printf("\x1b[2J");
|
||||||
|
//std::cout << (char)27 << "[1;1H";
|
||||||
|
|
||||||
|
//std::string output;
|
||||||
|
//output.reserve(1000000);
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
//std::vector<std::ostringstream> oss;
|
||||||
|
//oss.resize(RES_HEIGHT / 2);
|
||||||
|
|
||||||
|
//output += "\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m\x1b[1;1H";
|
||||||
|
|
||||||
|
Vec3ui8 prevc1(0), prevc2(0);
|
||||||
|
|
||||||
|
//#pragma omp parallel for
|
||||||
|
for (int y = 0; y <= RES_HEIGHT - 2; y += 2) {
|
||||||
|
//printf("\n");
|
||||||
|
//output += '\n';
|
||||||
|
|
||||||
|
offset += snprintf(s_outputbuffer + offset, sizeof(s_outputbuffer), "\n");
|
||||||
|
|
||||||
|
for (int x = 0; x < RES_WIDTH; ++x) {
|
||||||
|
const auto& c1 = s_colorbuffer[x + y * RES_WIDTH];
|
||||||
|
const auto& c2 = s_colorbuffer[x + (y + 1) * RES_WIDTH];
|
||||||
|
|
||||||
|
Vec3ui8 c1i = c1 * 255.0f;
|
||||||
|
Vec3ui8 c2i = c2 * 255.0f;
|
||||||
|
|
||||||
|
if (prevc1 == c1i && prevc2 == c2i) {
|
||||||
|
//offset += snprintf(s_outputbuffer + offset, sizeof(s_outputbuffer), "\xDF");
|
||||||
|
s_outputbuffer[offset++] = '\xDF';
|
||||||
|
//s_outputbuffer[offset++] = 'W';
|
||||||
|
s_outputbuffer[offset] = '\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset += snprintf(s_outputbuffer + offset, sizeof(s_outputbuffer), "\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dm\xDF", c1i.r, c1i.g, c1i.b, c2i.r, c2i.g, c2i.b);
|
||||||
|
//offset += snprintf(s_outputbuffer + offset, sizeof(s_outputbuffer), "\x1b[38;2;%d;%d;%dmW", c1i.r, c1i.g, c1i.b, c2i.r, c2i.g, c2i.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
prevc1 = c1i;
|
||||||
|
prevc2 = c2i;
|
||||||
|
|
||||||
|
|
||||||
|
//printf("\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dm\xDF", c1i.r, c1i.g, c1i.b, c2i.r, c2i.g, c2i.b);
|
||||||
|
|
||||||
|
//std::ostringstream os;
|
||||||
|
//auto& os = oss[y / 2];
|
||||||
|
|
||||||
|
//os << "\x1b[38;2;" << (int)c1i.r << ";" << (int)c1i.g << ";" << (int)c1i.b << "m" << "\x1b[48;2;" << (int)c2i.r << ";" << (int)c2i.g << ";" << (int)c2i.b << "m" << "\xDF";
|
||||||
|
//output += os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m");
|
||||||
|
printf("\x1b[1;1H");
|
||||||
|
|
||||||
|
printf("%s\n", s_outputbuffer);
|
||||||
|
|
||||||
|
//for (int i = 0; i < oss.size(); ++i)
|
||||||
|
// printf("%s\n", oss[i].str().c_str());
|
||||||
|
|
||||||
|
//output += "\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m";
|
||||||
|
//printf("%s\n", output.c_str());
|
||||||
|
|
||||||
|
printf("\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m\n");
|
||||||
|
|
||||||
|
printf("%6d %4.1f FPS ", offset, s_fps);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//// Find the closest RGBx approximation of a 24-bit RGB color, for x = 0 or 1
|
||||||
|
//glm::u8vec3 rgbx_approx(unsigned char red, unsigned char green, unsigned char blue, int x) {
|
||||||
|
// int threshold = (x + 1) * 255 / 3;
|
||||||
|
// glm::u8vec3 result;
|
||||||
|
// result.r = (red > threshold) ? 1 : 0;
|
||||||
|
// result.g = (green > threshold) ? 1 : 0;
|
||||||
|
// result.b = (blue > threshold) ? 1 : 0;
|
||||||
|
// return result;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// Convert a 4-bit RGBI color back to 24-bit RGB
|
||||||
|
//glm::u8vec3 rgbi_to_rgb24(int r, int g, int b, int i) {
|
||||||
|
// glm::u8vec3 result;
|
||||||
|
// result.r = ((2 * r + i) * 255) / 3;
|
||||||
|
// result.g = ((2 * g + i) * 255) / 3;
|
||||||
|
// result.b = ((2 * b + i) * 255) / 3;
|
||||||
|
// return result;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//float color_distance(const glm::u8vec3& colorA, const glm::u8vec3& colorB) {
|
||||||
|
// int diffR = colorA.r - colorB.r;
|
||||||
|
// int diffG = colorA.g - colorB.g;
|
||||||
|
// int diffB = colorA.b - colorB.b;
|
||||||
|
// return static_cast<float>((diffR * diffR) + (diffG * diffG) + (diffB * diffB));
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// Find the closest 4-bit RGBI approximation (by Euclidean distance) to a 24-bit RGB color
|
||||||
|
//std::pair<glm::u8vec3, int> rgbi_approx(unsigned char red, unsigned char green, unsigned char blue) {
|
||||||
|
// // Find best RGB0 and RGB1 approximations
|
||||||
|
// glm::u8vec3 rgb0 = rgbx_approx(red, green, blue, 0);
|
||||||
|
// glm::u8vec3 rgb1 = rgbx_approx(red, green, blue, 1);
|
||||||
|
//
|
||||||
|
// // Convert them back to 24-bit RGB
|
||||||
|
// glm::u8vec3 rgb24_0 = rgbi_to_rgb24(rgb0.r, rgb0.g, rgb0.b, 0);
|
||||||
|
// glm::u8vec3 rgb24_1 = rgbi_to_rgb24(rgb1.r, rgb1.g, rgb1.b, 1);
|
||||||
|
//
|
||||||
|
// // Calculate squared Euclidean distances
|
||||||
|
// float d0 = color_distance(glm::u8vec3(red, green, blue), rgb24_0);
|
||||||
|
// float d1 = color_distance(glm::u8vec3(red, green, blue), rgb24_1);
|
||||||
|
//
|
||||||
|
// if (d0 <= d1) {
|
||||||
|
// return std::make_pair(rgb0, 0);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// return std::make_pair(rgb1, 1);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//void OutputWindows() {
|
||||||
|
// HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
//
|
||||||
|
// COORD pos;
|
||||||
|
// pos.X = 0;
|
||||||
|
// pos.Y = 0;
|
||||||
|
// SetConsoleCursorPosition(hConsole, pos);
|
||||||
|
//
|
||||||
|
// const char palette[] = ".,-~:;=!*#$@";
|
||||||
|
// int chars = sizeof(palette) - 1;
|
||||||
|
//
|
||||||
|
// for (int y = 0; y < RES_HEIGHT; ++y) {
|
||||||
|
// for (int x = 0; x < RES_WIDTH; ++x) {
|
||||||
|
// const auto& c1 = s_colorbuffer[x + y * RES_WIDTH];
|
||||||
|
// Vec3ui8 c1i = c1 * 255.0f;
|
||||||
|
//
|
||||||
|
// auto [c, i] = rgbi_approx(c1i.r, c1i.g, c1i.b);
|
||||||
|
//
|
||||||
|
// DWORD attr = 0;
|
||||||
|
// if (c.r) attr |= FOREGROUND_RED;
|
||||||
|
// if (c.g) attr |= FOREGROUND_GREEN;
|
||||||
|
// if (c.b) attr |= FOREGROUND_BLUE;
|
||||||
|
// if (i) attr |= FOREGROUND_INTENSITY;
|
||||||
|
// SetConsoleTextAttribute(hConsole, attr);
|
||||||
|
// printf("X");
|
||||||
|
//
|
||||||
|
// //float brightness = (c1.r + c1.g + c1.b) / 3.0f;
|
||||||
|
// //float b2 = glm::max(c1.r, glm::max(c1.g, c1.b));
|
||||||
|
//
|
||||||
|
// //DWORD attr = 0;
|
||||||
|
// //if (c1.r / b2 > 0.5) attr |= FOREGROUND_RED;
|
||||||
|
// //if (c1.g / b2 > 0.5) attr |= FOREGROUND_GREEN;
|
||||||
|
// //if (c1.b / b2 > 0.5) attr |= FOREGROUND_BLUE;
|
||||||
|
//
|
||||||
|
// //if (b2 > 0.5) attr |= FOREGROUND_INTENSITY;
|
||||||
|
//
|
||||||
|
// //printf("%c", palette[(int)(chars * b2)]);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// printf("\n");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
static bool ProcessVertex(const glm::vec3& pos, const glm::mat4& mvp, glm::vec2& sc, float& z) {
|
||||||
|
auto cs = mvp * glm::vec4(pos.x, pos.y, pos.z, 1.0f);
|
||||||
|
|
||||||
|
//if (cs.w < 0.0f) return true;
|
||||||
|
cs /= cs.w;
|
||||||
|
|
||||||
|
sc.x = (cs.x + 1.0f) * 0.5f * (RES_WIDTH - 1);
|
||||||
|
sc.y = (1.0f - cs.y) * 0.5f * (RES_HEIGHT - 1);
|
||||||
|
|
||||||
|
z = cs.z;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsRight(glm::vec2 a, glm::vec2 b, glm::vec2 c) {
|
||||||
|
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Barycentric(glm::vec2 p, glm::vec2 a, glm::vec2 b, glm::vec2 c) {
|
||||||
|
glm::vec2 v0 = b - a, v1 = c - a, v2 = p - a;
|
||||||
|
float d00 = glm::dot(v0, v0);
|
||||||
|
float d01 = glm::dot(v0, v1);
|
||||||
|
float d11 = glm::dot(v1, v1);
|
||||||
|
float d20 = glm::dot(v2, v0);
|
||||||
|
float d21 = glm::dot(v2, v1);
|
||||||
|
float denom = d00 * d11 - d01 * d01;
|
||||||
|
float v = (d11 * d20 - d01 * d21) / denom;
|
||||||
|
float w = (d00 * d21 - d01 * d20) / denom;
|
||||||
|
float u = 1.0f - v - w;
|
||||||
|
return glm::vec3(u, v, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawTriangle(const Vertex& v0, const Vertex& v1, const Vertex& v2, const glm::mat4& mvp, const Texture& texture) {
|
||||||
|
glm::vec2 p0, p1, p2;
|
||||||
|
float z0, z1, z2;
|
||||||
|
|
||||||
|
if (ProcessVertex(v0.pos, mvp, p0, z0) || ProcessVertex(v1.pos, mvp, p1, z1) || ProcessVertex(v2.pos, mvp, p2, z2))
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
auto aabbmin = glm::max(glm::min(glm::min(p0, p1), p2), glm::vec2(0, 0));
|
||||||
|
auto aabbmax = glm::min(glm::max(glm::max(p0, p1), p2), glm::vec2(RES_WIDTH - 1, RES_HEIGHT - 1));
|
||||||
|
|
||||||
|
int ymin = aabbmin.y;
|
||||||
|
int ymax = aabbmax.y;
|
||||||
|
|
||||||
|
//#pragma omp parallel for
|
||||||
|
for (int y = ymin; y <= ymax; y++) {
|
||||||
|
for (int x = aabbmin.x; x <= aabbmax.x; x++) {
|
||||||
|
glm::vec2 p(x, y);
|
||||||
|
|
||||||
|
if (IsRight(p0, p1, p) && IsRight(p1, p2, p) && IsRight(p2, p0, p)) {
|
||||||
|
auto w = Barycentric(p, p0, p1, p2);
|
||||||
|
auto depth = w[0] * z0 + w[1] * z1 + w[2] * z2;
|
||||||
|
int idx = p.x + p.y * RES_WIDTH;
|
||||||
|
|
||||||
|
if (depth < s_depthbuffer[idx] && depth > 0.0f) {
|
||||||
|
s_depthbuffer[idx] = depth;
|
||||||
|
|
||||||
|
auto texcoord = w[0] * v0.texcoord + w[1] * v1.texcoord + w[2] * v2.texcoord;
|
||||||
|
auto normal = w[0] * v0.normal + w[1] * v1.normal + w[2] * v2.normal;
|
||||||
|
|
||||||
|
glm::vec3 light_dir(-1, -2, -1);
|
||||||
|
|
||||||
|
float diff = glm::max(glm::dot(glm::normalize(normal), -glm::normalize(light_dir)), 0.3f);
|
||||||
|
|
||||||
|
s_colorbuffer[idx] = texture.Sample(texcoord) * diff; //glm::vec3(0, texcoord.x, texcoord.y);
|
||||||
|
//s_colorbuffer[idx] = glm::vec3(0, texcoord.x, texcoord.y);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
//omp_set_num_threads(4);
|
||||||
|
|
||||||
|
std::ifstream data("data.txt");
|
||||||
|
size_t waste, num_vertices;
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
|
||||||
|
data >> waste >> num_vertices;
|
||||||
|
vertices.resize(num_vertices);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < num_vertices; ++i) {
|
||||||
|
auto& v = vertices[i];
|
||||||
|
data >> v.pos.x >> v.pos.y >> v.pos.z >> v.texcoord.x >> v.texcoord.y >> v.normal.x >> v.normal.y >> v.normal.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture texture;
|
||||||
|
|
||||||
|
data >> texture.width >> texture.height;
|
||||||
|
texture.texels.resize(texture.width * texture.height);
|
||||||
|
|
||||||
|
for (int i = 0; i < texture.texels.size(); ++i) {
|
||||||
|
auto& t = texture.texels[i];
|
||||||
|
int r, g, b;
|
||||||
|
data >> r >> g >> b;
|
||||||
|
|
||||||
|
t.r = r; t.g = g; t.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
//SetConsoleMode(hConsole, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||||
|
//system(" ");
|
||||||
|
|
||||||
|
float rot = 0.0f;
|
||||||
|
|
||||||
|
|
||||||
|
int lastfpstime = 0;
|
||||||
|
int frames = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
frames++;
|
||||||
|
auto time = timeGetTime();
|
||||||
|
if (lastfpstime + 1000 < time) {
|
||||||
|
lastfpstime = time;
|
||||||
|
s_fps = frames;
|
||||||
|
frames = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearBuffers(1.0f, glm::vec3(0.3f));
|
||||||
|
|
||||||
|
rot = (float)time * 0.001f;
|
||||||
|
|
||||||
|
glm::vec3 campos;
|
||||||
|
campos.x = glm::sin(rot) * 7.0f;
|
||||||
|
campos.y = 3.0f;
|
||||||
|
campos.z = glm::cos(rot) * 7.0f;
|
||||||
|
|
||||||
|
campos *= (glm::sin(rot * 0.3f) + 1.0f) * 0.5f;
|
||||||
|
|
||||||
|
//rot += glm::pi<float>() / 500.0f;
|
||||||
|
|
||||||
|
|
||||||
|
float aspect_ratio = (float)RES_WIDTH / (float)RES_HEIGHT;
|
||||||
|
auto view = glm::lookAt(campos, glm::vec3(0), glm::vec3(0, 1, 0));
|
||||||
|
auto proj = glm::perspective(glm::radians(90.0f) / aspect_ratio, aspect_ratio, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
auto mvp = proj * view;
|
||||||
|
|
||||||
|
for (int i = 0; i < vertices.size(); i += 3) {
|
||||||
|
const auto& v0 = vertices[i];
|
||||||
|
const auto& v1 = vertices[i + 1];
|
||||||
|
const auto& v2 = vertices[i + 2];
|
||||||
|
|
||||||
|
DrawTriangle(v0, v1, v2, mvp, texture);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//for (int y = 0; y < RES_HEIGHT; ++y) {
|
||||||
|
// for (int x = 0; x < RES_WIDTH; ++x) {
|
||||||
|
|
||||||
|
// s_colorbuffer[x + RES_WIDTH * y] = glm::vec3((float)x / RES_WIDTH, (float)y / RES_HEIGHT, 0);
|
||||||
|
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
OutputVT100();
|
||||||
|
//OutputWindows();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
|
||||||
|
// Debug program: F5 or Debug > Start Debugging menu
|
||||||
|
|
||||||
|
// Tips for Getting Started:
|
||||||
|
// 1. Use the Solution Explorer window to add/manage files
|
||||||
|
// 2. Use the Team Explorer window to connect to source control
|
||||||
|
// 3. Use the Output window to see build output and other messages
|
||||||
|
// 4. Use the Error List window to view errors
|
||||||
|
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
|
||||||
|
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
|
||||||
529
render.lua
Normal file
529
render.lua
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
local fps = 0
|
||||||
|
local math_floor = math.floor
|
||||||
|
local time = 0
|
||||||
|
|
||||||
|
local function ClearBuffers(meta, colorbuffer, depthbuffer, color, depth)
|
||||||
|
local i
|
||||||
|
for i = 0, meta[3] - 1 do
|
||||||
|
colorbuffer[1 + i * 3] = color[1]
|
||||||
|
colorbuffer[1 + i * 3 + 1] = color[2]
|
||||||
|
colorbuffer[1 + i * 3 + 2] = color[3]
|
||||||
|
|
||||||
|
depthbuffer[1 + i] = depth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function DegToRad(deg)
|
||||||
|
local rad
|
||||||
|
rad = deg * 0.0174532925
|
||||||
|
return rad
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Min(a, b)
|
||||||
|
local r
|
||||||
|
if a < b then
|
||||||
|
r = a
|
||||||
|
else
|
||||||
|
r = b
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Min3(a, b, c)
|
||||||
|
local r
|
||||||
|
r = Min(Min(a, b), c)
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Max(a, b)
|
||||||
|
local r
|
||||||
|
if a > b then
|
||||||
|
r = a
|
||||||
|
else
|
||||||
|
r = b
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Max3(a, b, c)
|
||||||
|
local r
|
||||||
|
r = Max(Max(a, b), c)
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function IsOnRight(a, b, c)
|
||||||
|
local r
|
||||||
|
if (b[1] - a[1]) * (c[2] - a[2]) - (b[2] - a[2]) * (c[1] - a[1]) <= 0 then
|
||||||
|
r = true
|
||||||
|
else
|
||||||
|
r = false
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Distance2(a, b)
|
||||||
|
local x, y, d
|
||||||
|
x = b[1] - a[1]
|
||||||
|
y = b[2] - a[2]
|
||||||
|
d = math.sqrt(x * x + y * y)
|
||||||
|
return d
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Normalize(a)
|
||||||
|
local l
|
||||||
|
l = math.sqrt(a[1] * a[1] + a[2] * a[2] + a[3] * a[3])
|
||||||
|
a[1] = a[1] / l
|
||||||
|
a[2] = a[2] / l
|
||||||
|
a[3] = a[3] / l
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MapToRes(meta, a)
|
||||||
|
a[1] = a[1] / a[4]
|
||||||
|
a[2] = a[2] / a[4]
|
||||||
|
a[3] = a[3] / a[4]
|
||||||
|
|
||||||
|
a[1] = (a[1] + 1.0) * 0.5 * (meta[1] - 1)
|
||||||
|
a[2] = (1.0 - a[2]) * 0.5 * (meta[2] - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Cross(result, a, b)
|
||||||
|
result[1] = a[2] * b[3] - a[3] * b[2]
|
||||||
|
result[2] = a[3] * b[1] - a[1] * b[3]
|
||||||
|
result[3] = a[1] * b[2] - a[2] * b[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Dot(a, b)
|
||||||
|
local result
|
||||||
|
result = a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Dot2(a, b)
|
||||||
|
local result
|
||||||
|
result = a[1] * b[1] + a[2] * b[2]
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function VecCopy3(result, a)
|
||||||
|
result[1] = a[1]
|
||||||
|
result[2] = a[2]
|
||||||
|
result[3] = a[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function VecSubVec3(result, a, b)
|
||||||
|
result[1] = a[1] - b[1]
|
||||||
|
result[2] = a[2] - b[2]
|
||||||
|
result[3] = a[3] - b[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultMat(result, a, b)
|
||||||
|
result[1] = a[1] * b[1] + a[2] * b[5] + a[3] * b[9] + a[4] * b[13]
|
||||||
|
result[2] = a[1] * b[2] + a[2] * b[6] + a[3] * b[10] + a[4] * b[14]
|
||||||
|
result[3] = a[1] * b[3] + a[2] * b[7] + a[3] * b[11] + a[4] * b[15]
|
||||||
|
result[4] = a[1] * b[4] + a[2] * b[8] + a[3] * b[12] + a[4] * b[16]
|
||||||
|
result[5] = a[5] * b[1] + a[6] * b[5] + a[7] * b[9] + a[8] * b[13]
|
||||||
|
result[6] = a[5] * b[2] + a[6] * b[6] + a[7] * b[10] + a[8] * b[14]
|
||||||
|
result[7] = a[5] * b[3] + a[6] * b[7] + a[7] * b[11] + a[8] * b[15]
|
||||||
|
result[8] = a[5] * b[4] + a[6] * b[8] + a[7] * b[12] + a[8] * b[16]
|
||||||
|
result[9] = a[9] * b[1] + a[10] * b[5] + a[11] * b[9] + a[12] * b[13]
|
||||||
|
result[10] = a[9] * b[2] + a[10] * b[6] + a[11] * b[10] + a[12] * b[14]
|
||||||
|
result[11] = a[9] * b[3] + a[10] * b[7] + a[11] * b[11] + a[12] * b[15]
|
||||||
|
result[12] = a[9] * b[4] + a[10] * b[8] + a[11] * b[12] + a[12] * b[16]
|
||||||
|
result[13] = a[13] * b[1] + a[14] * b[5] + a[15] * b[9] + a[16] * b[13]
|
||||||
|
result[14] = a[13] * b[2] + a[14] * b[6] + a[15] * b[10] + a[16] * b[14]
|
||||||
|
result[15] = a[13] * b[3] + a[14] * b[7] + a[15] * b[11] + a[16] * b[15]
|
||||||
|
result[16] = a[13] * b[4] + a[14] * b[8] + a[15] * b[12] + a[16] * b[16]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultVec(result, a, v)
|
||||||
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4] * v[4]
|
||||||
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8] * v[4]
|
||||||
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12] * v[4]
|
||||||
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16] * v[4]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultVec3(result, a, v)
|
||||||
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4]
|
||||||
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8]
|
||||||
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12]
|
||||||
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function LookAt(mat, campos, targetpos, upvec)
|
||||||
|
local forward = {}
|
||||||
|
local right = {}
|
||||||
|
local up = {}
|
||||||
|
|
||||||
|
VecSubVec3(forward, targetpos, campos)
|
||||||
|
Normalize(forward)
|
||||||
|
|
||||||
|
Cross(right, forward, upvec)
|
||||||
|
Normalize(right)
|
||||||
|
|
||||||
|
Cross(up, right, forward)
|
||||||
|
|
||||||
|
mat[1] = right[1]
|
||||||
|
mat[2] = right[2]
|
||||||
|
mat[3] = right[3]
|
||||||
|
mat[4] = -Dot(right, campos)
|
||||||
|
mat[5] = up[1]
|
||||||
|
mat[6] = up[2]
|
||||||
|
mat[7] = up[3]
|
||||||
|
mat[8] = -Dot(up, campos)
|
||||||
|
mat[9] = -forward[1]
|
||||||
|
mat[10] = -forward[2]
|
||||||
|
mat[11] = -forward[3]
|
||||||
|
mat[12] = Dot(forward, campos)
|
||||||
|
mat[13] = 0.0
|
||||||
|
mat[14] = 0.0
|
||||||
|
mat[15] = 0.0
|
||||||
|
mat[16] = 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Perspective(mat, fov, aspectratio, near, far)
|
||||||
|
local tanhalffovy
|
||||||
|
tanhalffovy = math.tan(fov * 0.5)
|
||||||
|
|
||||||
|
mat[1] = 1 / (aspectratio * tanhalffovy)
|
||||||
|
mat[2] = 0.0
|
||||||
|
mat[3] = 0.0
|
||||||
|
mat[4] = 0.0
|
||||||
|
mat[5] = 0.0
|
||||||
|
mat[6] = 1 / tanhalffovy
|
||||||
|
mat[7] = 0.0
|
||||||
|
mat[8] = 0.0
|
||||||
|
mat[9] = 0.0
|
||||||
|
mat[10] = 0.0
|
||||||
|
mat[11] = -(far + near) / (far - near)
|
||||||
|
mat[12] = -(2 * far * near) / (far - near)
|
||||||
|
mat[13] = 0.0
|
||||||
|
mat[14] = 0.0
|
||||||
|
mat[15] = -1.0
|
||||||
|
mat[16] = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OutputVT100(meta, colorbuffer)
|
||||||
|
print("\x1b[1;1H")
|
||||||
|
|
||||||
|
local r1, g1, b1, r2, b2, g2, width, height, idx, rowoffset
|
||||||
|
width = meta[1]
|
||||||
|
height = meta[2]
|
||||||
|
|
||||||
|
local out = {}
|
||||||
|
|
||||||
|
local pr1, pg1, pb1, pr2, pg2, pb2 = 0, 0, 0, 0, 0, 0
|
||||||
|
|
||||||
|
for y = 0, height - 2, 2 do
|
||||||
|
table.insert(out, "\n")
|
||||||
|
for x = 0, width - 1 do
|
||||||
|
idx = (x + y * width) * 3
|
||||||
|
rowoffset = width * 3
|
||||||
|
|
||||||
|
r1 = math_floor(colorbuffer[1 + idx] * 255)
|
||||||
|
g1 = math_floor(colorbuffer[1 + idx + 1] * 255)
|
||||||
|
b1 = math_floor(colorbuffer[1 + idx + 2] * 255)
|
||||||
|
|
||||||
|
r2 = math_floor(colorbuffer[1 + idx + rowoffset] * 255)
|
||||||
|
g2 = math_floor(colorbuffer[1 + idx + 1 + rowoffset] * 255)
|
||||||
|
b2 = math_floor(colorbuffer[1 + idx + 2 + rowoffset] * 255)
|
||||||
|
|
||||||
|
if r1 == pr1 and g1 == pg1 and b1 == pb1 and r2 == pr2 and g2 == pg2 and b2 == pb2 then
|
||||||
|
table.insert(out, "\xDF")
|
||||||
|
else
|
||||||
|
pr1, pg1, pb1, pr2, pg2, pb2 = r1, g1, b1, r2, g2, b2
|
||||||
|
table.insert(out, string.format("\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dm\xDF", r1, g1, b1, r2, g2, b2))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- io.write("\x1b[38;2;" ..
|
||||||
|
-- r1 .. ";" .. g1 .. ";" .. b1 .. "m" .. "\x1b[48;2;" .. r2 .. ";" .. g2 .. ";" .. b2 .. "m" .. "\xDF")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write(table.concat(out))
|
||||||
|
|
||||||
|
io.write(string.format("\n\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m%d FPS", fps))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function DrawTriangle(meta, colorbuffer, depthbuffer, wp0, wp1, wp2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
||||||
|
local p0 = {}
|
||||||
|
local p1 = {}
|
||||||
|
local p2 = {}
|
||||||
|
|
||||||
|
MatMultVec3(p0, mvp, wp0)
|
||||||
|
MatMultVec3(p1, mvp, wp1)
|
||||||
|
MatMultVec3(p2, mvp, wp2)
|
||||||
|
|
||||||
|
if p0[4] ~= 0.0 and p1[4] ~= 0.0 and p2[4] ~= 0.0 then
|
||||||
|
MapToRes(meta, p0)
|
||||||
|
MapToRes(meta, p1)
|
||||||
|
MapToRes(meta, p2)
|
||||||
|
|
||||||
|
local aabbmin = {}
|
||||||
|
local aabbmax = {}
|
||||||
|
|
||||||
|
aabbmin[1] = Max(Min3(p0[1], p1[1], p2[1]), 0)
|
||||||
|
aabbmin[2] = Max(Min3(p0[2], p1[2], p2[2]), 0)
|
||||||
|
aabbmax[1] = Min(Max3(p0[1], p1[1], p2[1]), meta[1] - 1)
|
||||||
|
aabbmax[2] = Min(Max3(p0[2], p1[2], p2[2]), meta[2] - 1)
|
||||||
|
|
||||||
|
local idx, tx, ty, ti
|
||||||
|
local p = {}
|
||||||
|
local depth
|
||||||
|
local w0, w1, w2, dot00, dot01, dot11, dot20, dot21, denom, d0, d1, d2
|
||||||
|
|
||||||
|
local v0 = {}
|
||||||
|
local v1 = {}
|
||||||
|
local v2 = {}
|
||||||
|
|
||||||
|
local texcoord = {}
|
||||||
|
|
||||||
|
local normal = {}
|
||||||
|
local diff
|
||||||
|
|
||||||
|
for y = math_floor(aabbmin[2]), math_floor(aabbmax[2]) do
|
||||||
|
for x = math_floor(aabbmin[1]), math_floor(aabbmax[1]) do
|
||||||
|
p[1] = x
|
||||||
|
p[2] = y
|
||||||
|
|
||||||
|
if IsOnRight(p0, p1, p) and IsOnRight(p1, p2, p) and IsOnRight(p2, p0, p) then
|
||||||
|
v0[1] = p1[1] - p0[1]
|
||||||
|
v0[2] = p1[2] - p0[2]
|
||||||
|
v1[1] = p2[1] - p0[1]
|
||||||
|
v1[2] = p2[2] - p0[2]
|
||||||
|
v2[1] = p[1] - p0[1]
|
||||||
|
v2[2] = p[2] - p0[2]
|
||||||
|
|
||||||
|
dot00 = Dot2(v0, v0)
|
||||||
|
dot01 = Dot2(v0, v1)
|
||||||
|
dot11 = Dot2(v1, v1)
|
||||||
|
dot20 = Dot2(v2, v0)
|
||||||
|
dot21 = Dot2(v2, v1)
|
||||||
|
|
||||||
|
denom = dot00 * dot11 - dot01 * dot01
|
||||||
|
w1 = (dot11 * dot20 - dot01 * dot21) / denom
|
||||||
|
w2 = (dot00 * dot21 - dot01 * dot20) / denom
|
||||||
|
w0 = 1.0 - w1 - w2
|
||||||
|
|
||||||
|
depth = p0[3] * w0 + p1[3] * w1 + p2[3] * w2
|
||||||
|
|
||||||
|
idx = math_floor(x) + meta[1] * math_floor(y)
|
||||||
|
|
||||||
|
if depth > 0.0 and depthbuffer[1 + idx] > depth then
|
||||||
|
depthbuffer[1 + idx] = depth
|
||||||
|
idx = idx * 3
|
||||||
|
|
||||||
|
texcoord[1] = w0 * c0[1] + w1 * c1[1] + w2 * c2[1]
|
||||||
|
texcoord[2] = w0 * c0[2] + w1 * c1[2] + w2 * c2[2]
|
||||||
|
|
||||||
|
normal[1] = w0 * n0[1] + w1 * n1[1] + w2 * n2[1]
|
||||||
|
normal[2] = w0 * n0[2] + w1 * n1[2] + w2 * n2[2]
|
||||||
|
normal[3] = w0 * n0[3] + w1 * n1[3] + w2 * n2[3]
|
||||||
|
|
||||||
|
Normalize(normal)
|
||||||
|
diff = Max(0.5, Dot(normal, lightdir))
|
||||||
|
|
||||||
|
tx = math_floor(texcoord[1] * meta[4])
|
||||||
|
ty = math_floor((1 - texcoord[2]) * meta[5])
|
||||||
|
ti = (tx + ty * meta[4]) * 3
|
||||||
|
|
||||||
|
|
||||||
|
-- uz ne kokote
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
colorbuffer[1 + idx] = texture[1 + ti] / 255 * diff
|
||||||
|
colorbuffer[1 + idx + 1] = texture[1 + ti + 1] / 255 * diff
|
||||||
|
colorbuffer[1 + idx + 2] = texture[1 + ti + 2] / 255 * diff
|
||||||
|
|
||||||
|
OutputVT100(meta, colorbuffer)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = io.open("data.txt", "r")
|
||||||
|
|
||||||
|
local function Input()
|
||||||
|
return file:read("*n")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- file:close() -- Close the file
|
||||||
|
|
||||||
|
-- return number
|
||||||
|
|
||||||
|
local function Main()
|
||||||
|
os.execute(" ")
|
||||||
|
|
||||||
|
local meta = {}
|
||||||
|
|
||||||
|
-- meta[1] = 175
|
||||||
|
-- meta[2] = 120
|
||||||
|
|
||||||
|
meta[1] = 175 * 2
|
||||||
|
meta[2] = 120 * 2
|
||||||
|
|
||||||
|
meta[3] = meta[1] * meta[2]
|
||||||
|
|
||||||
|
local depthbuffer = {}
|
||||||
|
local colorbuffer = {}
|
||||||
|
|
||||||
|
local background = {}
|
||||||
|
background[1] = 0.3
|
||||||
|
background[2] = 0.3
|
||||||
|
background[3] = 0.3
|
||||||
|
|
||||||
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
||||||
|
|
||||||
|
local lightdir = {}
|
||||||
|
lightdir[1] = .3
|
||||||
|
lightdir[2] = 1
|
||||||
|
lightdir[3] = .4
|
||||||
|
Normalize(lightdir)
|
||||||
|
|
||||||
|
local view = {}
|
||||||
|
local proj = {}
|
||||||
|
local mvp = {}
|
||||||
|
|
||||||
|
local campos = {}
|
||||||
|
local targetpos = {}
|
||||||
|
local upvector = {}
|
||||||
|
|
||||||
|
targetpos[1] = 0
|
||||||
|
targetpos[2] = 0
|
||||||
|
targetpos[3] = 0
|
||||||
|
|
||||||
|
upvector[1] = 0
|
||||||
|
upvector[2] = 1
|
||||||
|
upvector[3] = 0
|
||||||
|
local aspectratio
|
||||||
|
aspectratio = 1.46
|
||||||
|
|
||||||
|
|
||||||
|
Perspective(proj, DegToRad(90.0) / aspectratio, aspectratio, 0.1, 50.0)
|
||||||
|
|
||||||
|
local p0 = {}
|
||||||
|
local p1 = {}
|
||||||
|
local p2 = {}
|
||||||
|
|
||||||
|
local c0 = {}
|
||||||
|
local c1 = {}
|
||||||
|
local c2 = {}
|
||||||
|
|
||||||
|
local n0 = {}
|
||||||
|
local n1 = {}
|
||||||
|
local n2 = {}
|
||||||
|
|
||||||
|
local datasize, i, vertices
|
||||||
|
datasize = Input()
|
||||||
|
vertices = Input()
|
||||||
|
|
||||||
|
local data = {}
|
||||||
|
for i = 1, datasize do
|
||||||
|
data[i] = Input()
|
||||||
|
end
|
||||||
|
|
||||||
|
print("model rdy")
|
||||||
|
|
||||||
|
meta[4] = Input()
|
||||||
|
meta[5] = Input()
|
||||||
|
|
||||||
|
local tp
|
||||||
|
tp = meta[4] * meta[5] * 3
|
||||||
|
|
||||||
|
local texture = {}
|
||||||
|
|
||||||
|
for i = 0, tp - 1 do
|
||||||
|
texture[1 + i] = Input()
|
||||||
|
end
|
||||||
|
|
||||||
|
print("textura rdy")
|
||||||
|
|
||||||
|
local temp
|
||||||
|
|
||||||
|
local i0, i1, i2
|
||||||
|
|
||||||
|
local camangle
|
||||||
|
camangle = 0
|
||||||
|
|
||||||
|
local frames = 0
|
||||||
|
local lastframereset = 0
|
||||||
|
|
||||||
|
while true do
|
||||||
|
frames = frames + 1
|
||||||
|
|
||||||
|
time = os.clock() * 1000
|
||||||
|
|
||||||
|
if time > lastframereset + 1000 then
|
||||||
|
fps = frames
|
||||||
|
frames = 0
|
||||||
|
lastframereset = time
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
||||||
|
|
||||||
|
local camdis
|
||||||
|
camdis = 7.0
|
||||||
|
|
||||||
|
campos[1] = math.sin(camangle) * camdis
|
||||||
|
campos[2] = 0.8 * camdis
|
||||||
|
campos[3] = math.cos(camangle) * camdis
|
||||||
|
|
||||||
|
|
||||||
|
camangle = time * 0.0003
|
||||||
|
|
||||||
|
LookAt(view, campos, targetpos, upvector)
|
||||||
|
MatMultMat(mvp, proj, view)
|
||||||
|
|
||||||
|
for i = 0, vertices - 3, 3 do
|
||||||
|
i0 = i * 8
|
||||||
|
i1 = (i + 1) * 8
|
||||||
|
i2 = (i + 2) * 8
|
||||||
|
|
||||||
|
p0[1] = data[1 + i0]
|
||||||
|
p0[2] = data[1 + i0 + 1]
|
||||||
|
p0[3] = data[1 + i0 + 2]
|
||||||
|
|
||||||
|
p1[1] = data[1 + i1]
|
||||||
|
p1[2] = data[1 + i1 + 1]
|
||||||
|
p1[3] = data[1 + i1 + 2]
|
||||||
|
|
||||||
|
p2[1] = data[1 + i2]
|
||||||
|
p2[2] = data[1 + i2 + 1]
|
||||||
|
p2[3] = data[1 + i2 + 2]
|
||||||
|
|
||||||
|
|
||||||
|
c0[1] = data[1 + i0 + 3]
|
||||||
|
c0[2] = data[1 + i0 + 4]
|
||||||
|
|
||||||
|
c1[1] = data[1 + i1 + 3]
|
||||||
|
c1[2] = data[1 + i1 + 4]
|
||||||
|
|
||||||
|
c2[1] = data[1 + i2 + 3]
|
||||||
|
c2[2] = data[1 + i2 + 4]
|
||||||
|
|
||||||
|
n0[1] = data[1 + i0 + 5]
|
||||||
|
n0[2] = data[1 + i0 + 6]
|
||||||
|
n0[3] = data[1 + i0 + 7]
|
||||||
|
|
||||||
|
n1[1] = data[1 + i1 + 5]
|
||||||
|
n1[2] = data[1 + i1 + 6]
|
||||||
|
n1[3] = data[1 + i1 + 7]
|
||||||
|
|
||||||
|
n2[1] = data[1 + i2 + 5]
|
||||||
|
n2[2] = data[1 + i2 + 6]
|
||||||
|
n2[3] = data[1 + i2 + 7]
|
||||||
|
|
||||||
|
DrawTriangle(meta, colorbuffer, depthbuffer, p0, p1, p2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
OutputVT100(meta, colorbuffer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Main()
|
||||||
616
render_cc.lua
Normal file
616
render_cc.lua
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
local fps = 0
|
||||||
|
local math_floor = math.floor
|
||||||
|
local time = 0
|
||||||
|
|
||||||
|
local function ClearBuffers(meta, colorbuffer, depthbuffer, color, depth)
|
||||||
|
local i
|
||||||
|
for i = 0, meta[3] - 1 do
|
||||||
|
colorbuffer[1 + i * 3] = color[1]
|
||||||
|
colorbuffer[1 + i * 3 + 1] = color[2]
|
||||||
|
colorbuffer[1 + i * 3 + 2] = color[3]
|
||||||
|
|
||||||
|
depthbuffer[1 + i] = depth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function DegToRad(deg)
|
||||||
|
local rad
|
||||||
|
rad = deg * 0.0174532925
|
||||||
|
return rad
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Min(a, b)
|
||||||
|
local r
|
||||||
|
if a < b then
|
||||||
|
r = a
|
||||||
|
else
|
||||||
|
r = b
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Min3(a, b, c)
|
||||||
|
local r
|
||||||
|
r = Min(Min(a, b), c)
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Max(a, b)
|
||||||
|
local r
|
||||||
|
if a > b then
|
||||||
|
r = a
|
||||||
|
else
|
||||||
|
r = b
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Max3(a, b, c)
|
||||||
|
local r
|
||||||
|
r = Max(Max(a, b), c)
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function IsOnRight(a, b, c)
|
||||||
|
local r
|
||||||
|
if (b[1] - a[1]) * (c[2] - a[2]) - (b[2] - a[2]) * (c[1] - a[1]) <= 0 then
|
||||||
|
r = true
|
||||||
|
else
|
||||||
|
r = false
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Distance2(a, b)
|
||||||
|
local x, y, d
|
||||||
|
x = b[1] - a[1]
|
||||||
|
y = b[2] - a[2]
|
||||||
|
d = math.sqrt(x * x + y * y)
|
||||||
|
return d
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Normalize(a)
|
||||||
|
local l
|
||||||
|
l = math.sqrt(a[1] * a[1] + a[2] * a[2] + a[3] * a[3])
|
||||||
|
a[1] = a[1] / l
|
||||||
|
a[2] = a[2] / l
|
||||||
|
a[3] = a[3] / l
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MapToRes(meta, a)
|
||||||
|
a[1] = a[1] / a[4]
|
||||||
|
a[2] = a[2] / a[4]
|
||||||
|
a[3] = a[3] / a[4]
|
||||||
|
|
||||||
|
a[1] = (a[1] + 1.0) * 0.5 * (meta[1] - 1)
|
||||||
|
a[2] = (1.0 - a[2]) * 0.5 * (meta[2] - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Cross(result, a, b)
|
||||||
|
result[1] = a[2] * b[3] - a[3] * b[2]
|
||||||
|
result[2] = a[3] * b[1] - a[1] * b[3]
|
||||||
|
result[3] = a[1] * b[2] - a[2] * b[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Dot(a, b)
|
||||||
|
local result
|
||||||
|
result = a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Dot2(a, b)
|
||||||
|
local result
|
||||||
|
result = a[1] * b[1] + a[2] * b[2]
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function VecCopy3(result, a)
|
||||||
|
result[1] = a[1]
|
||||||
|
result[2] = a[2]
|
||||||
|
result[3] = a[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function VecSubVec3(result, a, b)
|
||||||
|
result[1] = a[1] - b[1]
|
||||||
|
result[2] = a[2] - b[2]
|
||||||
|
result[3] = a[3] - b[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultMat(result, a, b)
|
||||||
|
result[1] = a[1] * b[1] + a[2] * b[5] + a[3] * b[9] + a[4] * b[13]
|
||||||
|
result[2] = a[1] * b[2] + a[2] * b[6] + a[3] * b[10] + a[4] * b[14]
|
||||||
|
result[3] = a[1] * b[3] + a[2] * b[7] + a[3] * b[11] + a[4] * b[15]
|
||||||
|
result[4] = a[1] * b[4] + a[2] * b[8] + a[3] * b[12] + a[4] * b[16]
|
||||||
|
result[5] = a[5] * b[1] + a[6] * b[5] + a[7] * b[9] + a[8] * b[13]
|
||||||
|
result[6] = a[5] * b[2] + a[6] * b[6] + a[7] * b[10] + a[8] * b[14]
|
||||||
|
result[7] = a[5] * b[3] + a[6] * b[7] + a[7] * b[11] + a[8] * b[15]
|
||||||
|
result[8] = a[5] * b[4] + a[6] * b[8] + a[7] * b[12] + a[8] * b[16]
|
||||||
|
result[9] = a[9] * b[1] + a[10] * b[5] + a[11] * b[9] + a[12] * b[13]
|
||||||
|
result[10] = a[9] * b[2] + a[10] * b[6] + a[11] * b[10] + a[12] * b[14]
|
||||||
|
result[11] = a[9] * b[3] + a[10] * b[7] + a[11] * b[11] + a[12] * b[15]
|
||||||
|
result[12] = a[9] * b[4] + a[10] * b[8] + a[11] * b[12] + a[12] * b[16]
|
||||||
|
result[13] = a[13] * b[1] + a[14] * b[5] + a[15] * b[9] + a[16] * b[13]
|
||||||
|
result[14] = a[13] * b[2] + a[14] * b[6] + a[15] * b[10] + a[16] * b[14]
|
||||||
|
result[15] = a[13] * b[3] + a[14] * b[7] + a[15] * b[11] + a[16] * b[15]
|
||||||
|
result[16] = a[13] * b[4] + a[14] * b[8] + a[15] * b[12] + a[16] * b[16]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultVec(result, a, v)
|
||||||
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4] * v[4]
|
||||||
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8] * v[4]
|
||||||
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12] * v[4]
|
||||||
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16] * v[4]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultVec3(result, a, v)
|
||||||
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4]
|
||||||
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8]
|
||||||
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12]
|
||||||
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function LookAt(mat, campos, targetpos, upvec)
|
||||||
|
local forward = {}
|
||||||
|
local right = {}
|
||||||
|
local up = {}
|
||||||
|
|
||||||
|
VecSubVec3(forward, targetpos, campos)
|
||||||
|
Normalize(forward)
|
||||||
|
|
||||||
|
Cross(right, forward, upvec)
|
||||||
|
Normalize(right)
|
||||||
|
|
||||||
|
Cross(up, right, forward)
|
||||||
|
|
||||||
|
mat[1] = right[1]
|
||||||
|
mat[2] = right[2]
|
||||||
|
mat[3] = right[3]
|
||||||
|
mat[4] = -Dot(right, campos)
|
||||||
|
mat[5] = up[1]
|
||||||
|
mat[6] = up[2]
|
||||||
|
mat[7] = up[3]
|
||||||
|
mat[8] = -Dot(up, campos)
|
||||||
|
mat[9] = -forward[1]
|
||||||
|
mat[10] = -forward[2]
|
||||||
|
mat[11] = -forward[3]
|
||||||
|
mat[12] = Dot(forward, campos)
|
||||||
|
mat[13] = 0.0
|
||||||
|
mat[14] = 0.0
|
||||||
|
mat[15] = 0.0
|
||||||
|
mat[16] = 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Perspective(mat, fov, aspectratio, near, far)
|
||||||
|
local tanhalffovy
|
||||||
|
tanhalffovy = math.tan(fov * 0.5)
|
||||||
|
|
||||||
|
mat[1] = 1 / (aspectratio * tanhalffovy)
|
||||||
|
mat[2] = 0.0
|
||||||
|
mat[3] = 0.0
|
||||||
|
mat[4] = 0.0
|
||||||
|
mat[5] = 0.0
|
||||||
|
mat[6] = 1 / tanhalffovy
|
||||||
|
mat[7] = 0.0
|
||||||
|
mat[8] = 0.0
|
||||||
|
mat[9] = 0.0
|
||||||
|
mat[10] = 0.0
|
||||||
|
mat[11] = -(far + near) / (far - near)
|
||||||
|
mat[12] = -(2 * far * near) / (far - near)
|
||||||
|
mat[13] = 0.0
|
||||||
|
mat[14] = 0.0
|
||||||
|
mat[15] = -1.0
|
||||||
|
mat[16] = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- local function OutputVT100(meta, colorbuffer)
|
||||||
|
-- print("\x1b[1;1H")
|
||||||
|
|
||||||
|
-- local r1, g1, b1, r2, b2, g2, width, height, idx, rowoffset
|
||||||
|
-- width = meta[1]
|
||||||
|
-- height = meta[2]
|
||||||
|
|
||||||
|
-- local out = {}
|
||||||
|
|
||||||
|
-- local pr1, pg1, pb1, pr2, pg2, pb2 = 0, 0, 0, 0, 0, 0
|
||||||
|
|
||||||
|
-- for y = 0, height - 2, 2 do
|
||||||
|
-- table.insert(out, "\n")
|
||||||
|
-- for x = 0, width - 1 do
|
||||||
|
-- idx = (x + y * width) * 3
|
||||||
|
-- rowoffset = width * 3
|
||||||
|
|
||||||
|
-- r1 = math_floor(colorbuffer[1 + idx] * 255)
|
||||||
|
-- g1 = math_floor(colorbuffer[1 + idx + 1] * 255)
|
||||||
|
-- b1 = math_floor(colorbuffer[1 + idx + 2] * 255)
|
||||||
|
|
||||||
|
-- r2 = math_floor(colorbuffer[1 + idx + rowoffset] * 255)
|
||||||
|
-- g2 = math_floor(colorbuffer[1 + idx + 1 + rowoffset] * 255)
|
||||||
|
-- b2 = math_floor(colorbuffer[1 + idx + 2 + rowoffset] * 255)
|
||||||
|
|
||||||
|
-- if r1 == pr1 and g1 == pg1 and b1 == pb1 and r2 == pr2 and g2 == pg2 and b2 == pb2 then
|
||||||
|
-- table.insert(out, "\xDF")
|
||||||
|
-- else
|
||||||
|
-- pr1, pg1, pb1, pr2, pg2, pb2 = r1, g1, b1, r2, g2, b2
|
||||||
|
-- table.insert(out, string.format("\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dm\xDF", r1, g1, b1, r2, g2, b2))
|
||||||
|
-- end
|
||||||
|
|
||||||
|
|
||||||
|
-- -- io.write("\x1b[38;2;" ..
|
||||||
|
-- -- r1 .. ";" .. g1 .. ";" .. b1 .. "m" .. "\x1b[48;2;" .. r2 .. ";" .. g2 .. ";" .. b2 .. "m" .. "\xDF")
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- io.write(table.concat(out))
|
||||||
|
|
||||||
|
-- io.write(string.format("\n\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m%d FPS", fps))
|
||||||
|
-- end
|
||||||
|
|
||||||
|
local monitor = peripheral.find("monitor")
|
||||||
|
|
||||||
|
local function SetupMonitor()
|
||||||
|
monitor.setTextScale(0.5)
|
||||||
|
monitor.clear()
|
||||||
|
|
||||||
|
monitor.setPaletteColor(colors.white, 0, 0, 0 ) -- 0
|
||||||
|
monitor.setPaletteColor(colors.orange, 0, 0, 127 ) -- 1
|
||||||
|
monitor.setPaletteColor(colors.magenta, 0, 127, 0 ) -- 2
|
||||||
|
monitor.setPaletteColor(colors.lightBlue, 0, 127, 127 ) -- 3
|
||||||
|
monitor.setPaletteColor(colors.yellow, 127, 0, 0 ) -- 4
|
||||||
|
monitor.setPaletteColor(colors.lime, 127, 0, 127 ) -- 5
|
||||||
|
monitor.setPaletteColor(colors.pink, 127, 127, 0 ) -- 6
|
||||||
|
monitor.setPaletteColor(colors.gray, 127, 127, 127 ) -- 7
|
||||||
|
|
||||||
|
monitor.setPaletteColor(colors.lightGray, 127, 127, 127 ) -- 8
|
||||||
|
monitor.setPaletteColor(colors.cyan, 127, 127, 255 ) -- 9
|
||||||
|
monitor.setPaletteColor(colors.purple, 127, 255, 127 ) -- a
|
||||||
|
monitor.setPaletteColor(colors.blue, 127, 255, 255 ) -- b
|
||||||
|
monitor.setPaletteColor(colors.brown, 255, 127, 127 ) -- c
|
||||||
|
monitor.setPaletteColor(colors.green, 255, 127, 255 ) -- d
|
||||||
|
monitor.setPaletteColor(colors.red, 255, 255, 127 ) -- e
|
||||||
|
monitor.setPaletteColor(colors.black, 255, 255, 255 ) -- f
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OutputCCMonitor(meta, colorbuffer)
|
||||||
|
|
||||||
|
local width = meta[1]
|
||||||
|
local height = meta[2]
|
||||||
|
|
||||||
|
local chars = {}
|
||||||
|
local fcs = {}
|
||||||
|
local bcs = {}
|
||||||
|
local hex_digits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }
|
||||||
|
|
||||||
|
for y = 0, height - 1 do
|
||||||
|
for x = 0, width - 1 do
|
||||||
|
idx = (x + y * width) * 3
|
||||||
|
rowoffset = width * 3
|
||||||
|
|
||||||
|
local r = colorbuffer[1 + idx]
|
||||||
|
local g = colorbuffer[1 + idx + 1]
|
||||||
|
local b = colorbuffer[1 + idx + 2]
|
||||||
|
|
||||||
|
local avg = (r + g + b) / 3
|
||||||
|
|
||||||
|
local c = 0
|
||||||
|
local threshold = 1.2
|
||||||
|
if b > avg * threshold then c = c + 1 end
|
||||||
|
if g > avg * threshold then c = c + 2 end
|
||||||
|
if r > avg * threshold then c = c + 4 end
|
||||||
|
|
||||||
|
local bright_threshold = 0.5
|
||||||
|
if r > bright_threshold or g > bright_threshold or b > bright_threshold then c = c + 8 end
|
||||||
|
|
||||||
|
local xx = x + 1
|
||||||
|
local cc = hex_digits[c + 1]
|
||||||
|
chars[xx] = " "
|
||||||
|
fcs[xx] = cc
|
||||||
|
bcs[xx] = cc
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
monitor.setCursorPos(1, y + 1)
|
||||||
|
monitor.blit(table.concat(chars), table.concat(fcs), table.concat(bcs))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function DrawTriangle(meta, colorbuffer, depthbuffer, wp0, wp1, wp2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
||||||
|
local p0 = {}
|
||||||
|
local p1 = {}
|
||||||
|
local p2 = {}
|
||||||
|
|
||||||
|
MatMultVec3(p0, mvp, wp0)
|
||||||
|
MatMultVec3(p1, mvp, wp1)
|
||||||
|
MatMultVec3(p2, mvp, wp2)
|
||||||
|
|
||||||
|
if p0[4] ~= 0.0 and p1[4] ~= 0.0 and p2[4] ~= 0.0 then
|
||||||
|
MapToRes(meta, p0)
|
||||||
|
MapToRes(meta, p1)
|
||||||
|
MapToRes(meta, p2)
|
||||||
|
|
||||||
|
local aabbmin = {}
|
||||||
|
local aabbmax = {}
|
||||||
|
|
||||||
|
aabbmin[1] = Max(Min3(p0[1], p1[1], p2[1]), 0)
|
||||||
|
aabbmin[2] = Max(Min3(p0[2], p1[2], p2[2]), 0)
|
||||||
|
aabbmax[1] = Min(Max3(p0[1], p1[1], p2[1]), meta[1] - 1)
|
||||||
|
aabbmax[2] = Min(Max3(p0[2], p1[2], p2[2]), meta[2] - 1)
|
||||||
|
|
||||||
|
local idx, tx, ty, ti
|
||||||
|
local p = {}
|
||||||
|
local depth
|
||||||
|
local w0, w1, w2, dot00, dot01, dot11, dot20, dot21, denom, d0, d1, d2
|
||||||
|
|
||||||
|
local v0 = {}
|
||||||
|
local v1 = {}
|
||||||
|
local v2 = {}
|
||||||
|
|
||||||
|
local texcoord = {}
|
||||||
|
|
||||||
|
local normal = {}
|
||||||
|
local diff
|
||||||
|
|
||||||
|
for y = math_floor(aabbmin[2]), math_floor(aabbmax[2]) do
|
||||||
|
for x = math_floor(aabbmin[1]), math_floor(aabbmax[1]) do
|
||||||
|
p[1] = x
|
||||||
|
p[2] = y
|
||||||
|
|
||||||
|
if IsOnRight(p0, p1, p) and IsOnRight(p1, p2, p) and IsOnRight(p2, p0, p) then
|
||||||
|
v0[1] = p1[1] - p0[1]
|
||||||
|
v0[2] = p1[2] - p0[2]
|
||||||
|
v1[1] = p2[1] - p0[1]
|
||||||
|
v1[2] = p2[2] - p0[2]
|
||||||
|
v2[1] = p[1] - p0[1]
|
||||||
|
v2[2] = p[2] - p0[2]
|
||||||
|
|
||||||
|
dot00 = Dot2(v0, v0)
|
||||||
|
dot01 = Dot2(v0, v1)
|
||||||
|
dot11 = Dot2(v1, v1)
|
||||||
|
dot20 = Dot2(v2, v0)
|
||||||
|
dot21 = Dot2(v2, v1)
|
||||||
|
|
||||||
|
denom = dot00 * dot11 - dot01 * dot01
|
||||||
|
w1 = (dot11 * dot20 - dot01 * dot21) / denom
|
||||||
|
w2 = (dot00 * dot21 - dot01 * dot20) / denom
|
||||||
|
w0 = 1.0 - w1 - w2
|
||||||
|
|
||||||
|
depth = p0[3] * w0 + p1[3] * w1 + p2[3] * w2
|
||||||
|
|
||||||
|
idx = math_floor(x) + meta[1] * math_floor(y)
|
||||||
|
|
||||||
|
if depth > 0.0 and depthbuffer[1 + idx] > depth then
|
||||||
|
depthbuffer[1 + idx] = depth
|
||||||
|
idx = idx * 3
|
||||||
|
|
||||||
|
texcoord[1] = w0 * c0[1] + w1 * c1[1] + w2 * c2[1]
|
||||||
|
texcoord[2] = w0 * c0[2] + w1 * c1[2] + w2 * c2[2]
|
||||||
|
|
||||||
|
normal[1] = w0 * n0[1] + w1 * n1[1] + w2 * n2[1]
|
||||||
|
normal[2] = w0 * n0[2] + w1 * n1[2] + w2 * n2[2]
|
||||||
|
normal[3] = w0 * n0[3] + w1 * n1[3] + w2 * n2[3]
|
||||||
|
|
||||||
|
Normalize(normal)
|
||||||
|
diff = Max(0.5, Dot(normal, lightdir))
|
||||||
|
|
||||||
|
tx = math_floor(texcoord[1] * meta[4])
|
||||||
|
ty = math_floor((1 - texcoord[2]) * meta[5])
|
||||||
|
ti = (tx + ty * meta[4]) * 3
|
||||||
|
|
||||||
|
|
||||||
|
-- uz ne kokote
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
colorbuffer[1 + idx] = texture[1 + ti] / 255 * diff
|
||||||
|
colorbuffer[1 + idx + 1] = texture[1 + ti + 1] / 255 * diff
|
||||||
|
colorbuffer[1 + idx + 2] = texture[1 + ti + 2] / 255 * diff
|
||||||
|
|
||||||
|
-- OutputVT100(meta, colorbuffer)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = assert(io.open("mesh.txt", "r"))
|
||||||
|
|
||||||
|
local function Input()
|
||||||
|
return tonumber(file:read())
|
||||||
|
end
|
||||||
|
|
||||||
|
-- file:close() -- Close the file
|
||||||
|
|
||||||
|
-- return number
|
||||||
|
|
||||||
|
function load_texture(filename)
|
||||||
|
local file = assert(io.open(filename, "rb"))
|
||||||
|
local data = file:read("*all")
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
local tex = {}
|
||||||
|
for i = 1, #data do
|
||||||
|
tex[i] = string.byte(data, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
return tex
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Main()
|
||||||
|
SetupMonitor()
|
||||||
|
|
||||||
|
local meta = {}
|
||||||
|
|
||||||
|
-- meta[1] = 175
|
||||||
|
-- meta[2] = 120
|
||||||
|
|
||||||
|
meta[1] = 79
|
||||||
|
meta[2] = 38
|
||||||
|
local charaspect = 1.5
|
||||||
|
|
||||||
|
meta[3] = meta[1] * meta[2]
|
||||||
|
|
||||||
|
local depthbuffer = {}
|
||||||
|
local colorbuffer = {}
|
||||||
|
|
||||||
|
local background = {}
|
||||||
|
background[1] = 0.3
|
||||||
|
background[2] = 0.3
|
||||||
|
background[3] = 0.3
|
||||||
|
|
||||||
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
||||||
|
|
||||||
|
local lightdir = {}
|
||||||
|
lightdir[1] = .3
|
||||||
|
lightdir[2] = 1
|
||||||
|
lightdir[3] = .4
|
||||||
|
Normalize(lightdir)
|
||||||
|
|
||||||
|
local view = {}
|
||||||
|
local proj = {}
|
||||||
|
local mvp = {}
|
||||||
|
|
||||||
|
local campos = {}
|
||||||
|
local targetpos = {}
|
||||||
|
local upvector = {}
|
||||||
|
|
||||||
|
targetpos[1] = 0
|
||||||
|
targetpos[2] = 0
|
||||||
|
targetpos[3] = 0
|
||||||
|
|
||||||
|
upvector[1] = 0
|
||||||
|
upvector[2] = 1
|
||||||
|
upvector[3] = 0
|
||||||
|
local aspectratio
|
||||||
|
aspectratio = (meta[1] / meta[2]) / charaspect
|
||||||
|
|
||||||
|
|
||||||
|
Perspective(proj, DegToRad(90.0) / aspectratio, aspectratio, 0.1, 50.0)
|
||||||
|
|
||||||
|
local p0 = {}
|
||||||
|
local p1 = {}
|
||||||
|
local p2 = {}
|
||||||
|
|
||||||
|
local c0 = {}
|
||||||
|
local c1 = {}
|
||||||
|
local c2 = {}
|
||||||
|
|
||||||
|
local n0 = {}
|
||||||
|
local n1 = {}
|
||||||
|
local n2 = {}
|
||||||
|
|
||||||
|
local i, vertices
|
||||||
|
vertices = Input()
|
||||||
|
local datasize = vertices * 8
|
||||||
|
|
||||||
|
local data = {}
|
||||||
|
for i = 1, datasize do
|
||||||
|
data[i] = Input()
|
||||||
|
end
|
||||||
|
|
||||||
|
print("model rdy")
|
||||||
|
|
||||||
|
meta[4] = 256 -- tex width
|
||||||
|
meta[5] = 256 -- tex height
|
||||||
|
|
||||||
|
-- local tp
|
||||||
|
-- tp = meta[4] * meta[5] * 3
|
||||||
|
|
||||||
|
-- local texture = {}
|
||||||
|
|
||||||
|
-- for i = 0, tp - 1 do
|
||||||
|
-- texture[1 + i] = Input()
|
||||||
|
-- end
|
||||||
|
|
||||||
|
local texture = load_texture("texture.bin")
|
||||||
|
|
||||||
|
print("textura rdy")
|
||||||
|
|
||||||
|
local temp
|
||||||
|
|
||||||
|
local i0, i1, i2
|
||||||
|
|
||||||
|
local camangle
|
||||||
|
camangle = 0
|
||||||
|
|
||||||
|
local frames = 0
|
||||||
|
local lastframereset = 0
|
||||||
|
|
||||||
|
while true do
|
||||||
|
frames = frames + 1
|
||||||
|
|
||||||
|
time = os.clock() * 1000
|
||||||
|
|
||||||
|
if time > lastframereset + 1000 then
|
||||||
|
fps = frames
|
||||||
|
frames = 0
|
||||||
|
lastframereset = time
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
||||||
|
|
||||||
|
local camdis
|
||||||
|
camdis = 7.0
|
||||||
|
|
||||||
|
campos[1] = math.sin(camangle) * camdis
|
||||||
|
campos[2] = 0.8 * camdis
|
||||||
|
campos[3] = math.cos(camangle) * camdis
|
||||||
|
|
||||||
|
|
||||||
|
camangle = time * 0.0005
|
||||||
|
|
||||||
|
LookAt(view, campos, targetpos, upvector)
|
||||||
|
MatMultMat(mvp, proj, view)
|
||||||
|
|
||||||
|
for i = 0, vertices - 3, 3 do
|
||||||
|
i0 = i * 8
|
||||||
|
i1 = (i + 1) * 8
|
||||||
|
i2 = (i + 2) * 8
|
||||||
|
|
||||||
|
p0[1] = data[1 + i0]
|
||||||
|
p0[2] = data[1 + i0 + 1]
|
||||||
|
p0[3] = data[1 + i0 + 2]
|
||||||
|
|
||||||
|
p1[1] = data[1 + i1]
|
||||||
|
p1[2] = data[1 + i1 + 1]
|
||||||
|
p1[3] = data[1 + i1 + 2]
|
||||||
|
|
||||||
|
p2[1] = data[1 + i2]
|
||||||
|
p2[2] = data[1 + i2 + 1]
|
||||||
|
p2[3] = data[1 + i2 + 2]
|
||||||
|
|
||||||
|
|
||||||
|
c0[1] = data[1 + i0 + 3]
|
||||||
|
c0[2] = data[1 + i0 + 4]
|
||||||
|
|
||||||
|
c1[1] = data[1 + i1 + 3]
|
||||||
|
c1[2] = data[1 + i1 + 4]
|
||||||
|
|
||||||
|
c2[1] = data[1 + i2 + 3]
|
||||||
|
c2[2] = data[1 + i2 + 4]
|
||||||
|
|
||||||
|
n0[1] = data[1 + i0 + 5]
|
||||||
|
n0[2] = data[1 + i0 + 6]
|
||||||
|
n0[3] = data[1 + i0 + 7]
|
||||||
|
|
||||||
|
n1[1] = data[1 + i1 + 5]
|
||||||
|
n1[2] = data[1 + i1 + 6]
|
||||||
|
n1[3] = data[1 + i1 + 7]
|
||||||
|
|
||||||
|
n2[1] = data[1 + i2 + 5]
|
||||||
|
n2[2] = data[1 + i2 + 6]
|
||||||
|
n2[3] = data[1 + i2 + 7]
|
||||||
|
|
||||||
|
DrawTriangle(meta, colorbuffer, depthbuffer, p0, p1, p2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
OutputCCMonitor(meta, colorbuffer)
|
||||||
|
|
||||||
|
os.sleep(0.01)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Main()
|
||||||
522
render_origo.lua
Normal file
522
render_origo.lua
Normal file
@ -0,0 +1,522 @@
|
|||||||
|
local fps = 0
|
||||||
|
|
||||||
|
local function ClearBuffers(meta, colorbuffer, depthbuffer, color, depth)
|
||||||
|
local i
|
||||||
|
for i = 0, meta[3] - 1 do
|
||||||
|
colorbuffer[1 + i * 3] = color[1]
|
||||||
|
colorbuffer[1 + i * 3 + 1] = color[2]
|
||||||
|
colorbuffer[1 + i * 3 + 2] = color[3]
|
||||||
|
|
||||||
|
depthbuffer[1 + i] = depth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function DegToRad(deg)
|
||||||
|
local rad
|
||||||
|
rad = deg * 0.0174532925
|
||||||
|
return rad
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Min(a, b)
|
||||||
|
local r
|
||||||
|
if a < b then
|
||||||
|
r = a
|
||||||
|
else
|
||||||
|
r = b
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Min3(a, b, c)
|
||||||
|
local r
|
||||||
|
r = Min(Min(a, b), c)
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Max(a, b)
|
||||||
|
local r
|
||||||
|
if a > b then
|
||||||
|
r = a
|
||||||
|
else
|
||||||
|
r = b
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Max3(a, b, c)
|
||||||
|
local r
|
||||||
|
r = Max(Max(a, b), c)
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function IsOnRight(a, b, c)
|
||||||
|
local r
|
||||||
|
if (b[1] - a[1]) * (c[2] - a[2]) - (b[2] - a[2]) * (c[1] - a[1]) <= 0 then
|
||||||
|
r = true
|
||||||
|
else
|
||||||
|
r = false
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Distance2(a, b)
|
||||||
|
local x, y, d
|
||||||
|
x = b[1] - a[1]
|
||||||
|
y = b[2] - a[2]
|
||||||
|
d = math.sqrt(x * x + y * y)
|
||||||
|
return d
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Normalize(a)
|
||||||
|
local l
|
||||||
|
l = math.sqrt(a[1] * a[1] + a[2] * a[2] + a[3] * a[3])
|
||||||
|
a[1] = a[1] / l
|
||||||
|
a[2] = a[2] / l
|
||||||
|
a[3] = a[3] / l
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MapToRes(meta, a)
|
||||||
|
a[1] = a[1] / a[4]
|
||||||
|
a[2] = a[2] / a[4]
|
||||||
|
a[3] = a[3] / a[4]
|
||||||
|
|
||||||
|
a[1] = (a[1] + 1.0) * 0.5 * (meta[1] - 1)
|
||||||
|
a[2] = (1.0 - a[2]) * 0.5 * (meta[2] - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Cross(result, a, b)
|
||||||
|
result[1] = a[2] * b[3] - a[3] * b[2]
|
||||||
|
result[2] = a[3] * b[1] - a[1] * b[3]
|
||||||
|
result[3] = a[1] * b[2] - a[2] * b[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Dot(a, b)
|
||||||
|
local result
|
||||||
|
result = a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Dot2(a, b)
|
||||||
|
local result
|
||||||
|
result = a[1] * b[1] + a[2] * b[2]
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function VecCopy3(result, a)
|
||||||
|
result[1] = a[1]
|
||||||
|
result[2] = a[2]
|
||||||
|
result[3] = a[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function VecSubVec3(result, a, b)
|
||||||
|
result[1] = a[1] - b[1]
|
||||||
|
result[2] = a[2] - b[2]
|
||||||
|
result[3] = a[3] - b[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultMat(result, a, b)
|
||||||
|
result[1] = a[1] * b[1] + a[2] * b[5] + a[3] * b[9] + a[4] * b[13]
|
||||||
|
result[2] = a[1] * b[2] + a[2] * b[6] + a[3] * b[10] + a[4] * b[14]
|
||||||
|
result[3] = a[1] * b[3] + a[2] * b[7] + a[3] * b[11] + a[4] * b[15]
|
||||||
|
result[4] = a[1] * b[4] + a[2] * b[8] + a[3] * b[12] + a[4] * b[16]
|
||||||
|
result[5] = a[5] * b[1] + a[6] * b[5] + a[7] * b[9] + a[8] * b[13]
|
||||||
|
result[6] = a[5] * b[2] + a[6] * b[6] + a[7] * b[10] + a[8] * b[14]
|
||||||
|
result[7] = a[5] * b[3] + a[6] * b[7] + a[7] * b[11] + a[8] * b[15]
|
||||||
|
result[8] = a[5] * b[4] + a[6] * b[8] + a[7] * b[12] + a[8] * b[16]
|
||||||
|
result[9] = a[9] * b[1] + a[10] * b[5] + a[11] * b[9] + a[12] * b[13]
|
||||||
|
result[10] = a[9] * b[2] + a[10] * b[6] + a[11] * b[10] + a[12] * b[14]
|
||||||
|
result[11] = a[9] * b[3] + a[10] * b[7] + a[11] * b[11] + a[12] * b[15]
|
||||||
|
result[12] = a[9] * b[4] + a[10] * b[8] + a[11] * b[12] + a[12] * b[16]
|
||||||
|
result[13] = a[13] * b[1] + a[14] * b[5] + a[15] * b[9] + a[16] * b[13]
|
||||||
|
result[14] = a[13] * b[2] + a[14] * b[6] + a[15] * b[10] + a[16] * b[14]
|
||||||
|
result[15] = a[13] * b[3] + a[14] * b[7] + a[15] * b[11] + a[16] * b[15]
|
||||||
|
result[16] = a[13] * b[4] + a[14] * b[8] + a[15] * b[12] + a[16] * b[16]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultVec(result, a, v)
|
||||||
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4] * v[4]
|
||||||
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8] * v[4]
|
||||||
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12] * v[4]
|
||||||
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16] * v[4]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MatMultVec3(result, a, v)
|
||||||
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4]
|
||||||
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8]
|
||||||
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12]
|
||||||
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function LookAt(mat, campos, targetpos, upvec)
|
||||||
|
local forward = {}
|
||||||
|
local right = {}
|
||||||
|
local up = {}
|
||||||
|
|
||||||
|
VecSubVec3(forward, targetpos, campos)
|
||||||
|
Normalize(forward)
|
||||||
|
|
||||||
|
Cross(right, forward, upvec)
|
||||||
|
Normalize(right)
|
||||||
|
|
||||||
|
Cross(up, right, forward)
|
||||||
|
|
||||||
|
mat[1] = right[1]
|
||||||
|
mat[2] = right[2]
|
||||||
|
mat[3] = right[3]
|
||||||
|
mat[4] = -Dot(right, campos)
|
||||||
|
mat[5] = up[1]
|
||||||
|
mat[6] = up[2]
|
||||||
|
mat[7] = up[3]
|
||||||
|
mat[8] = -Dot(up, campos)
|
||||||
|
mat[9] = -forward[1]
|
||||||
|
mat[10] = -forward[2]
|
||||||
|
mat[11] = -forward[3]
|
||||||
|
mat[12] = Dot(forward, campos)
|
||||||
|
mat[13] = 0.0
|
||||||
|
mat[14] = 0.0
|
||||||
|
mat[15] = 0.0
|
||||||
|
mat[16] = 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Perspective(mat, fov, aspectratio, near, far)
|
||||||
|
local tanhalffovy
|
||||||
|
tanhalffovy = math.tan(fov * 0.5)
|
||||||
|
|
||||||
|
mat[1] = 1 / (aspectratio * tanhalffovy)
|
||||||
|
mat[2] = 0.0
|
||||||
|
mat[3] = 0.0
|
||||||
|
mat[4] = 0.0
|
||||||
|
mat[5] = 0.0
|
||||||
|
mat[6] = 1 / tanhalffovy
|
||||||
|
mat[7] = 0.0
|
||||||
|
mat[8] = 0.0
|
||||||
|
mat[9] = 0.0
|
||||||
|
mat[10] = 0.0
|
||||||
|
mat[11] = -(far + near) / (far - near)
|
||||||
|
mat[12] = -(2 * far * near) / (far - near)
|
||||||
|
mat[13] = 0.0
|
||||||
|
mat[14] = 0.0
|
||||||
|
mat[15] = -1.0
|
||||||
|
mat[16] = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function DrawTriangle(meta, colorbuffer, depthbuffer, wp0, wp1, wp2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
||||||
|
local p0 = {}
|
||||||
|
local p1 = {}
|
||||||
|
local p2 = {}
|
||||||
|
|
||||||
|
MatMultVec3(p0, mvp, wp0)
|
||||||
|
MatMultVec3(p1, mvp, wp1)
|
||||||
|
MatMultVec3(p2, mvp, wp2)
|
||||||
|
|
||||||
|
if p0[4] ~= 0.0 and p1[4] ~= 0.0 and p2[4] ~= 0.0 then
|
||||||
|
MapToRes(meta, p0)
|
||||||
|
MapToRes(meta, p1)
|
||||||
|
MapToRes(meta, p2)
|
||||||
|
|
||||||
|
local aabbmin = {}
|
||||||
|
local aabbmax = {}
|
||||||
|
|
||||||
|
aabbmin[1] = Max(Min3(p0[1], p1[1], p2[1]), 0)
|
||||||
|
aabbmin[2] = Max(Min3(p0[2], p1[2], p2[2]), 0)
|
||||||
|
aabbmax[1] = Min(Max3(p0[1], p1[1], p2[1]), meta[1] - 1)
|
||||||
|
aabbmax[2] = Min(Max3(p0[2], p1[2], p2[2]), meta[2] - 1)
|
||||||
|
|
||||||
|
local idx, tx, ty, ti
|
||||||
|
local p = {}
|
||||||
|
local depth
|
||||||
|
local w0, w1, w2, dot00, dot01, dot11, dot20, dot21, denom, d0, d1, d2
|
||||||
|
|
||||||
|
local v0 = {}
|
||||||
|
local v1 = {}
|
||||||
|
local v2 = {}
|
||||||
|
|
||||||
|
local texcoord = {}
|
||||||
|
|
||||||
|
local normal = {}
|
||||||
|
local diff
|
||||||
|
|
||||||
|
for x = math.floor(aabbmin[1]), math.floor(aabbmax[1]) do
|
||||||
|
for y = math.floor(aabbmin[2]), math.floor(aabbmax[2]) do
|
||||||
|
p[1] = x
|
||||||
|
p[2] = y
|
||||||
|
|
||||||
|
if IsOnRight(p0, p1, p) and IsOnRight(p1, p2, p) and IsOnRight(p2, p0, p) then
|
||||||
|
v0[1] = p1[1] - p0[1]
|
||||||
|
v0[2] = p1[2] - p0[2]
|
||||||
|
v1[1] = p2[1] - p0[1]
|
||||||
|
v1[2] = p2[2] - p0[2]
|
||||||
|
v2[1] = p[1] - p0[1]
|
||||||
|
v2[2] = p[2] - p0[2]
|
||||||
|
|
||||||
|
dot00 = Dot2(v0, v0)
|
||||||
|
dot01 = Dot2(v0, v1)
|
||||||
|
dot11 = Dot2(v1, v1)
|
||||||
|
dot20 = Dot2(v2, v0)
|
||||||
|
dot21 = Dot2(v2, v1)
|
||||||
|
|
||||||
|
denom = dot00 * dot11 - dot01 * dot01
|
||||||
|
w1 = (dot11 * dot20 - dot01 * dot21) / denom
|
||||||
|
w2 = (dot00 * dot21 - dot01 * dot20) / denom
|
||||||
|
w0 = 1.0 - w1 - w2
|
||||||
|
|
||||||
|
depth = p0[3] * w0 + p1[3] * w1 + p2[3] * w2
|
||||||
|
|
||||||
|
idx = math.floor(x) + meta[1] * math.floor(y)
|
||||||
|
|
||||||
|
if depth > 0.0 and depthbuffer[1 + idx] > depth then
|
||||||
|
depthbuffer[1 + idx] = depth
|
||||||
|
idx = idx * 3
|
||||||
|
|
||||||
|
texcoord[1] = w0 * c0[1] + w1 * c1[1] + w2 * c2[1]
|
||||||
|
texcoord[2] = w0 * c0[2] + w1 * c1[2] + w2 * c2[2]
|
||||||
|
|
||||||
|
normal[1] = w0 * n0[1] + w1 * n1[1] + w2 * n2[1]
|
||||||
|
normal[2] = w0 * n0[2] + w1 * n1[2] + w2 * n2[2]
|
||||||
|
normal[3] = w0 * n0[3] + w1 * n1[3] + w2 * n2[3]
|
||||||
|
|
||||||
|
Normalize(normal)
|
||||||
|
diff = Max(0.5, Dot(normal, lightdir))
|
||||||
|
|
||||||
|
tx = math.floor(texcoord[1] * meta[4])
|
||||||
|
ty = math.floor((1 - texcoord[2]) * meta[5])
|
||||||
|
ti = (tx + ty * meta[4]) * 3
|
||||||
|
|
||||||
|
|
||||||
|
-- uz ne kokote
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
colorbuffer[1 + idx] = texture[1 + ti] / 255 * diff
|
||||||
|
colorbuffer[1 + idx + 1] = texture[1 + ti + 1] / 255 * diff
|
||||||
|
colorbuffer[1 + idx + 2] = texture[1 + ti + 2] / 255 * diff
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OutputVT100(meta, colorbuffer)
|
||||||
|
print("\x1b[1;1H")
|
||||||
|
|
||||||
|
local r1, g1, b1, r2, b2, g2, width, height, idx, rowoffset
|
||||||
|
width = meta[1]
|
||||||
|
height = meta[2]
|
||||||
|
|
||||||
|
local out = {}
|
||||||
|
|
||||||
|
local pr1, pg1, pb1, pr2, pg2, pb2 = 0, 0, 0, 0, 0, 0
|
||||||
|
|
||||||
|
for y = 0, height - 2, 2 do
|
||||||
|
table.insert(out, "\n")
|
||||||
|
for x = 0, width - 1 do
|
||||||
|
idx = (x + y * width) * 3
|
||||||
|
rowoffset = width * 3
|
||||||
|
|
||||||
|
r1 = math.floor(colorbuffer[1 + idx] * 255)
|
||||||
|
g1 = math.floor(colorbuffer[1 + idx + 1] * 255)
|
||||||
|
b1 = math.floor(colorbuffer[1 + idx + 2] * 255)
|
||||||
|
|
||||||
|
r2 = math.floor(colorbuffer[1 + idx + rowoffset] * 255)
|
||||||
|
g2 = math.floor(colorbuffer[1 + idx + 1 + rowoffset] * 255)
|
||||||
|
b2 = math.floor(colorbuffer[1 + idx + 2 + rowoffset] * 255)
|
||||||
|
|
||||||
|
if r1 == pr1 and g1 == pg1 and b1 == pb1 and r2 == pr2 and g2 == pg2 and b2 == pb2 then
|
||||||
|
table.insert(out, "\xDF")
|
||||||
|
else
|
||||||
|
pr1, pg1, pb1, pr2, pg2, pb2 = r1, g1, b1, r2, g2, b2
|
||||||
|
table.insert(out, string.format("\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dm\xDF", r1, g1, b1, r2, g2, b2))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- io.write("\x1b[38;2;" ..
|
||||||
|
-- r1 .. ";" .. g1 .. ";" .. b1 .. "m" .. "\x1b[48;2;" .. r2 .. ";" .. g2 .. ";" .. b2 .. "m" .. "\xDF")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write(table.concat(out))
|
||||||
|
|
||||||
|
io.write(string.format("\n\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m%d FPS", fps))
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = io.open("data.txt", "r")
|
||||||
|
|
||||||
|
local function Input()
|
||||||
|
return file:read("*n")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- file:close() -- Close the file
|
||||||
|
|
||||||
|
-- return number
|
||||||
|
|
||||||
|
local function Main()
|
||||||
|
os.execute(" ")
|
||||||
|
|
||||||
|
local meta = {}
|
||||||
|
|
||||||
|
meta[1] = 175
|
||||||
|
meta[2] = 120
|
||||||
|
|
||||||
|
|
||||||
|
meta[3] = meta[1] * meta[2]
|
||||||
|
|
||||||
|
local depthbuffer = {}
|
||||||
|
local colorbuffer = {}
|
||||||
|
|
||||||
|
local background = {}
|
||||||
|
background[1] = 0.3
|
||||||
|
background[2] = 0.3
|
||||||
|
background[3] = 0.3
|
||||||
|
|
||||||
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
||||||
|
|
||||||
|
local lightdir = {}
|
||||||
|
lightdir[1] = .3
|
||||||
|
lightdir[2] = 1
|
||||||
|
lightdir[3] = .4
|
||||||
|
Normalize(lightdir)
|
||||||
|
|
||||||
|
local view = {}
|
||||||
|
local proj = {}
|
||||||
|
local mvp = {}
|
||||||
|
|
||||||
|
local campos = {}
|
||||||
|
local targetpos = {}
|
||||||
|
local upvector = {}
|
||||||
|
|
||||||
|
targetpos[1] = 0
|
||||||
|
targetpos[2] = 0
|
||||||
|
targetpos[3] = 0
|
||||||
|
|
||||||
|
upvector[1] = 0
|
||||||
|
upvector[2] = 1
|
||||||
|
upvector[3] = 0
|
||||||
|
local aspectratio
|
||||||
|
aspectratio = 1.46
|
||||||
|
|
||||||
|
|
||||||
|
Perspective(proj, DegToRad(90.0) / aspectratio, aspectratio, 0.1, 50.0)
|
||||||
|
|
||||||
|
local p0 = {}
|
||||||
|
local p1 = {}
|
||||||
|
local p2 = {}
|
||||||
|
|
||||||
|
local c0 = {}
|
||||||
|
local c1 = {}
|
||||||
|
local c2 = {}
|
||||||
|
|
||||||
|
local n0 = {}
|
||||||
|
local n1 = {}
|
||||||
|
local n2 = {}
|
||||||
|
|
||||||
|
local datasize, i, vertices
|
||||||
|
datasize = Input()
|
||||||
|
vertices = Input()
|
||||||
|
|
||||||
|
local data = {}
|
||||||
|
for i = 1, datasize do
|
||||||
|
data[i] = Input()
|
||||||
|
end
|
||||||
|
|
||||||
|
print("model rdy")
|
||||||
|
|
||||||
|
meta[4] = Input()
|
||||||
|
meta[5] = Input()
|
||||||
|
|
||||||
|
local tp
|
||||||
|
tp = meta[4] * meta[5] * 3
|
||||||
|
|
||||||
|
local texture = {}
|
||||||
|
|
||||||
|
for i = 0, tp - 1 do
|
||||||
|
texture[1 + i] = Input()
|
||||||
|
end
|
||||||
|
|
||||||
|
print("textura rdy")
|
||||||
|
|
||||||
|
local temp
|
||||||
|
|
||||||
|
local i0, i1, i2
|
||||||
|
|
||||||
|
local camangle
|
||||||
|
camangle = 0
|
||||||
|
|
||||||
|
local frames = 0
|
||||||
|
local lastframereset = 0
|
||||||
|
|
||||||
|
while true do
|
||||||
|
frames = frames + 1
|
||||||
|
|
||||||
|
local time = os.clock() * 1000
|
||||||
|
|
||||||
|
if time > lastframereset + 1000 then
|
||||||
|
fps = frames
|
||||||
|
frames = 0
|
||||||
|
lastframereset = time
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
||||||
|
|
||||||
|
local camdis
|
||||||
|
camdis = 7.0
|
||||||
|
|
||||||
|
campos[1] = math.sin(camangle) * camdis
|
||||||
|
campos[2] = 0.8 * camdis
|
||||||
|
campos[3] = math.cos(camangle) * camdis
|
||||||
|
|
||||||
|
|
||||||
|
camangle = camangle + math.pi / 50
|
||||||
|
|
||||||
|
LookAt(view, campos, targetpos, upvector)
|
||||||
|
MatMultMat(mvp, proj, view)
|
||||||
|
|
||||||
|
for i = 0, vertices - 3, 3 do
|
||||||
|
i0 = i * 8
|
||||||
|
i1 = (i + 1) * 8
|
||||||
|
i2 = (i + 2) * 8
|
||||||
|
|
||||||
|
p0[1] = data[1 + i0]
|
||||||
|
p0[2] = data[1 + i0 + 1]
|
||||||
|
p0[3] = data[1 + i0 + 2]
|
||||||
|
|
||||||
|
p1[1] = data[1 + i1]
|
||||||
|
p1[2] = data[1 + i1 + 1]
|
||||||
|
p1[3] = data[1 + i1 + 2]
|
||||||
|
|
||||||
|
p2[1] = data[1 + i2]
|
||||||
|
p2[2] = data[1 + i2 + 1]
|
||||||
|
p2[3] = data[1 + i2 + 2]
|
||||||
|
|
||||||
|
|
||||||
|
c0[1] = data[1 + i0 + 3]
|
||||||
|
c0[2] = data[1 + i0 + 4]
|
||||||
|
|
||||||
|
c1[1] = data[1 + i1 + 3]
|
||||||
|
c1[2] = data[1 + i1 + 4]
|
||||||
|
|
||||||
|
c2[1] = data[1 + i2 + 3]
|
||||||
|
c2[2] = data[1 + i2 + 4]
|
||||||
|
|
||||||
|
n0[1] = data[1 + i0 + 5]
|
||||||
|
n0[2] = data[1 + i0 + 6]
|
||||||
|
n0[3] = data[1 + i0 + 7]
|
||||||
|
|
||||||
|
n1[1] = data[1 + i1 + 5]
|
||||||
|
n1[2] = data[1 + i1 + 6]
|
||||||
|
n1[3] = data[1 + i1 + 7]
|
||||||
|
|
||||||
|
n2[1] = data[1 + i2 + 5]
|
||||||
|
n2[2] = data[1 + i2 + 6]
|
||||||
|
n2[3] = data[1 + i2 + 7]
|
||||||
|
|
||||||
|
DrawTriangle(meta, colorbuffer, depthbuffer, p0, p1, p2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
OutputVT100(meta, colorbuffer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Main()
|
||||||
BIN
res/screen-dosbox.png
Normal file
BIN
res/screen-dosbox.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Loading…
x
Reference in New Issue
Block a user