Files
SoftwareRenderer/main.cpp
2026-04-03 12:34:06 +02:00

151 lines
4.9 KiB
C++

#include "MainWindow.hpp"
#include "fastmath.hpp"
#include "plane.hpp"
#include "polygon.hpp"
#include "renderer.hpp"
#include "rendertarget.hpp"
#include "testModel.hpp"
#include <QApplication>
#include <chrono>
#include <functional>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define HIGHT 64
#define WIDTH 64
#define FAA_FAC 2
#define RHIGHT ((int)(HIGHT * FAA_FAC))
#define RWIDTH ((int)(WIDTH * FAA_FAC))
char *drawToString(unsigned short *img) {
char *textImg = (char *)malloc(200000 * sizeof(char));
// strcat(textImg,"\e[1;1H\e[2J"); --clear
for (int y = 0; y < HIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
// printf("%d,%d\n",x,y);
char buff[20];
unsigned short val = 0;
int my = y * FAA_FAC;
int mx = x * FAA_FAC;
val += img[my * RWIDTH + mx];
val += img[my * RWIDTH + mx + 1];
val += img[(my + 1) * RWIDTH + mx];
val += img[(my + 1) * RWIDTH + mx + 1];
sprintf(buff, "\033[38;5;%dm██\033[0m", 232 + val / 4);
strcat(textImg, buff);
}
strcat(textImg, "\n");
}
return textImg;
}
int main(int argc, char *argv[]) {
Rendertarget target(128, 128);
Renderer renderer;
renderer.target = &target;
std::chrono::steady_clock::time_point begin =
std::chrono::steady_clock::now();
renderer.render(&testModel, mat4::translation(vec3(0.0f, -1.0f, 5.0f)) *
mat4::rotateOnY(-1.5707963267948966f));
std::chrono::steady_clock::time_point end =
std::chrono::steady_clock::now();
std::cout << "Time difference = "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end -
begin)
.count()
<< "[ms]" << std::endl;
uint8_t *pixel = new uint8_t[64 * 64 * 3];
/*for (int i = 0; i < 64 * 64 * 3; i++) {
pixel[i] = target.pixels[i].i >> SHIFT_AMOUNT;
}*/
std::function<void(int, uint32_t *)> addTo = [&target](int start,
uint32_t *arr) {
for (int c = 0; c < 3; c++) {
arr[c] += target.pixels[start + c];
}
};
vec3 pos;
QApplication a(argc, argv);
MainWindow widget;
widget.setWindowTitle("SoftwareRenderer");
// display.setPixmap(QPixmap::fromImage(img).scaled(widget.size()));
auto keyEvent = [&pos](QKeyEvent *e) {
decimal step = decimal(0.5);
switch (e->key()) {
case Qt::Key_W:
pos.z() += step;
break;
case Qt::Key_S:
pos.z() -= step;
break;
case Qt::Key_A:
pos.x() += step;
break;
case Qt::Key_D:
pos.x() -= step;
break;
}
};
widget.keyDownCallBack = keyEvent;
float rot = 0.f;
std::function<void()> renderLoop = [&addTo, &target, &pixel, &renderer,
&widget, &rot, &pos]() {
std::chrono::steady_clock::time_point begin =
std::chrono::steady_clock::now();
target.clearDepth();
target.clearTarget();
// renderer.render(&testModel, mat4::translation(vec3(0.0f,
// -1.0f, 5.0f)) *
// mat4::rotateOnY(rot));
// renderer.render(&testModel, mat4::translation(vec3(1.0f,
// -1.0f, 7.0f)) *
// mat4::rotateOnY(rot));
renderer.render(&plane, mat4::translation(pos));
std::chrono::steady_clock::time_point end =
std::chrono::steady_clock::now();
std::cout << "Time difference = "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
end - begin)
.count()
<< "[ms]" << std::endl;
for (int x = 0; x < 64; x++) {
for (int y = 0; y < 64; y++) {
uint32_t result[3] = {};
addTo((target.width * y * 2 + x * 2) * 3, result);
addTo((target.width * (y * 2 + 1) + x * 2) * 3, result);
addTo((target.width * y * 2 + (x * 2 + 1)) * 3, result);
addTo((target.width * (y * 2 + 1) + (x * 2 + 1)) * 3, result);
for (int c = 0; c < 3; c++) {
pixel[(WIDTH * (WIDTH - y - 1) + WIDTH - x - 1) * 3 + c] =
result[c] >> 2;
}
}
}
// QImage img((unsigned char *)pixel, 64, 64, QImage::Format_RGB888);
widget.updateLabel(pixel);
rot += 0.1f;
};
renderLoop();
widget.show();
QTimer timer;
timer.setInterval(20);
timer.start();
QObject::connect(&timer, &QTimer::timeout, &widget, renderLoop);
return a.exec();
}