Created
August 19, 2025 21:05
-
-
Save DenisBelmondo/64611b8f824b04d1e3aa5e9e442749ed to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <cmath> | |
| #include <cstdio> | |
| #include <raylib.h> | |
| #include <raymath.h> | |
| #include <vector> | |
| static const auto TICK_RATE = 1.0 / 30.0; | |
| static Vector2 playerPosition { 5, 5 }; | |
| static Vector2 playerDirection { 0, -1 }; | |
| static Vector2 playerVelocity; | |
| static std::vector<int> plane; | |
| static std::size_t planePitch; | |
| static Camera3D camera { | |
| .position = {}, | |
| .target = {}, | |
| .up = { 0, 1, 0 }, | |
| .fovy = 75, | |
| .projection = CAMERA_PERSPECTIVE, | |
| }; | |
| static const auto WALL_VERTEX_SHADER_SOURCE = R"( | |
| #version 330 | |
| // Input vertex attributes | |
| in vec3 vertexPosition; | |
| in vec2 vertexTexCoord; | |
| in vec3 vertexNormal; | |
| in vec4 vertexColor; | |
| // Input uniform values | |
| uniform mat4 mvp; | |
| // Output vertex attributes (to fragment shader) | |
| out vec2 fragTexCoord; | |
| out vec4 fragColor; | |
| out vec3 fragVertexNormal; | |
| // NOTE: Add your custom variables here | |
| void main() { | |
| // Send vertex attributes to fragment shader | |
| fragTexCoord = vertexTexCoord; | |
| fragColor = vertexColor; | |
| fragVertexNormal = vertexNormal; | |
| // Calculate final vertex position | |
| gl_Position = mvp * vec4(vertexPosition, 1.0); | |
| } | |
| )"; | |
| static const auto WALL_FRAGMENT_SHADER_SOURCE = R"( | |
| #version 330 | |
| // Input vertex attributes (from vertex shader) | |
| in vec2 fragTexCoord; | |
| in vec4 fragColor; | |
| in vec3 fragVertexNormal; | |
| // Input uniform values | |
| uniform sampler2D texture0; | |
| uniform vec4 colDiffuse; | |
| // Output fragment color | |
| out vec4 finalColor; | |
| // NOTE: Add your custom variables here | |
| void main() { | |
| // Texel color fetching from texture sampler | |
| vec4 texelColor = texture(texture0, fragTexCoord); | |
| // TODO: hsv | |
| float shade = abs(dot(fragVertexNormal, vec3(0.5, 1, 1))); | |
| vec4 sshade = vec4(shade, shade, shade, 1.0); | |
| // final color is the color from the texture | |
| // times the tint color (colDiffuse) | |
| // times the fragment color (interpolated vertex color) | |
| finalColor = texelColor * colDiffuse * fragColor * sshade; | |
| } | |
| )"; | |
| static RenderTexture renderTexture; | |
| static Mesh wallMesh; | |
| static Texture pistolTexture; | |
| static Image wallImage000; | |
| static Texture wallTexture000; | |
| static Material wallMaterial; | |
| static void tick(double deltaTime) { | |
| float lookAxis = IsKeyDown(KEY_RIGHT) - IsKeyDown(KEY_LEFT); | |
| float forwardAxis = IsKeyDown(KEY_W) - IsKeyDown(KEY_S); | |
| float strafeAxis = IsKeyDown(KEY_D) - IsKeyDown(KEY_A); | |
| Vector2 move {}; | |
| lookAxis *= 3; | |
| lookAxis *= deltaTime; | |
| playerDirection = Vector2Rotate(playerDirection, lookAxis); | |
| move += playerDirection * forwardAxis; | |
| move += Vector2 { -playerDirection.y, playerDirection.x } * strafeAxis; | |
| move = Vector2Normalize(move); | |
| move *= 2; | |
| move *= deltaTime; | |
| playerVelocity += move; | |
| auto oldPlayerPosition = playerPosition; | |
| playerPosition += playerVelocity; | |
| if (plane[int(playerPosition.y + 0.5f) * planePitch + int(playerPosition.x + 0.5f)]) { | |
| playerPosition = oldPlayerPosition; | |
| } | |
| playerVelocity = Vector2Lerp(playerVelocity, Vector2Zero(), 10 * deltaTime); | |
| } | |
| int main() { | |
| plane = { | |
| 31, 15, 7, 3, 1, 32, 16, 8, 4, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| }; | |
| planePitch = std::sqrt(plane.size()); | |
| InitWindow(640, 480, "Wolfenstein 3D"); | |
| renderTexture = LoadRenderTexture(640, 480); | |
| wallMesh = GenMeshCube(1, 1, 1); | |
| pistolTexture = LoadTexture("static/textures/pistol.png"); | |
| wallImage000 = LoadImage("static/textures/wall_000.png"); | |
| ImageFlipVertical(&wallImage000); | |
| wallTexture000 = LoadTextureFromImage(wallImage000); | |
| wallMaterial = LoadMaterialDefault(); | |
| wallMaterial.shader = LoadShaderFromMemory(WALL_VERTEX_SHADER_SOURCE, WALL_FRAGMENT_SHADER_SOURCE); | |
| wallMaterial.maps[MATERIAL_MAP_DIFFUSE].color = WHITE; | |
| wallMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = wallTexture000; | |
| double previousTime = GetTime(); | |
| double lag = 0.0; | |
| while (!WindowShouldClose()) { | |
| double currentTime = GetTime(); | |
| double deltaTime = currentTime - previousTime; | |
| previousTime = currentTime; | |
| lag += deltaTime; | |
| while (lag >= TICK_RATE) { | |
| tick(TICK_RATE); | |
| lag -= TICK_RATE; | |
| } | |
| BeginTextureMode(renderTexture); { | |
| ClearBackground(BLACK); | |
| DrawRectangle(0, 0, 640, 240, { 114, 114, 114, 255 }); | |
| DrawRectangle(0, 241, 640, 480, { 32, 32, 32, 255 }); | |
| camera.position = { playerPosition.x, 0, playerPosition.y }; | |
| camera.target = Vector3Add(camera.position, { playerDirection.x, 0, playerDirection.y }); | |
| BeginMode3D(camera); { | |
| for (std::size_t i = 0; i < plane.size(); i++) { | |
| float x = float(i % planePitch); | |
| float y = std::floor(i / float(planePitch)); | |
| for (int j = plane[i], k = 0; j > 0; j >>= 1, k++) { | |
| if (j & 1) { | |
| DrawMesh(wallMesh, wallMaterial, MatrixTranslate(x, k, y)); | |
| } | |
| } | |
| } | |
| } EndMode3D(); | |
| } EndTextureMode(); | |
| BeginDrawing(); | |
| DrawTexturePro(renderTexture.texture, { 0, 0, float(renderTexture.texture.width), float(-renderTexture.texture.height) }, { 0, 0, 640, 480 }, {}, 0, WHITE); | |
| EndDrawing(); | |
| } | |
| UnloadMaterial(wallMaterial); | |
| UnloadTexture(pistolTexture); | |
| UnloadTexture(wallTexture000); | |
| UnloadImage(wallImage000); | |
| UnloadMesh(wallMesh); | |
| UnloadRenderTexture(renderTexture); | |
| CloseWindow(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment