diff --git a/include/globals.hpp b/include/globals.hpp index 484f08e..301b30f 100644 --- a/include/globals.hpp +++ b/include/globals.hpp @@ -1,8 +1,8 @@ #ifndef DELTA_GLOBALS #define DELTA_GLOBALS -const int SIMULATED_WIDTH = 1200; -const int SIMULATED_HEIGHT = 800; +const int SIMULATED_WIDTH = 1920; +const int SIMULATED_HEIGHT = 1000; const int FOCAL = 300; #endif \ No newline at end of file diff --git a/include/math.hpp b/include/math.hpp index 70f6d7c..93c9407 100644 --- a/include/math.hpp +++ b/include/math.hpp @@ -36,6 +36,7 @@ class DeltaVector3 { float dotProduct(const DeltaVector3 &vec) const; float angleTo(const DeltaVector3 &vec) const; float length() const; + DeltaVector3 crossProduct(const DeltaVector3 &vec) const; }; @@ -59,6 +60,7 @@ struct DeltaModelConnector { struct DeltaRenderTriangle { DeltaVertex a, b, c; std::string texID; + DeltaVector3 normal; }; struct DeltaModel { diff --git a/include/renderer/calls.hpp b/include/renderer/calls.hpp index 8ec9d42..ac45444 100644 --- a/include/renderer/calls.hpp +++ b/include/renderer/calls.hpp @@ -8,7 +8,7 @@ // void rasterizeTriangle(SDL_Renderer *renderer, const DeltaVector2 &a, const DeltaVector2 &b, const DeltaVector2 &c); void rasterizeTriangleFast(SDL_Surface* surface, const DeltaVector2& v0, const DeltaVector2& v1, const DeltaVector2& v2, uint32_t color); -void rasterizeTriangleSurface(DeltaAssetLoader& assets, std::vector& depthbuffer, SDL_Surface* surface, const DeltaVector3& v0, const DeltaVector3& v1, const DeltaVector3& v2, const std::string& textureID, float u0, float v0_uv, float u1, float v1_uv, float u2, float v2_uv); +void rasterizeTriangleSurface(DeltaAssetLoader& assets, std::vector& depthbuffer, SDL_Surface* surface, const DeltaVector3& v0, const DeltaVector3& v1, const DeltaVector3& v2, const std::string& textureID, float u0, float v0_uv, float u1, float v1_uv, float u2, float v2_uv, float shade); void setPixel(SDL_Surface* surface, int x, int y, uint32_t color); uint32_t getPixel(SDL_Surface* surface, int x, int y); #endif \ No newline at end of file diff --git a/make-release.sh b/make-release.sh new file mode 100644 index 0000000..882e27e --- /dev/null +++ b/make-release.sh @@ -0,0 +1,7 @@ +clang++ -c src/*.cpp -O3 -ffast-math -I/opt/homebrew/include -Iinclude/ +clang++ -c src/**/*.cpp -O3 -ffast-math -I/opt/homebrew/include -Iinclude/ +clang++ *.o -L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib -lSDL3 -o out/release.bin +rm ./*.o +cd out +./release.bin +cd .. \ No newline at end of file diff --git a/make.sh b/make.sh index b1c0c88..3ef8279 100644 --- a/make.sh +++ b/make.sh @@ -2,4 +2,6 @@ clang++ -c src/*.cpp -I/opt/homebrew/include -Iinclude/ clang++ -c src/**/*.cpp -I/opt/homebrew/include -Iinclude/ clang++ *.o -L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib -lSDL3 -o out/debug.bin rm ./*.o -./out/debug.bin \ No newline at end of file +cd ./out +./debug.bin +cd .. \ No newline at end of file diff --git a/src/assetloader.cpp b/src/assetloader.cpp index 6e2e22b..869bfdd 100644 --- a/src/assetloader.cpp +++ b/src/assetloader.cpp @@ -7,7 +7,7 @@ #include "assetloader.hpp" void DeltaAssetLoader::loadTexture(std::string id, const char* path) { - std::string fullPath = base_path + "\\" + img_path + "\\" + path; + std::string fullPath = base_path + "/" + img_path + "/" + path; SDL_Surface* surface = SDL_LoadPNG(fullPath.c_str()); if (!surface) { SDL_Log(SDL_GetError()); diff --git a/src/main.cpp b/src/main.cpp index a8c86d9..e0b7263 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,6 +76,9 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) triangles.push_back({ {{410, 410, 200}, {2, 2}}, {{10, 410, 200}, {0, 2}}, {{10, 10, 200}, {0, 0}} , "stone"}); triangles.push_back({ {{410, 10, 200}, {2, 0}}, {{410, 410, 200}, {2, 2}}, {{10, 10, 200}, {0, 0}} , "stone"}); + // after this point, no modifying triangles! (without recalculation of normals) + + backbuffer = SDL_CreateSurface(SIMULATED_WIDTH, SIMULATED_HEIGHT, SDL_PIXELFORMAT_ARGB8888); depthbuffer.resize(SIMULATED_WIDTH * SIMULATED_HEIGHT); @@ -140,21 +143,41 @@ SDL_AppResult SDL_AppIterate(void *appstate) DeltaTriangle out1, out2; DeltaTriangle2D uv1, uv2; + DeltaVector3 edge1 = triangle.b.pos - triangle.a.pos; + DeltaVector3 edge2 = triangle.c.pos - triangle.a.pos; + DeltaVector3 normal = edge1.crossProduct(edge2); + normal = normal * (1.0f / normal.length()); + + float shade = 1.0f; + float nx = std::abs(normal.x); + float ny = std::abs(normal.y); + float nz = std::abs(normal.z); + + // out1.a = player.camera.projectPointVec(out1.a); + // out1.b = player.camera.projectPointVec(out1.b); + // out1.c = player.camera.projectPointVec(out1.c); + + SDL_Log(std::to_string(0.5f + normal.dotProduct({0.3f, 1.0f, 0.3f}) / 2).c_str()); + + shade = std::max(0.1f, 0.9f + normal.dotProduct({0.35f, 0.88f, 0.35f}) / 4); + int numtriangles = player.camera.projectTriangle(triangle, out1, out2, uv1, uv2); // SDL_Log(std::to_string(numtriangles).c_str()); if (numtriangles == 1) { + // SDL_Log(std::to_string(shade).c_str()); + // rasterizeTriangleFast(backbuffer, out1.a, out1.b, out1.c, SDLColorToUint32({ 255, 0, 0, 255 })); // rasterizeTriangleFast(backbuffer, out1.a, out1.b, out1.c, SDLColorToUint32({ 0, 0, 255, 255 })); - rasterizeTriangleSurface(assets, depthbuffer, backbuffer, out1.a, out1.b, out1.c, triangle.texID, uv1.a.x, uv1.a.y, uv1.b.x, uv1.b.y, uv1.c.x, uv1.c.y); + rasterizeTriangleSurface(assets, depthbuffer, backbuffer, out1.a, out1.b, out1.c, triangle.texID, uv1.a.x, uv1.a.y, uv1.b.x, uv1.b.y, uv1.c.x, uv1.c.y, shade); // SDL_Log(std::to_string(triangle.a.y).c_str()); // SDL_Log(std::to_string(triangle.b.y).c_str()); // SDL_Log(std::to_string(triangle.c.y).c_str()); } if (numtriangles == 2) { // rasterizeTriangleFast(backbuffer, out1.a, out1.b, out1.c, SDLColorToUint32({ 255, 0, 0, 255 })); - rasterizeTriangleSurface(assets, depthbuffer, backbuffer, out1.a, out1.b, out1.c, triangle.texID, uv1.a.x, uv1.a.y, uv1.b.x, uv1.b.y, uv1.c.x, uv1.c.y); + rasterizeTriangleSurface(assets, depthbuffer, backbuffer, out1.a, out1.b, out1.c, triangle.texID, uv1.a.x, uv1.a.y, uv1.b.x, uv1.b.y, uv1.c.x, uv1.c.y, shade); // rasterizeTriangleFast(backbuffer, out1.c, out1.b, out1.a, SDLColorToUint32({ 0, 255, 0, 255 })); - rasterizeTriangleSurface(assets, depthbuffer, backbuffer, out2.a, out2.b, out2.c, triangle.texID, uv2.a.x, uv2.a.y, uv2.b.x, uv2.b.y, uv2.c.x, uv2.c.y); + rasterizeTriangleSurface(assets, depthbuffer, backbuffer, out2.a, out2.b, out2.c, triangle.texID, uv2.a.x, uv2.a.y, uv2.b.x, uv2.b.y, uv2.c.x, uv2.c.y, shade); } // int intersected = clipTriangleAgainstNearPlane(0.1, { triangle.a, triangle.b, triangle.c }, triangle1, triangle2); diff --git a/src/math.cpp b/src/math.cpp index ca3b4fd..c1969c7 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -106,6 +106,10 @@ float DeltaVector3::angleTo(const DeltaVector3 &vec) const { return std::acos(dotProduct(vec)) / (length() * vec.length()); } +DeltaVector3 DeltaVector3::crossProduct(const DeltaVector3 &vec) const { + return {y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x}; +} + float getDeterminant(const DeltaVector2 &pointA, const DeltaVector2 &pointB, const DeltaVector2 &candidate) { DeltaVector2 ab = pointB - pointA; DeltaVector2 ac = candidate - pointA; diff --git a/src/player.cpp b/src/player.cpp index 19488ec..93d5684 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -14,7 +14,7 @@ void Player::update(float deltaTime) { DeltaVector2 angleChange; angleChange.x = (float)(key_states[SDL_SCANCODE_RIGHT] - key_states[SDL_SCANCODE_LEFT]); - angleChange.y = (float)(key_states[SDL_SCANCODE_UP] - key_states[SDL_SCANCODE_DOWN]); + angleChange.y = -(float)(key_states[SDL_SCANCODE_UP] - key_states[SDL_SCANCODE_DOWN]); float dx = std::sin(angle.x), dy = std::cos(angle.x); @@ -38,8 +38,8 @@ void Player::update(float deltaTime) { // SDL_Log(std::to_string(pos.z).c_str()); // SDL_Log("==="); - angle.x += angleChange.x * 3.14 * deltaTime; - angle.y += angleChange.y * 3.14 * deltaTime; + angle.x += angleChange.x * 3.14 / 2 * deltaTime; + angle.y += angleChange.y * 3.14 / 2 * deltaTime; pos += velocity * deltaTime; diff --git a/src/renderer/calls.cpp b/src/renderer/calls.cpp index dbc666f..9dfadfe 100644 --- a/src/renderer/calls.cpp +++ b/src/renderer/calls.cpp @@ -1,6 +1,6 @@ #include #include -#include +// #include #include #include "globals.hpp" @@ -28,7 +28,7 @@ uint32_t getPixel(SDL_Surface* surface, int x, int y) { return pixels[y * pitchInWords + x]; } -void rasterizeTriangleSurface(DeltaAssetLoader& assets, std::vector& depthbuffer, SDL_Surface* surface, const DeltaVector3& v0, const DeltaVector3& v1, const DeltaVector3& v2, const std::string& textureID, float u0, float v0_uv, float u1, float v1_uv, float u2, float v2_uv) { +void rasterizeTriangleSurface(DeltaAssetLoader& assets, std::vector& depthbuffer, SDL_Surface* surface, const DeltaVector3& v0, const DeltaVector3& v1, const DeltaVector3& v2, const std::string& textureID, float u0, float v0_uv, float u1, float v1_uv, float u2, float v2_uv, float shade) { int minX = std::max(0, (int)std::min({v0.x, v1.x, v2.x})); int maxX = std::min((int)surface->w - 1, (int)std::max({v0.x, v1.x, v2.x})); int minY = std::max(0, (int)std::min({v0.y, v1.y, v2.y})); @@ -110,7 +110,17 @@ void rasterizeTriangleSurface(DeltaAssetLoader& assets, std::vector& dept // rowPtr[x] = SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, (uint8_t)(u * 255), (uint8_t)(v * 255), 0); //getPixel(textureOrigin, (int)(u * textureOrigin->w), (int)(v * textureOrigin->h)); // rowPtr[x] = getPixel(textureOrigin, (int)(u * textureOrigin->w) % textureOrigin->w, (int)(v * textureOrigin->h) % textureOrigin->h); // (int)(u * textureOrigin->w) & (textureOrigin->w - 1) - rowPtr[x] = texpixels[ty * pitchInWords + tx]; + + uint32_t texColor = texpixels[ty * pitchInWords + tx]; + + float finalBrightness = shade; + + uint8_t r = (uint8_t)std::max(0.0f, std::min(255.0f, (uint8_t)(texColor >> 16) * finalBrightness)); + uint8_t g = (uint8_t)std::max(0.0f, std::min(255.0f, (uint8_t)(texColor >> 8) * finalBrightness)); + uint8_t b = (uint8_t)std::max(0.0f, std::min(255.0f, (uint8_t)(texColor) * finalBrightness)); + + rowPtr[x] = (r << 16) | (g << 8) | b | 0xFF000000; + // rowPtr[x] = r << 16 | 0xFF000000; } } @@ -128,55 +138,55 @@ void rasterizeTriangleSurface(DeltaAssetLoader& assets, std::vector& dept } } -void rasterizeTriangleFast(SDL_Surface* surface, const DeltaVector2& v0, const DeltaVector2& v1, const DeltaVector2& v2, uint32_t color) { - int minX = std::max(0, (int)std::min({v0.x, v1.x, v2.x})); - int maxX = std::min((int)surface->w - 1, (int)std::max({v0.x, v1.x, v2.x})); - int minY = std::max(0, (int)std::min({v0.y, v1.y, v2.y})); - int maxY = std::min((int)surface->h - 1, (int)std::max({v0.y, v1.y, v2.y})); +// void rasterizeTriangleFast(SDL_Surface* surface, const DeltaVector2& v0, const DeltaVector2& v1, const DeltaVector2& v2, uint32_t color) { +// int minX = std::max(0, (int)std::min({v0.x, v1.x, v2.x})); +// int maxX = std::min((int)surface->w - 1, (int)std::max({v0.x, v1.x, v2.x})); +// int minY = std::max(0, (int)std::min({v0.y, v1.y, v2.y})); +// int maxY = std::min((int)surface->h - 1, (int)std::max({v0.y, v1.y, v2.y})); - float a0 = v1.y - v2.y, b0 = v2.x - v1.x, c0 = v1.x * v2.y - v2.x * v1.y; - float a1 = v2.y - v0.y, b1 = v0.x - v2.x, c1 = v2.x * v0.y - v0.x * v2.y; - float a2 = v0.y - v1.y, b2 = v1.x - v0.x, c2 = v0.x * v1.y - v1.x * v0.y; +// float a0 = v1.y - v2.y, b0 = v2.x - v1.x, c0 = v1.x * v2.y - v2.x * v1.y; +// float a1 = v2.y - v0.y, b1 = v0.x - v2.x, c1 = v2.x * v0.y - v0.x * v2.y; +// float a2 = v0.y - v1.y, b2 = v1.x - v0.x, c2 = v0.x * v1.y - v1.x * v0.y; - __m128 a0_4 = _mm_set1_ps(a0), a1_4 = _mm_set1_ps(a1), a2_4 = _mm_set1_ps(a2); - __m128 stepX = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); +// __m128 a0_4 = _mm_set1_ps(a0), a1_4 = _mm_set1_ps(a1), a2_4 = _mm_set1_ps(a2); +// __m128 stepX = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); - uint32_t* pixels = (uint32_t*)surface->pixels; - int pitch = surface->pitch / sizeof(uint32_t); +// uint32_t* pixels = (uint32_t*)surface->pixels; +// int pitch = surface->pitch / sizeof(uint32_t); - for (int y = minY; y <= maxY; y++) { - float fy = (float)y; - uint32_t* rowPtr = &pixels[y * pitch]; +// for (int y = minY; y <= maxY; y++) { +// float fy = (float)y; +// uint32_t* rowPtr = &pixels[y * pitch]; - __m128 e0 = _mm_add_ps(_mm_set1_ps(a0 * minX + b0 * fy + c0), _mm_mul_ps(a0_4, stepX)); - __m128 e1 = _mm_add_ps(_mm_set1_ps(a1 * minX + b1 * fy + c1), _mm_mul_ps(a1_4, stepX)); - __m128 e2 = _mm_add_ps(_mm_set1_ps(a2 * minX + b2 * fy + c2), _mm_mul_ps(a2_4, stepX)); +// __m128 e0 = _mm_add_ps(_mm_set1_ps(a0 * minX + b0 * fy + c0), _mm_mul_ps(a0_4, stepX)); +// __m128 e1 = _mm_add_ps(_mm_set1_ps(a1 * minX + b1 * fy + c1), _mm_mul_ps(a1_4, stepX)); +// __m128 e2 = _mm_add_ps(_mm_set1_ps(a2 * minX + b2 * fy + c2), _mm_mul_ps(a2_4, stepX)); - __m128 e0_step = _mm_set1_ps(a0 * 4.0f); - __m128 e1_step = _mm_set1_ps(a1 * 4.0f); - __m128 e2_step = _mm_set1_ps(a2 * 4.0f); +// __m128 e0_step = _mm_set1_ps(a0 * 4.0f); +// __m128 e1_step = _mm_set1_ps(a1 * 4.0f); +// __m128 e2_step = _mm_set1_ps(a2 * 4.0f); - for (int x = minX; x <= maxX; x += 4) { - __m128 mask = _mm_and_ps(_mm_cmpge_ps(e0, _mm_setzero_ps()), - _mm_and_ps(_mm_cmpge_ps(e1, _mm_setzero_ps()), - _mm_cmpge_ps(e2, _mm_setzero_ps()))); +// for (int x = minX; x <= maxX; x += 4) { +// __m128 mask = _mm_and_ps(_mm_cmpge_ps(e0, _mm_setzero_ps()), +// _mm_and_ps(_mm_cmpge_ps(e1, _mm_setzero_ps()), +// _mm_cmpge_ps(e2, _mm_setzero_ps()))); - int bitmask = _mm_movemask_ps(mask); +// int bitmask = _mm_movemask_ps(mask); - if (bitmask != 0) { - if (bitmask == 0xF && (x + 3 <= maxX)) { - _mm_storeu_si128((__m128i*)&rowPtr[x], _mm_set1_epi32(color)); - } else { - for (int i = 0; i < 4; i++) { - if ((bitmask >> i) & 1 && (x + i <= maxX)) { - rowPtr[x + i] = color; - } - } - } - } - e0 = _mm_add_ps(e0, e0_step); - e1 = _mm_add_ps(e1, e1_step); - e2 = _mm_add_ps(e2, e2_step); - } - } -} \ No newline at end of file +// if (bitmask != 0) { +// if (bitmask == 0xF && (x + 3 <= maxX)) { +// _mm_storeu_si128((__m128i*)&rowPtr[x], _mm_set1_epi32(color)); +// } else { +// for (int i = 0; i < 4; i++) { +// if ((bitmask >> i) & 1 && (x + i <= maxX)) { +// rowPtr[x + i] = color; +// } +// } +// } +// } +// e0 = _mm_add_ps(e0, e0_step); +// e1 = _mm_add_ps(e1, e1_step); +// e2 = _mm_add_ps(e2, e2_step); +// } +// } +// } \ No newline at end of file