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
相关产品推荐
相关产品推荐

