Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <SDL2/SDL.h>
- #include <stdbool.h>
- #include "map.h"
- #include <math.h>
- #define USE_REFLECTIONS 1
- #define RESX 800
- #define RESY 600
- #define HALFRESX (RESX/2.0)
- #define HALFRESY (RESY/2.0)
- #define MOVESPEED 0.008
- #define STRAFEMOVESPEED 0.00565685424948
- #define ROTATESPEED 0.002
- #define MAXLIGHTS 4
- #define MAPSIZE 32
- struct Point3D {
- float x, y, z;
- };
- struct pos {
- int x, y, z;
- };
- void randGenMap(int level) {
- for(int x = 1; x < 31; x++) {
- for(int y = 1; y < 31; y++) {
- char material = rand()%20;
- if(material!=2 && material < 6) {
- MAP[x][level][y] = material;
- }
- else MAP[x][level][y] = 0;
- }
- }
- }
- void main() {
- char placeDist = 5;
- SDL_Window* window = NULL; //init SDL
- SDL_Renderer* renderer = NULL;
- bool running = true;
- if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
- printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
- running = false;
- }
- window = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, RESX, RESY, SDL_WINDOW_SHOWN );
- if( window==NULL) {
- printf( "SDL_Error: %s\n", SDL_GetError() );
- running = false;
- }
- renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
- if(renderer==NULL) {
- printf("Renderer error: %s\n", SDL_GetError() );
- running = false;
- }
- SDL_Texture * texture = SDL_CreateTexture(renderer,
- SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, RESX,RESY);
- auto Uint32 pixels[RESY][RESX];
- const Uint8* keystate = SDL_GetKeyboardState( NULL );
- int t1, t2;
- struct Point3D pos;
- pos.x = 16;
- pos.y = 16;
- pos.z = 16;
- struct Point3D dir;
- dir.x = 0;
- dir.y = -1; //direction vector
- dir.z = 0;
- struct Point3D plane;
- plane.x = 1.0;
- plane.y = 0;
- plane.z = 0.75;
- float planeConstant = sqrtf(plane.x*plane.x+plane.y*plane.y+plane.z*plane.z);
- char light[MAXLIGHTS][3];
- light[0][0] = 4;
- light[0][1] = 4;
- light[0][2] = 4;
- unsigned char voxelColour;
- void rotatez(float rotspeed) {
- float oldDirX = dir.x;
- dir.x = dir.x * cos(rotspeed) - dir.y * sin(rotspeed);
- dir.y = oldDirX * sin(rotspeed) + dir.y * cos(rotspeed);
- oldDirX = plane.x;
- plane.x = plane.x * cos(rotspeed) - plane.y * sin(rotspeed);
- plane.y = oldDirX * sin(rotspeed) + plane.y * cos(rotspeed);
- }
- void rotatey(float rotspeed) {
- //How?
- return; // placeholder
- }
- void move(int ms) {
- float velocity = ((keystate[SDL_SCANCODE_D] ^ keystate[SDL_SCANCODE_A]) &&
- (keystate[SDL_SCANCODE_W] ^ keystate[SDL_SCANCODE_S])) ? STRAFEMOVESPEED*ms : MOVESPEED*ms;
- struct Point3D oldpos = pos;
- if(keystate[SDL_SCANCODE_D]) {
- pos.x -= dir.y * velocity;
- pos.y += dir.x * velocity;
- }
- if(keystate[SDL_SCANCODE_A]) {
- pos.x += dir.y * velocity;
- pos.y -= dir.x * velocity;
- }
- if(keystate[SDL_SCANCODE_W]) {
- pos.x += dir.x * velocity;
- pos.y += dir.y * velocity;
- }
- if(keystate[SDL_SCANCODE_S]) {
- pos.x -= dir.x * velocity;
- pos.y -= dir.y * velocity;
- }
- if(keystate[SDL_SCANCODE_E]) {
- pos.z -= STRAFEMOVESPEED*ms;
- }
- if(keystate[SDL_SCANCODE_Q]) {
- pos.z += STRAFEMOVESPEED*ms;
- }
- if(MAP[(char)pos.x][(char)pos.y][(char)pos.z]) pos = oldpos;
- } //remove oldpos and velocity when not needed
- int ms = 5;
- int a = 0;
- while( running ) {
- t1 = SDL_GetTicks();
- SDL_Event e;
- running = !(SDL_PollEvent( &e ) && e.type == SDL_QUIT);
- move(ms);
- if(keystate[SDL_SCANCODE_LEFT]) {
- rotatez(-ROTATESPEED*ms);
- }
- if(keystate[SDL_SCANCODE_RIGHT]){
- rotatez(ROTATESPEED*ms);
- }
- if(keystate[SDL_SCANCODE_UP]) {
- rotatey(ROTATESPEED*ms);
- }
- if(keystate[SDL_SCANCODE_DOWN]){
- rotatey(-ROTATESPEED*ms);
- }
- char blockMat;
- if(keystate[SDL_SCANCODE_1]) blockMat = 1;
- else if(keystate[SDL_SCANCODE_2]) blockMat = 3;
- else if(keystate[SDL_SCANCODE_3]) blockMat = 4;
- else if(keystate[SDL_SCANCODE_4]) blockMat = 5;
- #ifdef USE_REFLECTIONS
- else if(keystate[SDL_SCANCODE_5]) blockMat = 6;
- #endif
- if(keystate[SDL_SCANCODE_SPACE] && !MAP[(char)(pos.x+dir.x*placeDist)][(char)(pos.y+dir.y*placeDist)][(char)pos.z]) {
- MAP[(char)(pos.x+dir.x*placeDist)][(char)(pos.y+dir.y*placeDist)][(char)pos.z] = blockMat;
- }
- else if(keystate[SDL_SCANCODE_LCTRL] && MAP[(char)(pos.x+dir.x*placeDist)][(char)(pos.y+dir.y*placeDist)][(char)pos.z] != 2) {
- MAP[(char)(pos.x+dir.x*placeDist)][(char)(pos.y+dir.y*placeDist)][(char)pos.z] = 0;
- }
- else if(keystate[SDL_SCANCODE_LSHIFT] && !MAP[(char)(pos.x+dir.x*placeDist)][(char)(pos.y+dir.y*placeDist)][(char)pos.z]) {
- light[0][0] = (char)(pos.x+dir.x*placeDist);
- light[0][1] = (char)(pos.y+dir.y*placeDist);
- light[0][2] = (char) pos.z;
- }
- else if(keystate[SDL_SCANCODE_ESCAPE]) running = false;
- else if(keystate[SDL_SCANCODE_B]) {
- randGenMap(1);
- randGenMap(2);
- randGenMap(3);
- randGenMap(4);
- randGenMap(5);
- randGenMap(6);
- randGenMap(7);
- randGenMap(8);
- }
- for(int x = 0; x < RESX; x ++) {
- float cameraX = x/HALFRESX -1;
- for(int y = 0; y < RESY; y ++) {
- float cameraY = y/HALFRESY -1;//cam vec, -1 to 1
- struct Point3D rayd;
- rayd.z = dir.z + plane.z*cameraY;
- rayd.x = dir.x + plane.x*cameraX;
- rayd.y = dir.y + plane.y*cameraX;
- struct Point3D delta;
- delta.y = fabsf(1/rayd.y);
- delta.x = fabsf(1/rayd.x);
- delta.z = fabsf(1/rayd.z);
- struct pos map;
- map.x = (char)pos.x;
- map.y = (char)pos.y;
- map.z = (char)pos.z;
- struct pos s;
- struct pos step;
- struct Point3D sdist;
- if(rayd.x < 0) {
- step.x = -1;
- s.x = 1;
- sdist.x = (pos.x - map.x) * delta.x;
- }
- else {
- step.x = 1;
- s.x = 0;
- sdist.x = (map.x + 1 - pos.x) * delta.x;
- }
- if(rayd.y < 0) {
- step.y = -1;
- s.y = 1;
- sdist.y = (pos.y - map.y) * delta.y;
- }
- else {
- step.y = 1;
- s.y = 0;
- sdist.y = (map.y + 1 - pos.y) * delta.y;
- }
- if(rayd.z < 0) {
- step.z = -1;
- s.z = 1;
- sdist.z = (pos.z - map.z) * delta.z;
- }
- else {
- step.z = 1;
- s.z = 0;
- sdist.z = (map.z + 1 - pos.z) * delta.z;
- }
- char side; //either 0 (NS), or 1 (EW), or 2(UD)
- while( !MAP[map.x][map.y][map.z]) {
- if(sdist.y < sdist.x ) {
- if(sdist.y < sdist.z) {
- sdist.y += delta.y;
- map.y += step.y;
- side = 1; // y
- }
- else {
- sdist.z += delta.z;
- map.z += step.z;
- side = 2;
- }
- }
- else {
- if(sdist.x < sdist.z) {
- sdist.x += delta.x;
- map.x += step.x;
- side = 0;
- }
- else {
- sdist.z += delta.z;
- map.z += step.z;
- side = 2;
- }
- }
- }
- char blockHit = MAP[map.x][map.y][map.z];
- #ifdef USE_REFLECTIONS
- bool reflect = false;
- reflect:;
- if(blockHit == 6){
- reflect = true;
- if(!side) {
- step.x*=-1;
- sdist.x += delta.x;
- map.x += step.x;
- rayd.x*=-1;
- }
- else if(side == 1) {
- step.y*=-1;
- sdist.y += delta.y;
- map.y += step.y;
- rayd.y*=-1;
- }
- else {
- step.z*=-1;
- sdist.z += delta.z;
- map.z += step.z;
- rayd.z*=-1;
- }
- while( !MAP[map.x][map.y][map.z]) {
- if(sdist.y < sdist.x ) {
- if(sdist.y < sdist.z) {
- sdist.y += delta.y;
- map.y += step.y;
- side = 1; // y
- }
- else {
- sdist.z += delta.z;
- map.z += step.z;
- side = 2;
- }
- }
- else {
- if(sdist.x < sdist.z) {
- sdist.x += delta.x;
- map.x += step.x;
- side = 0;
- }
- else {
- sdist.z += delta.z;
- map.z += step.z;
- side = 2;
- }
- }
- }
- blockHit = MAP[map.x][map.y][map.z];
- }
- #endif
- struct Point3D lightDist;
- struct Point3D hit;
- if(!side) { // x side hit
- hit.x = map.x + s.x;
- float relativeHit = hit.x-pos.x;
- hit.y = pos.y + relativeHit/rayd.x*rayd.y;
- hit.z = pos.z + relativeHit/rayd.x*rayd.z;
- }
- else if(side == 1) { // y side hit
- hit.y = map.y + s.y;
- float relativeHit = hit.y-pos.y;
- hit.x = pos.x + relativeHit/rayd.y*rayd.x;
- hit.z = pos.z + relativeHit/rayd.y*rayd.z;
- }
- else { // z side hit
- hit.z = map.z + s.z;
- float relativeHit = hit.z-pos.z;
- hit.x = pos.x + relativeHit/rayd.z*rayd.x;
- hit.y = pos.y + relativeHit/rayd.z*rayd.y;
- }
- lightDist.x = light[0][0] - hit.x; // x
- lightDist.y = light[0][1] - hit.y; // y
- lightDist.z = light[0][2] - hit.z; // z
- double lightdist = sqrt(lightDist.x*lightDist.x + lightDist.y*lightDist.y + lightDist.z*lightDist.z);
- if(lightdist > 32) {voxelColour = 32;}
- else if(lightdist > 4) voxelColour = 1024/lightdist;
- else voxelColour = 255;
- #ifdef USE_REFLECTIONS
- if(reflect) voxelColour/=1.2;
- #endif
- void drawPixel( Uint32 colour) {
- pixels[y][x] = colour;
- }
- if(blockHit <3) drawPixel(0x010101*voxelColour);
- else if(blockHit == 3) drawPixel(voxelColour);
- else if(blockHit == 4) drawPixel(0x10000*voxelColour);
- #ifdef USE_REFLECTIONS
- else if(blockHit == 6) goto reflect;
- #endif
- else drawPixel(0x100*voxelColour);
- }
- }
- SDL_UpdateTexture(texture, NULL, pixels, RESX*sizeof(Uint32));
- SDL_RenderCopy(renderer, texture, NULL, NULL);
- SDL_RenderPresent( renderer );
- t2 = SDL_GetTicks();
- ms = t2-t1;
- printf("pos: %f, %f, %f | render time: %dms\n", pos.x, pos.y, pos.z, ms );
- }
- SDL_DestroyWindow( window );
- SDL_DestroyRenderer( renderer );
- SDL_DestroyTexture( texture );
- SDL_Quit();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement