Mostly working textures, an ability to look up/down (pitch) and ready to read in images for the textures.

master
Zed A. Shaw 3 months ago
parent c1b7df1850
commit 22b3299fb6
  1. 82
      fenscaster.cpp

@ -1,5 +1,6 @@
#include <fmt/core.h>
#include <numbers>
#include <algorithm>
#include <cmath>
#include "matrix.hpp"
#include <cstdlib>
@ -10,14 +11,14 @@ using matrix::Matrix;
using namespace fmt;
Matrix MAP{
{1,1,1,1,1,1,1,1,1},
{1,0,1,0,0,0,0,0,1},
{1,0,1,0,0,1,1,0,1},
{1,0,0,0,0,0,0,0,1},
{1,1,0,0,0,0,0,1,1},
{1,0,0,1,1,1,0,0,1},
{1,0,0,0,0,0,1,1,1},
{1,1,1,1,1,1,1,1,1}
{2,2,2,2,2,2,2,2,2},
{2,0,8,0,0,0,0,0,2},
{2,0,7,0,0,5,6,0,2},
{2,0,0,0,0,0,0,0,2},
{2,2,0,0,0,0,0,2,2},
{2,0,0,1,3,4,0,0,2},
{2,0,0,0,0,0,2,2,2},
{2,2,2,2,2,2,2,2,2}
};
const int SCREEN_HEIGHT=480;
@ -33,6 +34,7 @@ const int CASTED_RAYS=120;
const float STEP_ANGLE = FOV / CASTED_RAYS;
const int MAX_DEPTH = MAP_SIZE * TILE_SIZE;
const float SCALE = (SCREEN_WIDTH / 2) / CASTED_RAYS;
int PITCH=25;
float player_x = SCREEN_WIDTH / 4;
float player_y = SCREEN_WIDTH / 4;
@ -56,6 +58,7 @@ std::vector<uint32_t> texture[8];
#define texWidth 64
#define texHeight 64
void load_textures() {
for(int i = 0; i < 8; i++) {
texture[i].resize(texWidth * texHeight);
@ -111,7 +114,7 @@ void draw_map(Fenster &window, Matrix &map) {
for(size_t y = 0; y < matrix::height(map); y++) {
for(size_t x = 0; x < matrix::width(map); x++) {
draw_map_rect(window, x, y, map[y][x] == 1 ? light_grey : dark_grey);
draw_map_rect(window, x, y, map[y][x] == 0 ? dark_grey : light_grey);
}
}
}
@ -231,30 +234,57 @@ void ray_casting(Fenster &window, Matrix& map) {
int lineHeight = int(h / perpWallDist);
int drawStart = -lineHeight / 2 + h / 2;
int drawStart = -lineHeight / 2 + h / 2 + PITCH;
if(drawStart < 0) drawStart = 0;
int drawEnd = lineHeight / 2 + h / 2;
int drawEnd = lineHeight / 2 + h / 2 + PITCH;
if(drawEnd >= h) drawEnd = h - 1;
uint32_t color = gray_color(std::min(lineHeight, 255));
int texNum = MAP[mapY][mapX] - 1;
// calculate value of wallX
double wallX; // where exactly the wall was hit
if(side == 0) {
wallX = posY + perpWallDist * rayDirY;
} else {
wallX = posX + perpWallDist * rayDirX;
}
wallX -= floor((wallX));
// x coorindate on the texture
int texX = int(wallX * double(texWidth));
if(side == 0 && rayDirX > 0) texX = texWidth - texX - 1;
if(side == 1 && rayDirY < 0) texX = texWidth - texX - 1;
// LODE: an integer-only bresenham or DDA like algorithm could make the texture coordinate stepping faster
draw_line(window,
{size_t(x + THREED_VIEW_WIDTH), size_t(drawStart)},
{size_t(x + THREED_VIEW_WIDTH), size_t(drawEnd)}, color);
// How much to increase the texture coordinate per screen pixel
double step = 1.0 * texHeight / lineHeight;
// Starting texture coordinate
double texPos = (drawStart - PITCH - h / 2 + lineHeight / 2) * step;
for(int y = drawStart; y < drawEnd; y++) {
// BUG? Why bitwise and here?
int texY = (int)texPos & (texHeight - 1);
texPos += step;
uint32_t color = texture[texNum][texHeight * texY + texX];
if(side == 1) color = (color >> 1) & 8355711;
window.px(x + THREED_VIEW_WIDTH, y) = color;
}
}
}
void draw_ceiling_floor(Fenster &window) {
draw_rect(window,
{size_t(window.width() / 2), 0},
{size_t(window.height()), size_t(window.height() / 2)},
gray_color(100));
draw_rect(window,
{size_t(window.width() / 2), size_t(window.height() / 2)},
{size_t(window.width() / 2), size_t(window.height() / 2)},
gray_color(200));
draw_rect(window,
{size_t(window.width() / 2), 0},
{size_t(window.height()), size_t(window.height() / 2 + PITCH)},
gray_color(100));
}
void draw_everything(Fenster &window) {
@ -292,7 +322,7 @@ int main() {
if(empty_space(int(posX), int(posY - dirY * moveSpeed))) posY -= dirY * moveSpeed;
}
if(window.key('E')) {
if(window.key('D')) {
double oldDirX = dirX;
dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed);
dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed);
@ -300,7 +330,7 @@ int main() {
double oldPlaneX = planeX;
planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed);
planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed);
} else if(window.key('Q')) {
} else if(window.key('A')) {
double oldDirX = dirX;
dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed);
dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed);
@ -310,10 +340,10 @@ int main() {
planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed);
}
if(window.key('D')) {
println("NOT IMPLEMENTED USE E");
} else if(window.key('A')) {
println("NOT IMPLEMENTED USE Q");
if(window.key('E')) {
PITCH = std::clamp(PITCH + 10, -60, 240);
} else if(window.key('Q')) {
PITCH = std::clamp(PITCH - 10, -60, 240);
}
}

Loading…
Cancel
Save