123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- * 3D Engine
- * main.c:
- * Based on pikuma.com 3D software renderer in C
- * Copyright (c) 2021 986-Studio. All rights reserved.
- *
- * Created by Manoël Trapier on 01/03/2021.
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <SDL.h>
- #include <log.h>
- #include <display.h>
- #include <vector.h>
- bool isRunning = true;
- int previousFrameTime = 0;
- #define N_POINTS (9*9*9)
- vec3_t cubePoints[N_POINTS];
- vec2_t projectedPoints[N_POINTS];
- vec3_t cameraPosition =
- {
- .x = 0,
- .y = 0,
- .z = -5,
- };
- vec3_t cubeRotation =
- {
- .x = 0,
- .y = 0,
- .z = 0,
- };
- double fovFactor = 820 ;
- void setup()
- {
- frameBuffer = (uint32_t *)calloc(windowWidth * windowHeight, sizeof(uint32_t));
- if (!frameBuffer)
- {
- log(TLOG_PANIC, NULL, "Memory allocation error.");
- goto exit;
- }
- frameBufferTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, windowWidth,
- windowHeight);
- if (frameBufferTexture == NULL)
- {
- log(TLOG_PANIC, NULL, "SDL Texture creation error: %s", SDL_GetError());
- goto exit;
- }
- int pointCount = 0;
- for(double x = -1; x <= 1 ; x += 0.25)
- {
- for(double y = -1; y <= 1 ; y += 0.25)
- {
- for(double z = -1; z <= 1 ; z += 0.25)
- {
- vec3_t new_point = { x, y, z };
- cubePoints[pointCount++] = new_point;
- }
- }
- }
- exit:
- return;
- }
- void processInput()
- {
- SDL_Event event;
- SDL_PollEvent(&event);
- switch (event.type)
- {
- case SDL_QUIT:isRunning = false;
- break;
- case SDL_KEYDOWN:
- if (event.key.keysym.sym == SDLK_ESCAPE)
- {
- isRunning = false;
- }
- break;
- default:
- break;
- }
- }
- vec2_t orthographicPointProjection(vec3_t point)
- {
- vec2_t ret;
- ret.x = point.x * fovFactor + (windowWidth / 2.);
- ret.y = point.y * fovFactor + (windowHeight / 2.);
- return ret;
- }
- vec2_t perspectivePointProjection(vec3_t point)
- {
- vec2_t ret;
- ret.x = (point.x/point.z) * (fovFactor/2.) + (windowWidth / 2.);
- ret.y = (point.y/point.z) * (fovFactor/2.) + (windowHeight / 2.);
- return ret;
- }
- void update()
- {
- int i;
- while(!SDL_TICKS_PASSED(SDL_GetTicks(), previousFrameTime + FRAME_TARGET_TIME));
- previousFrameTime = SDL_GetTicks();
- cubeRotation.x += 0.01;
- cubeRotation.y += 0.01;
- cubeRotation.z += 0.01;
- for(i = 0; i < N_POINTS; i++)
- {
- vec3_t point = cubePoints[i];
- point = vec3RotateX(point, cubeRotation.x);
- point = vec3RotateY(point, cubeRotation.y);
- point = vec3RotateZ(point, cubeRotation.z);
- point.z -= cameraPosition.z;
- projectedPoints[i] = perspectivePointProjection(point);
- }
- }
- void render()
- {
- int i;
- SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
- SDL_RenderClear(renderer);
- for(i = 0; i < N_POINTS; i++)
- {
- vec2_t projPoint = projectedPoints[i];
- drawRectangle(projPoint.x, projPoint.y, 4, 4, 0xFFFFFF00);
- }
- renderFrameBuffer();
- clearFrameBuffer(0xFF000000);
- SDL_RenderPresent(renderer);
- }
- int main(int argc, char *argv[])
- {
- int param_i;
- bool fullScreen = false;
- MAX_DEBUG_LEVEL = TLOG_DEBUG;
- log(TLOG_ALWAYS, NULL, "Booting 3D Engine (version %s)!", VERSION);
- for (param_i = 1 ; (param_i < argc) && (argv[param_i][0] == '-') ; param_i++)
- {
- switch (argv[param_i][1])
- {
- default: exit(-1); /* Option not recognized */
- case 'f': fullScreen = true; break;
- case 'w': windowWidth = atoi(argv[++param_i]);
- case 'h': windowHeight = atoi(argv[++param_i]); break;
- #ifdef DYNA_LOG_LEVEL
- case 'l': MAX_DEBUG_LEVEL = atoi(argv[++param_i]); break;
- #endif
- case '-': goto no_more_params; /* Could use break, but this is more clear */
- }
- }
- no_more_params:
- isRunning = initialiseWindow(fullScreen);
- setup();
- while (isRunning)
- {
- processInput();
- update();
- render();
- }
- destroy_window();
- return 0;
- }
|