You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SFML 3射线投射3D程序添加地板纹理后运行数秒崩溃(错误代码0xc0000409)求助

SFML 3射线投射3D程序添加地板纹理后运行数秒崩溃(错误代码0xc0000409)求助

我用C++20 + SFML 3.0 + Visual Studio 2022在Windows 10上开发了一个射线投射程序,之前没加地板渲染的时候一切正常,但添加地板之后就出问题了:程序能正常运行个几秒——如果把帧率限制到60的话能多跑一倍时间,但之后就会出现“白屏”问题:整个屏幕变白,但墙壁还能显示(因为墙壁是绘制在地板上层的),紧接着程序就崩溃了,调试控制台显示退出代码为0xc0000409。我肯定是地板渲染的代码导致的问题,因为没加这部分之前完全没有异常。

下面是我的代码:

Main.cpp

#include "libraries.h"

int main() {
    sf::RenderWindow window(sf::VideoMode({ (size_t)SCREEN_W, (size_t)SCREEN_H }), "Raycaster", sf::Style::Close | sf::Style::Titlebar);
    window.setFramerateLimit(60);

    Map map(48.0f, "map.png");
    Player player;
    player.position = sf::Vector2f(50, 50);
    Renderer renderer;

    sf::Clock gameClock;

    while (window.isOpen()) {
        float deltaTime = gameClock.restart().asSeconds();

        while (const std::optional event = window.pollEvent()) {
            if (event->is<sf::Event::Closed>()) {
                window.close();
            }
        }

        player.update(deltaTime);

        window.clear();
        renderer.draw3dView(window, player, map);
        window.display();

        window.setTitle("Garbage Ass Raycasting [FrameRate: " + std::to_string((int)(1.0f / deltaTime)) + "]");
    }
}

Renderer.h

#pragma once
#ifndef _RENDERER_H
#define _RENDERER_H

#include "libraries.h"

class Renderer {
public:
    Renderer();
    void draw3dView(sf::RenderTarget& target, const Player& player, const Map& map);

private:
    sf::Texture wallTexture;
    sf::Image floorImage;
};

#endif // !_RENDERER_H

Renderer.cpp

#include "libraries.h"

struct Ray {
    sf::Vector2f hitPosition;
    sf::Vector2u mapPosition;
    float distance;
    bool hit;
    bool isHitVertical;
};

Renderer::Renderer() : wallTexture("wall_texture.png"), floorImage("floor_texture.png") {
    if (!wallTexture.loadFromFile("wall_texture.png")) {
        std::cerr << "Failed to load \"wall_texture.png\"!\n";
    }
    if (wallTexture.getSize().x != wallTexture.getSize().y) {
        std::cerr << "ERROR: Wall texture is not square!\n";
    }
    if (!floorImage.loadFromFile("floor_texture.png")) {
        std::cerr << "Failed to load \"floor_texture.png\"!\n";
    }
    if (floorImage.getSize().x != floorImage.getSize().y) {
        std::cerr << "ERROR: Floor texture is not square!\n";
    }
}

void Renderer::draw3dView(sf::RenderTarget& target, const Player& player, const Map& map) {
    float radians = player.angle * PI / 180.0f;
    sf::Vector2f direction{ std::cos(radians), std::sin(radians) };
    sf::Vector2f plane{ -direction.y, direction.x * 0.66f};
    sf::Vector2f position = player.position / map.getCellSize();

    // Ceiling
    sf::RectangleShape rectangle(sf::Vector2f(SCREEN_W, SCREEN_H / 2.0f));
    rectangle.setFillColor(sf::Color(100, 170, 255));
    target.draw(rectangle);

    // *** BELOW IS WHERE THE PROBLEM HAPPENS!!! I JUST DON'T KNOW EXACTLY WHERE!!! ***
    // Floor
    const unsigned int W = SCREEN_W;
    const unsigned int H = SCREEN_H;
    uint8_t* floorPixels = new uint8_t[W * H * 4]{};

    for (size_t y = SCREEN_H / 2; y < SCREEN_H; y++) {
        sf::Vector2f rayDirLeft{ direction - plane }, rayDirRight{ direction + plane };
        float rowDistance = CAMERA_Z / ((float)y - SCREEN_H / 2);
        sf::Vector2f floorStep = rowDistance * (rayDirRight - rayDirLeft) / SCREEN_W;
        sf::Vector2f floor = position + rowDistance * rayDirLeft;

        for (size_t x = 0; x < SCREEN_W; x++) {
            sf::Vector2i cell{ floor };
            float textureSize = floorImage.getSize().x;
            sf::Vector2i texCoords{textureSize * (floor - (sf::Vector2f)cell)};
            texCoords.x &= (int)textureSize - 1;
            texCoords.y &= (int)textureSize - 1;
            sf::Color color = floorImage.getPixel(sf::Vector2u(texCoords.x, texCoords.y));

            for (size_t i = 0; i < (W * H); i++) {
                floorPixels[(x + y * (size_t)SCREEN_W) * 4 + 0] = color.r;
                floorPixels[(x + y * (size_t)SCREEN_W) * 4 + 1] = color.g;
                floorPixels[(x + y * (size_t)SCREEN_W) * 4 + 2] = color.b;
                floorPixels[(x + y * (size_t)SCREEN_W) * 4 + 3] = color.a;
            }

            floor += floorStep;
        }
    }

    sf::Image image(sf::Vector2u(W, H), floorPixels);
    sf::Texture texture(image);
    sf::Sprite sprite{ texture };
    target.draw(sprite);
    // *** ABOVE IS WHERE THE PROBLEM HAPPENS!!! I JUST DON'T KNOW EXACTLY WHERE!!! ***

    //Walls
    sf::VertexArray walls{ sf::PrimitiveType::Lines };
    for (size_t i = 0; i < SCREEN_W; i++) {
        float cameraX = i * 2.0f / SCREEN_W - 1.0f; // -1.0f -> 0.0f -> 1.0f
        sf::Vector2f rayPos = position;
        sf::Vector2f rayDir = direction + plane * cameraX;
        sf::Vector2f deltaDist { std::abs(1.0f / rayDir.x), std::abs(1.0f / rayDir.y), };
        sf::Vector2i mapPos{ rayPos };
        sf::Vector2i step;
        sf::Vector2f sideDist;

        if (rayDir.x < 0.0f) {
            step.x = -1;
            sideDist.x = (-mapPos.x + rayPos.x) * deltaDist.x;
        } else {
            step.x = 1;
            sideDist.x = (mapPos.x - rayPos.x + 1.0f) * deltaDist.x;
        }
        // 原代码此处被截断,仅保留已提供部分
    }
}

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 03:13:12