M1 + VSCode로 SFML 사용하기 Use SFML in M1 and VSCode

이경헌·2021년 10월 26일
0
  1. M1용 Homebrew를 이용하여 SFML를 다운로드합니다(조금 오래 걸립니다).
brew install sfml

그러면 /opt/homebrew/Cellar/ 경로에 sfml이라는 폴더가 생깁니다.

  1. 원래는 컴파일할 때 SFML 의존성을 인자에 전달하여 명시해야 합니다. 그러나 VSCode에서는 tasks.json에 이를 자동화할 수 있습니다. 저는 c++17 기준 clang++를 쓰므로 tasks.json을 다음과 같이 구성합니다.

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "clang++ build active file",
            "command": "/usr/bin/clang++",
            "args": [
                "-std=c++17",
                "-stdlib=libc++",
                "-g",
                "${file}",
                // SFML dependency including begin
                "-I/opt/homebrew/Cellar/sfml/2.5.1_1/include",
                "-L/opt/homebrew/Cellar/sfml/2.5.1_1/lib",
                "-lsfml-window",
                "-lsfml-system",
                "-lsfml-graphics",
                // SFML dependency including end
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build"
        },
		{
			"label": "Open Terminal",
			"type": "shell",
			"command": "osascript -e 'tell application \"Terminal\"\ndo script \"echo hello\"\nend tell'",
			"problemMatcher": []
		}
    ]
}
  1. 이러면 컴파일은 제대로 되지만 VSCode의 인텔리센스 기능을 사용할 수 없습니다(#include <SFML/Graphics.hpp>에서 링크를 찾을 수 없다고 함). 따라서 c_cpp_properties.jsonincludePath에도 SFML 폴더 경로를 넣어 주어야 합니다.

c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "${workspaceFolder}/**",
                "/opt/homebrew/Cellar/sfml/2.5.1_1/include/"
            ],
            "defines": [],
            "macFrameworkPath": [
                "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
            ],
            "compilerPath": "/usr/bin/clang",
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "macos-clang-arm64"
        }
    ],
    "version": 4
}
  1. 끝!
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <cmath>

class ParticleSystem : public sf::Drawable, public sf::Transformable{
public:
    ParticleSystem(unsigned int count) : particles{count}, vertices{sf::Points, count}, lifetime{sf::seconds(3.0f)}, emitter{0.0f, 0.0f}{

    }

    void setEmitter(sf::Vector2f position){
        emitter = position;
    }

    void update(sf::Time elapsed){
        for (std::size_t i = 0; i < particles.size(); ++i){
            auto& p = particles.at(i);
            p.lifetime -= elapsed;

            if (p.lifetime <= sf::Time::Zero){
                resetParticle(i);
            }

            vertices[i].position += p.velocity * elapsed.asSeconds();

            float ratio = p.lifetime.asSeconds() / lifetime.asSeconds();
            vertices[i].color.a = static_cast<sf::Uint8>(ratio * 255);
        }
    }

private:
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const{
        states.transform *= getTransform();
        target.draw(vertices, states);
    }

    struct Particle{
        sf::Vector2f velocity;
        sf::Time lifetime;
    };

    void resetParticle(std::size_t index){
        float angle = (std::rand() % 360) * 3.14f / 180.0f;
        float speed = (std::rand() % 50) + 50.0f;
        particles[index].velocity = { std::cos(angle) * speed, std::sin(angle) * speed };
        particles[index].lifetime = sf::milliseconds((std::rand() % 2000) + 1000);

        vertices[index].position = emitter;
    }

    std::vector<Particle> particles;
    sf::VertexArray vertices;
    sf::Time lifetime;
    sf::Vector2f emitter;
};

int main(){
    sf::RenderWindow window {sf::VideoMode {800, 480}, "Particles" };

    ParticleSystem particles(1000);
    sf::Clock clock;

    while (window.isOpen()){
        sf::Event event;
        while (window.pollEvent(event)){
            if (event.type == sf::Event::Closed){
                window.close();
            }
        }

        auto mouse = sf::Mouse::getPosition(window);
        particles.setEmitter(window.mapPixelToCoords(mouse));

        auto elapsed = clock.restart();
        particles.update(elapsed);

        window.clear();
        window.draw(particles);
        window.display();
    }

    return EXIT_SUCCESS;
}

profile
Undergraduate student in Korea University. Major in electrical engineering and computer science.

0개의 댓글