SDL の簡単なサンプル
対象
SDL初学者
内容
SDL には四角や円を描くそれ用の関数はないので、それ用のコードを防備録として載せておきます。
デモはこちら。
main.cpp:
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <SDL3/SDL.h>
#include <cmath>
#include <iostream>
constexpr int WINDOW_WIDTH = 300;
constexpr int WINDOW_HEIGHT = 300;
SDL_Renderer *renderer = nullptr;
SDL_Window *window = nullptr;
void drawBox(float x, float y) {
SDL_FColor color = {0.5f, 0.5f, 0.5f, 1.0};
SDL_FPoint tex = {0.0f, 0.0f};
float len = 100.0f;
SDL_Vertex box[4] = {
{{x, y}, color, tex},
{{x + len, y}, color, tex},
{{x + len, y + len}, color, tex},
{{x, y + len}, color, tex},
};
int indice[6] = {0};
for (int i = 0; i < 2; i++) {
indice[i * 3] = i * 2;
indice[i * 3 + 1] = i * 2 + 1;
indice[i * 3 + 2] = (i * 2 + 2) % 4;
}
SDL_RenderGeometry(renderer, NULL, box, 4, indice, 6);
}
void drawCircle(float x, float y) {
constexpr int segment = 32;
float radius = 50.0f;
SDL_FColor color = {0.5f, 0.5f, 0.5f, 1.0};
SDL_Vertex vec[segment + 1];
vec[0].position = {x, y};
vec[0].color = color;
vec[0].tex_coord = {0.0f, 0.0f};
for (int i = 0; i < segment; i++) {
float angle = i * 2 * SDL_PI_F / (segment);
vec[i + 1].position = {x + radius * cosf(angle),
y + radius * sinf(angle)};
vec[i + 1].color = color;
vec[i + 1].tex_coord = vec[0].tex_coord;
}
int indice[segment * 3];
for (int i = 0; i < segment; i++) {
indice[i * 3 + 0] = 0;
indice[i * 3 + 1] = i + 1;
indice[i * 3 + 2] = (i + 1) % segment + 1;
}
SDL_RenderGeometry(renderer, NULL, vec, segment + 1, indice, segment * 3);
}
void main_loop() {
SDL_RenderClear(renderer);
drawBox(50, 50);
drawCircle(200, 200);
SDL_RenderPresent(renderer);
}
int main(int argc, char *argv[]) {
if (!SDL_Init(SDL_INIT_VIDEO)) {
std::cerr << "Failed to initiate SDL3" << SDL_GetError() << "\n";
return 1;
}
window = SDL_CreateWindow("Sample", WINDOW_WIDTH, WINDOW_HEIGHT,
SDL_WINDOW_RESIZABLE);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED);
renderer = SDL_CreateRenderer(window, nullptr);
SDL_SetRenderVSync(renderer, 1);
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(main_loop, 0, 1);
#else
bool running = true;
SDL_Event ev;
while (running) {
while (SDL_PollEvent(&ev)) {
if (ev.type == SDL_EVENT_QUIT) {
running = false;
}
}
main_loop();
}
#endif
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
#ifdef __EMSCRIPTEN__
extern "C" {
EMSCRIPTEN_KEEPALIVE
void stop_loop() { emscripten_cancel_main_loop(); }
}
#endif
CMakeList.txt は以下の様に。
cmake_minimum_required(VERSION 3.28)
project(sdlSample LANGUAGES CXX)
if(EMSCRIPTEN)
else()
find_package(SDL3 CONFIG REQUIRED)
endif()
add_executable(${PROJECT_NAME} main.cpp)
if(EMSCRIPTEN)
target_link_libraries(${PROJECT_NAME} PRIVATE
"-sUSE_SDL=3"
"-sMODULARIZE=1"
"-sEXPORT_NAME=SDLSampleModule"
"-sENVIRONMENT=web"
"-sOFFSCREENCANVAS_SUPPORT=1"
"-sNO_EXIT_RUNTIME=1"
"-sEXPORTED_FUNCTIONS=['_main','_stop_loop']"
)
else()
target_link_libraries(${PROJECT_NAME} PRIVATE
SDL3::SDL3
)
endif()三角形を合わせて描くことになります。上のサンプルの四角形だと2つの三角形を合わせて作るので、頂点は6つになる。
円の場合も三角形を使って描くので、上の場合は segment=32、つまり 32分割の三角形で円を描くことに。細かくするほどきれいな円になりますが、それだけ処理時間がかかる。