オーディオとビデオの開発 17: SDL 関連の API と構造

SDL関連のAPI

テクスチャレンダリング関連のAPI

SDL_init

SDL_Init は SDL ライブラリの初期化関数であり、その役割は SDL ライブラリを初期化し、必要なサブシステムをロードすることです。この関数は、SDL ライブラリを使用する他の関数よりも前に呼び出す必要があります関数の定義は次のとおりです。

int SDL_Init(Uint32 flags)

flags パラメータは、初期化する必要があるサブシステムを指定するビットマスクです。一般的な値は次のとおりです。

  • SDL_INIT_VIDEO: ウィンドウやレンダラーなどの作成と管理に使用されるビデオ サブシステムの初期化を示します。
  • SDL_INIT_AUDIO: オーディオの再生および録音のためのオーディオ サブシステムの初期化を示します。
  • SDL_INIT_JOYSTICK: ゲーム ハンドルとゲーム パッドを管理するための初期化ハンドル サブシステムを示します。
  • SDL_INIT_GAMECONTROLLER: ゲーム コントローラを管理するためにゲーム コントローラ サブシステムが初期化されていることを示します。
  • SDL_INIT_EVENTS: SDL アプリケーションのイベント ループとメッセージ キューを処理するために初期化イベント サブシステムが使用されることを示します。

その他の利用可能なサブシステムには、SDL_INIT_TIMER、SDL_INIT_HAPTIC、SDL_INIT_SENSOR などがあります。複数のサブシステムを使用するには、それらの値をビットごとに OR 演算することができます。次に例を示します。

SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);

関数の戻り値は、初期化が成功したかどうかを示す整数です。戻り値が 0 の場合は初期化が成功したことを意味します。それ以外の場合はエラー コードが返され、SDL_GetError() 関数を呼び出すことで関連するエラー情報を取得できます。

SDL_CreateWindow

SDL_CreateWindow はウィンドウを作成するための SDL ライブラリの関数であり、その役割はグラフィカル インターフェイスを表示するための SDL ウィンドウ オブジェクトを作成することです。関数の定義は次のとおりです。

SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int w, int h, Uint32 flags)

関数のパラメータとその説明は次のとおりです。

  • title: ウィンドウのタイトル、ゼロで終わる文字列。

  • x: 画面上のウィンドウの左上隅の水平座標 値が SDL_WINDOWPOS_CENTERED の場合、ウィンドウは画面の中央に表示されます。

  • y: 画面上のウィンドウの左上隅の垂直座標値が SDL_WINDOWPOS_CENTERED の場合、ウィンドウは画面の中央に表示されます。

    x と y は、SDL_WINDOWPOS_UNDEFINEDオペレーティング システムがウィンドウの位置を独自に決定することを示すように設定されます。

  • w:ウィンドウの幅(単位:ピクセル)。

  • h: ウィンドウの高さ (単位: ピクセル)。

  • flags: ウィンドウの属性。SDL_WindowFlags 列挙型のビットマスクです。一般的に使用されるプロパティは次のとおりです。

    • SDL_WINDOW_SHOWN: ウィンドウが作成されるとすぐに表示されます。
    • SDL_WINDOW_RESIZABLE: ウィンドウはサイズ変更可能です。
    • SDL_WINDOW_FULLSCREEN: ウィンドウが全画面表示されます (タスクバーなどを覆う)。
    • SDL_WINDOW_BORDERLESS: ウィンドウには枠がないため、サイズを変更できません。
    • SDL_WINDOW_ALLOW_HIGHDPI: 高解像度ディスプレイ (Retina スクリーンなど) をサポートします。
    • SDL_WINDOW_OPENGL: ウィンドウのレンダリングに OpenGL が使用されることを示します。

戻り値は、作成されたウィンドウ オブジェクトを表す SDL_Window 構造体ポインターです。作成に失敗した場合は NULL が返され、SDL_GetError() 関数を呼び出してエラー情報が取得されます。

SDL_CreateWindow 関数は、基本的なウィンドウ オブジェクトの作成にのみ使用できます。OpenGL または Vulkan を使用してグラフィックをレンダリングする必要がある場合は、SDL_CreateWindowAndRenderer または SDL_CreateWindowFrom 関数を使用する必要があります。

SDL_DestroyWindow

SDL_DestroyWindow は、SDL2 でウィンドウを破棄するために使用される関数ですウィンドウは SDL_Window タイプの構造体であり、さまざまなウィンドウをモジュール化するために必要なデータとプロパティが含まれています。ウィンドウの使用が終了したら、メモリを解放してプログラム リークを回避するために、SDL_DestroyWindow 関数を呼び出してウィンドウを破棄する必要があります。SDL_DestroyWindow 関数の関数プロトタイプは次のとおりです。

void SDL_DestroyWindow(SDL_Window* window)

関数パラメータはwindow、破棄されるウィンドウ ポインタです。この関数を使用すると、プログラムはウィンドウとそのすべてのリソースをメモリから削除し、ウィンドウへの参照を使用できなくなります。

SDL_終了

SDL_Quit はSDL ライブラリの終了関数です。その役割は、SDL ライブラリによって占有されているリソースを解放し、SDL アプリケーションを終了することです関数の定義は次のとおりです。

void SDL_Quit(void)

この関数にはパラメータも戻り値もありません。この関数を呼び出した後、SDL アプリケーションは正常に終了します。SDL_Quit 関数を呼び出した後は、すべての SDL ウィンドウ、レンダラー、オーディオ デバイスなどが破棄されることに注意してください。SDL_Quit 関数を呼び出す前に、これらすべてのオブジェクトのリソースが正常に解放されていることを確認する必要があります

main 関数の最後では、SDL_Quit 関数を常に呼び出して、SDL ライブラリによって占有されているリソースを解放する必要があります。例は次のとおりです。

int main(int argc, char* argv[])
{
    
    
    // 初始化 SDL 库
    SDL_Init(SDL_INIT_VIDEO);

    // 创建窗口
    SDL_Window* window = SDL_CreateWindow("My Window",
                                          SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                                          640, 480, SDL_WINDOW_SHOWN);

    // 等待用户关闭窗口
    bool is_quit = false;
    SDL_Event event;
    while (!is_quit) {
    
    
        while (SDL_PollEvent(&event)) {
    
    
            if (event.type == SDL_QUIT) {
    
    
                is_quit = true;
            }
        }
    }

    // 释放窗口资源并退出 SDL 库
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

この例では、SDL ライブラリが初期化され、ウィンドウが作成され、ユーザーがウィンドウを閉じるのを待機するメイン ループが開始されます。ウィンドウを閉じた後、SDL_DestroyWindow 関数を呼び出してウィンドウ リソースを解放し、SDL_Quit 関数を呼び出して SDL アプリケーションを終了します。

SDL_CreateRenderer

SDL_CreateRenderer は、SDL レンダラー (レンダリング コンテキスト) を作成する関数であり、次のように定義されています。

SDL_Renderer* SDL_CreateRenderer(SDL_Window* window, int index, Uint32 flags)

パラメータの説明:

  • window: SDL ウィンドウ ポインター。作成されたレンダラー オブジェクトをウィンドウに関連付けるために使用されます。

  • Index: レンダラーのインデックス値。レンダラーの特定の実装を決定します。デフォルトのレンダラーを使用するには、-1 を渡すことができます。

  • flags: レンダラの設定オプション。レンダリング モード、ハードウェア アクセラレーション、バッファ モードなどを設定できます。0 を渡すと、ソフトウェア レンダリングのみをサポートし、ハードウェア アクセラレーションを使用しないレンダラー オブジェクトを作成することを意味します。

    SDL_RENDERER_SOFTWARE        // 兼容性模式,使用软件渲染
    SDL_RENDERER_ACCELERATED     // 硬件加速模式,充分利用GPU的硬件加速功能
    SDL_RENDERER_PRESENTVSYNC    // 垂直同步模式,来防止画面撕裂
    SDL_RENDERER_TARGETTEXTURE   // 可以将渲染的内容保存到纹理中
    

    さまざまな状況のニーズに合わせて、ビットごとの OR 演算子を使用して|複数のオプションを組み合わせることができます。たとえば、ハードウェア アクセラレーションと vsync をサポートするレンダラーを作成するには、次のフラグを使用できます。

    int flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
    

    ニーズに応じて、すべての種類のフラグを使用する必要はないことに注意することが重要です。たとえば、テクスチャを頻繁に使用せず、リアルタイム VSync が必要ない場合は、デフォルトのソフトウェア レンダラーを使用しても問題ありません。

関数の戻り値は SDL_Renderer 型のポインターであり、レンダラー オブジェクトが正常に作成されたことを意味します。作成に失敗した場合は NULL を返します。

サンプルコード:

SDL_Window* window = SDL_CreateWindow("my window", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

上の例では、最初に SDL ウィンドウを作成し、次に SDL_CreateRenderer 関数を通じてレンダラ オブジェクトを作成し、パラメータでデフォルトのインデックス値とハードウェア アクセラレーション オプションを使用しました。作成後、このレンダラー オブジェクトを使用して SDL ウィンドウに描画できます。プログラムが正常に終了するように、プログラムの終了前に SDL_DestroyRenderer 関数を呼び出してレンダラー オブジェクトを解放する必要があることに注意してください。

SDL_DestroyRenderer

SDL_DestroyRenderer は、 SDL2 でレンダラーを破棄するために使用される関数です。レンダラーが必要なくなったら、メモリを解放してプログラム リークを回避するために、SDL_DestroyRenderer 関数を呼び出してレンダラーを破棄する必要があります。SDL_DestroyRenderer 関数の関数プロトタイプは次のとおりです。

void SDL_DestroyRenderer(SDL_Renderer* renderer)

関数パラメータは、renderer破棄する必要があるレンダラ ポインタです。この関数を使用すると、プログラムはレンダラーとそのすべてのリソースをメモリから削除し、レンダラーへの参照を使用できなくなります。

SDL_SetRenderDrawColor

SDL_SetRenderDrawColor は、SDL2 レンダラーの描画色を設定する

関数プロトタイプ:

int SDL_SetRenderDrawColor(SDL_Renderer* renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a);

パラメータの説明:

  • レンダラー: レンダラーポインタ。
  • r: 赤チャンネル、範囲は 0 ~ 255 です。
  • g: 緑チャンネル、範囲は 0 ~ 255 です。
  • b: 青チャンネル、範囲は 0 ~ 255 です。
  • a: アルファ チャネル、範囲は 0 ~ 255、0 は完全に透明、255 は完全に不透明を意味します。

機能の役割:

レンダラーのペイント カラーを設定します。これは、次のペイントで使用される色です。たとえば、描画色を赤 (r=255、g=0、b=0、a=255) に設定した場合、次に SDL_RenderDrawRect を呼び出すと、赤い四角形が描画されます。

注: ペイント カラーの設定は、ペイントに使用する色を決定するだけであり、実際にペイントを行うわけではありません。設定した色でレンダーターゲットに描画するには、描画関数(SDL_RenderDrawLine、SDL_RenderDrawRectなど)を呼び出す必要があります。

例:

SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // 将绘制颜色设置为红色
SDL_RenderDrawRect(renderer, &rect); // 使用红色绘制矩形

このコードは、レンダラーの描画色を赤に設定し、SDL_RenderDrawRect 関数を使用して赤い四角形を描画します。この描画操作は、SDL_RenderPresent 関数を呼び出した後に画面に表示されます。

SDL_RenderClear

これは、設定された色 (デフォルトの黒) を使用してレンダー ターゲットを「クリア」することです。まずレンダー ターゲット内のすべてのカラーをクリアしてから、描画したカラーでレンダー ターゲットを塗りつぶしていることがわかります。ブラシとも言えますが、設定した色で描画対象全体を塗りつぶす非常に特殊なブラシです。

サンプルコードは次のとおりです。

SDL_Window* window = SDL_CreateWindow("SDL Render Clear Example",
                                      SDL_WINDOWPOS_CENTERED,
                                      SDL_WINDOWPOS_CENTERED,
                                      640, 480,
                                      SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

/SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);//设置绘制颜色,白色
SDL_RenderClear(renderer);// 清空渲染目标,不指定绘制颜色的话,默认为黑色,由于上述设置,所以填充为白色

// 设置颜色为红色
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

// 绘制一个矩形
SDL_Rect rect = {
    
    100, 100, 200, 200};
SDL_RenderFillRect(renderer, &rect);

// 更新屏幕
SDL_RenderPresent(renderer);

SDL_Delay(2000);

SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);

上記のサンプル コードは、ウィンドウとハードウェア アクセラレータ レンダラー オブジェクトを作成し、関数を呼び出してSDL_RenderClearレンダー ターゲットをクリアし、色を赤に設定して、画面上に四角形を描画します。最後に、SDL_RenderPresent関数を呼び出して画面表示を更新すると、描画結果が表示され、白い画面に赤い四角形が描画されます実行後、レンダラーとウィンドウを破棄し、対応するリソースを解放します。

SDL_CreateTexture

SDL_CreateTextureSDL2 で(テクスチャオブジェクト)を作成するSDL_Textureために使用される関数で、既存のSDL_Rendererフォーマットと指定されたフォーマットから作成され、幅と高さをレンダリングします。この関数のプロトタイプは次のとおりです。

SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer, Uint32 format, int access, int w, int h); 

パラメータリスト:

  • renderer:SDL_Rendererポインタ、SDL_Texture作成時に使用されるレンダラー。

  • format:Uint32テクスチャ ピクセル形式 (つまり、各ピクセルが何バイト表現する必要があるか) を指定するために使用されます。SDL では、RGB、RGBA、ARGB、BGR、BGRA、ABGR などのさまざまなピクセル形式が提供されます。その中で最も一般的なのは RGBA 形式で、赤、緑、青、アルファ (透明度) を表す各ピクセルを 4 バイトで表します。;

    Uint32 textureFormat = SDL_PIXELFORMAT_RGBA8888;
    SDL_Texture* texture = SDL_CreateTexture(renderer, textureFormat, SDL_TEXTUREACCESS_STREAMING, 640, 480);
    

    その中には、SDL_PIXELFORMAT_RGBA8888SDL でサポートされている 32 ビット RGBA ピクセル形式の 1 つが含まれます。これは、各ピクセルが 4 オクテット コンポーネントで構成され、順序がそれぞれ赤、緑、青、アルファ コンポーネントであることを意味します。textureFormatに設定するSDL_PIXELFORMAT_RGBA8888、画面上に透明度のある画像を描画する RGBA8888 テクスチャを作成できます。

  • access: int、作成したテクスチャのアクセス方法を指定します。テクスチャのアクセス方法を指定します。次のオプションがあります。

    • SDL_TEXTUREACCESS_STATIC: テクスチャはビデオ メモリに固定的に割り当てられ、変更できません。
    • SDL_TEXTUREACCESS_STREAMING: テクスチャは頻繁な更新に使用されます。ビデオメモリはCPUと共有されており、ロック/ロック解除操作によって実行できます。
    • SDL_TEXTUREACCESS_TARGET: テクスチャをレンダリング ターゲットとして使用し、他のテクスチャやウィンドウに貼り付けることができます。
  • w: int、作成されたテクスチャの幅。

  • h: int、テクスチャが作成される高さ。

戻り値: 作成が失敗した場合は NULL を返し、それ以外の場合はSDL_Textureポインタを返します。

SDL_UpdateTexture

SDL_UpdateTexture() は、 SDL2 でテクスチャを更新するために使用される関数です。ビットマップ コンテンツを作成されたテクスチャにコピーするために使用されます。テクスチャが更新されるたびに、テクスチャ全体が置き換えられます。部分的に更新するには、SDL_UpdateTextureRect()を使用します。

関数プロトタイプ:

int SDL_UpdateTexture(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)

パラメータ分析:

  • texture : 更新するテクスチャへのポインタ。
  • ect : 更新されたテクスチャの長方形の領域。NULL の場合、デフォルトはテクスチャ全体です。
  • ピクセル: テクスチャにコピーされるピクセル データへのポインタ。
  • ピッチ: バイト単位のピクセルデータの長さ。

戻り値:

  • 成功した場合は 0 を返し、それ以外の場合は -1 を返し、SDL_GetError() のエラー メッセージを設定します。

** SDL_CreateTexture() でテクスチャを作成する場合は、SDL_TEXTUREACCESS_STREAMING フラグを使用する必要があります。これにより、動的な変更を伴うテクスチャを使用する必要があることが SDL に通知されます。**これは、画像を更新するために SDL_UpdateTexture() 関数を繰り返し呼び出す必要がある可能性があることを意味します。一般的な使用例は、ストリーミング メディアまたはビデオです。

SDL_CreateTexture 関数の使用手順:

  1. テクスチャが静的な場合、つまり頻繁に更新する必要がない場合は、SDL_TEXTUREACCESS_STATIC アクセス メソッドを使用することをお勧めします。この方法により、テクスチャの描画速度を保証できます。
  2. テクスチャを頻繁に更新する必要がある場合は、テクスチャ コンテンツを更新するためのロック/ロック解除操作をサポートする SDL_TEXTUREACCESS_STREAMING アクセス メソッドを使用することをお勧めします。
  3. テクスチャをレンダリング ターゲットとして使用する必要がある場合は、SDL_TEXTUREACCESS_TARGET アクセス メソッドを使用することをお勧めします。このメソッドは、レンダリング ターゲットとしてのテクスチャの使用と、ウィンドウでのテクスチャの使用をサポートします。

**次の点に注意してください:** テクスチャを作成した後、SDL_DestroyTextureメモリ リークを避けるために、関数によってテクスチャを破棄する必要があります。

SDL_UpdateYUVTexture

SDL_UpdateYUVTexture() は、YUV 形式のテクスチャを更新するための SDL ライブラリの関数です。

関数のプロトタイプは次のとおりです。

int SDL_UpdateYUVTexture(SDL_Texture* texture, const SDL_Rect* rect, const Uint8* dataY, int pitchY, const Uint8* dataU, int pitchU, const Uint8* dataV, int pitchV)

パラメータの説明:

  • texture: 更新するテクスチャ。
  • rect: 更新される長方形の領域。NULL はテクスチャ全体を更新することを意味します。
  • dataY、dataU、dataV: YUV データ ポインター。
  • itchY、pitchU、pitchV: YUV データの行ごとのバイト数 (通常は幅)。

SDL_UpdateYUVTexture() 関数を使用すると、YUV データを SDL ウィンドウに更新して表示できます。

SDL_DestroyTexture

SDL_DestroyTexture は、 SDL2 でテクスチャを破棄するために使用される関数です。具体的な関数のプロトタイプは次のとおりです。

void SDL_DestroyTexture(SDL_Texture* texture)

パラメータの説明:

  • texture: 破壊するテクスチャ。

この関数を使用して、SDL_DestroyTextureテクスチャ オブジェクト自体や対応するビデオ メモリ リソースなど、テクスチャの作成時に使用されたリソースを解放します。テクスチャが時間内に破棄されない場合、プログラムは大量のリソースを使用して実行されるため、パフォーマンス上の問題が発生しやすくなります。

SDL_DestroyTexture を使用する場合:

通常、SDL_CreateTexture を使用してテクスチャを作成した後、終了する前に SDL_DestroyTexture によってテクスチャを破棄できます。多数のテクスチャが作成された場合、システムの動作効率を向上させるために、テクスチャが不要になったときにそれらを破棄する必要があります。

SDL_RenderDrawRect

SDL_RenderDrawRect 関数は、レンダー ターゲット上に四角形を描画できます。そのプロトタイプは次のとおりです。

int SDL_RenderDrawRect(SDL_Renderer* renderer, const SDL_Rect* rect);

その中には、描画された四角形を表す SDL_Rect 構造体ポインターであるrendererレンダラー ポインターがありますrectSDL_Rect 構造体には 4 つの整数変数が含まれており、それぞれ四角形の左上隅の座標、幅、高さを表します。

SDL_RenderDrawRect 関数を呼び出した後、レンダラーはレンダー ターゲット上のパラメータでrect指定された四角形を描画します。四角形の境界線は現在設定されている描画色で、塗りつぶされた領域は空です。

SDL_RenderFillRect

SDL_RenderFillRect 関数は、レンダー ターゲット上に塗りつぶし四角形を描画します使用するパラメータは SDL_RenderDrawRect に似ていますが、境界線を描画するだけでなく、描画された四角形が塗りつぶされる点が異なります。

そのプロトタイプは次のとおりです。

int SDL_RenderFillRect(SDL_Renderer* renderer, const SDL_Rect* rect);

その中には、描画された四角形を表す SDL_Rect 構造体ポインターであるrendererレンダラー ポインターがありますrect

rectSDL_RenderFillRect 関数を呼び出した後、レンダラーはパラメータで指定された塗りつぶされた四角形をレンダー ターゲット上に描画します。四角形の色は現在設定されている描画色になります。

SDL_RenderCopy

SDL_RenderCopy は、指定されたターゲット上にテクスチャをレンダリングするためにSDL2 で使用される関数ですその具体的な関数のプロトタイプは次のとおりです。

int SDL_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srcrect, const SDL_Rect* dstrect);

関数パラメータの説明:

  • renderer: レンダラー、レンダー ターゲットを指定するために使用されます。
  • texture: テクスチャ オブジェクト、つまりレンダリングされるテクスチャ。
  • srcrect: ソース四角形。テクスチャからレンダリングする部分を指定するために使用されます。NULL はすべてを意味します
  • dstrect: ターゲット四角形。レンダー ターゲット内の位置とサイズを指定するために使用されます。NULL はすべてを意味します

SDL_RenderCopy 関数を使用すると、指定したレンダー ターゲット上にテクスチャをレンダリングし、ターゲット四角形内のテクスチャの位置とサイズを指定できます。一般に、プログラムがテクスチャに基づいてイメージをレンダリングする場合、SDL_RenderCopy 関数を使用してテクスチャをレンダラーにレンダリングし、イメージ レンダリングの効果を実現できます。

SDL_RenderCopy の 4 つのパラメータをすべて指定する必要があることに注意してください。NULL が渡された場合、テクスチャのデフォルト値が使用されることを意味します。実際の使用プロセスでは、ソース四角形とターゲット四角形のデータ型を浮動小数点型に変換して拡大縮小や移動操作を容易にするなど、ソース四角形とターゲット四角形を指定する際にいくつかの工夫をすることができます。また、SDL_Rect 構造体のボリュームのクリッピング プロパティを使用して、テクスチャのローカル部分のみをレンダリングします

SDL_SetRenderTarget

SDL_SetRenderTargetSDL2のレンダリング対象(誰にレンダリングするか)を設定するための機能で、SDLではレンダリング対象はデフォルトのウィンドウでも作成したテクスチャでも構いません。

そのプロトタイプは次のとおりです。

int SDL_SetRenderTarget(SDL_Renderer*   renderer,
                        SDL_Texture*    texture);

パラメータリスト:

  • renderer:SDL_Rendererポインター。レンダー ターゲットによって使用されるレンダラーを設定します。
  • texture:SDL_Textureレンダリング ターゲットとして使用されるテクスチャへのポインタ。

NULL に設定するとtexture、レンダー ターゲットはデフォルトのウィンドウに復元されます。関数を使用するとSDL_SetRenderTarget、テクスチャをレンダー ターゲットとして設定し、このテクスチャ上に他のテクスチャやイメージをレンダリングできます。同時に、テクスチャに透明性を持たせることができるため、透明効果の実現が容易になります。

戻り値: 関数が正常に実行された場合は 0 を返し、それ以外の場合は -1 を返します。

SDL_SetRenderTarget 関数の使用:

  1. 関数を呼び出してSDL_CreateTextureテクスチャ オブジェクトを作成します。
  2. 関数を使用してSDL_SetRenderTarget、レンダリングするテクスチャを設定します。
  3. 他のレンダリング関数を使用して、イメージをテクスチャ上にレンダリングします。
  4. 関数を呼び出してSDL_RenderCopyテクスチャをウィンドウにレンダリングします。

レンダリング ターゲットが設定されている限り、レンダリングが終了する前にそれを使用しSDL_SetRenderTargetてレンダリング ターゲットをデフォルト ウィンドウに復元する必要があることに注意してください。そうしないと、その後のレンダリング イメージに問題が発生します。

SDL_RenderPresent

レンダーターゲットの表示を更新するために使用される関数。

関数プロトタイプ:

void SDL_RenderPresent(SDL_Renderer* renderer);

パラメータの説明:

  • レンダラー: レンダラーポインタ。

機能の役割:

現在のレンダリング ターゲット (通常は画面) 上の描画結果をディスプレイに更新します。つまり、最新の描画結果を表示するようにレンダラーを更新します

各レンダリング操作の後に、SDL_RenderPresent 関数を呼び出して、描画されたコンテンツを画面に表示する必要があります。この関数が呼び出されないと、プログラムは何も描画されません。

例:

// 绘制完所有的图像后,需要调用 SDL_RenderPresent 函数将绘制结果更新到屏幕上
SDL_RenderPresent(renderer);

このコードは、レンダラー上のすべての描画結果を画面に更新します。

SDL_AddTimer

SDL_AddTimer 関数は SDL のタイマー関数であり、コールバック関数の登録とタイマーの作成に使用されます

SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void* param);

パラメータの説明:

  • interval: タイマートリガー間隔(ミリ秒)
  • callback: タイマーがトリガーされたときにイベントを処理するために使用されるコールバック関数ポインター
  • param: コールバック関数のパラメータ。NULL にすることもできます。

戻り値:

  • 成功: タイマー ID を返します
  • 失敗: 0 を返す

間隔ごとにコールバックをトリガーし、渡しますparam

SDLイベント関連API

DL_Event は、システム内で発生するイベントを表すためにSDL ライブラリで使用されるデータ構造ですイベントには、キーボードのキーの押下、マウスの動き、ゲームパッドの動き、ウィンドウ イベントなどがあります。SDL_Event 構造には、イベントの種類、イベントの発生時期、およびイベント パラメーターに関する詳細が含まれています。

SDL_Event 構造体には次のメンバーがあります。

  • type: イベントのタイプを表す整数。
    • SDL_QUIT: ユーザーがウィンドウを閉じるか、キーボードの Alt + F4 キーまたは Cmd + Q キーの組み合わせを押したときにトリガーされる終了イベントを示します。
    • SDL_KEYDOWN / SDL_KEYUP: ユーザーがキーボードのキーを押すか離したときにトリガーされるキーボード キー イベントを示します。
    • SDL_MOUSEMOTION / SDL_MOUSEBUTTONDOWN / SDL_MOUSEBUTTONUP: ユーザーがマウスを動かしたり、マウス ボタンを押したり放したりするとトリガーされるマウス イベントを示します。
    • SDL_WINDOWEVENT: ウィンドウ サイズの変更、ウィンドウのフォーカスの取得または喪失など、ウィンドウの状態が変化したときにトリガーされるウィンドウ イベントを表します。
    • SDL_JOYAXISMOTION / SDL_JOYBALLMOTION / SDL_JOYHATMOTION / SDL_JOYBUTTONDOWN / SDL_JOYBUTTONUP / SDL_JOYDEVICEADDED / SDL_JOYDEVICEREMOVED: ハンドルの動き、ボタンの押し方、放し方など、ゲームパッドの状態が変化したときにトリガーされるゲームパッド イベントを示します。
    • SDL_CONTROLLERAXISMOTION / SDL_CONTROLLERBUTTONDOWN / SDL_CONTROLLERBUTTONUP / SDL_CONTROLLERDEVICEADDED / SDL_CONTROLLERDEVICEREMOVED: コントローラーの動き、ボタンの押し方、放し方など、コントローラーの状態が変化したときにトリガーされるコントローラー イベントを示します。
    • SDL_USEREVENT: ユーザー定義イベントを示します。このイベントは、アプリケーションが SDL_PushEvent 関数を呼び出してカスタム イベントをイベント キューに追加するときにトリガーされます。
  • timestamp: イベントの発生時刻を表すUint32型の値。
  • window: イベントが属する SDL_Window データ ポインタを示します。
  • key: キーボード イベントを表す SDL_KeyboardEvent データ構造。
  • motion: マウス移動イベントを表す SDL_MouseMotionEvent データ構造。
  • button: マウス ボタン イベントを表す SDL_MouseButtonEvent データ構造。
  • Wheel: マウス ホイール イベントを表す SDL_MouseWheelEvent データ構造。
  • jaxis: ゲームパッド軸の移動イベントを表す SDL_JoyAxisEvent データ構造体。
  • jball: ゲームパッドのボール移動イベントを表す SDL_JoyBallEvent データ構造。
  • jbutton: ゲームパッドのボタン イベントを表す SDL_JoyButtonEvent データ構造体。
  • jdevice: ゲームパッドデバイスイベントを表す SDL_JoyDeviceEvent データ構造。
  • caxis: ゲームパッド軸の移動イベントを表す SDL_ControllerAxisEvent データ構造体。
  • cbutton: ゲームパッドのボタン イベントを表す SDL_ControllerButtonEvent データ構造体。
  • cdevice: ゲームパッド デバイス イベントを表す SDL_ControllerDeviceEvent データ構造。
  • quit: 終了イベントを表す SDL_QuitEvent データ構造。
  • user: ユーザー定義イベントを表す SDL_UserEvent データ構造。

SDL_Event 構造データを処理することにより、アプリケーションはユーザー入力とシステム イベントを処理してインタラクティブな動作を生成できます。

SDL_PollEvent()

SDL_PollEvent() は、SDL イベント処理ライブラリの関数であり、イベント キューからイベントをポーリング (常にループ) して返すために使用されます。ユーザー入力のキャプチャ、ゲーム状態の制御などに使用できます。

SDL_PollEvent() 関数が呼び出されると、SDL イベント キューにイベントがあるかどうかを確認し、キューの先頭からイベントをポップして返します。イベント キューが空の場合、関数はすぐに 0 を返します。イベントが存在する場合、関数は 1 を返し、イベント構造体を指定された SDL_Event 構造体に書き込みます。イベントの種類に応じて、SDL_Event 構造体のさまざまなフィールドが入力されます。

以下は、マウス イベントのみを処理する単純な SDL_PollEvent() 関数の例です。

SDL_Event event;

while (SDL_PollEvent(&event)) {
    
    
    switch (event.type) {
    
    
        case SDL_MOUSEMOTION:
            // 处理鼠标移动事件
            break;
        case SDL_MOUSEBUTTONDOWN:
            // 处理鼠标按下事件
            break;
        case SDL_MOUSEBUTTONUP:
            // 处理鼠标释放事件
            break;
        default:
            break;
    }
}

SDL_PollEvent() 関数はイベント キューをポーリングするため、多くのリソースを消費せず、ループ内で繰り返し使用できます。ただし、イベント処理中に特定のタスクを実行すると、イベントのポーリングに遅延が発生する可能性があることに注意してください。

SDL_WaitEvent

SDL_WaitEvent() は、SDL イベント処理ライブラリの関数であり、次のイベントを待機して取得するために使用されますイベントが発生するまでプログラムの実行をブロックするために使用できます。

SDL_WaitEvent() 関数が呼び出されると、イベント キューにイベントがあるかどうかがチェックされます。イベント キューが空の場合、関数は現在のスレッドをブロックし、イベントの到着を待ちますキューにイベントがある場合、関数はイベントをデキューし、ゼロ以外の値を返します。SDL_PollEvent() とは異なり、ポーリングするイベントのタイプを指定する必要はありません。

以下は、QUIT イベントを待機して処理する単純な SDL_WaitEvent() 関数の例です。QUIT イベントは、ユーザーがウィンドウを閉じたか、プログラムが終了していることを示します。

SDL_Event event;

while (SDL_WaitEvent(&event)) {
    if (event.type == SDL_QUIT) {
        // 处理退出事件
        break;
    }
}

SDL_WaitEvent() 関数は現在のスレッドをブロックするため、イベントの待機時間が長すぎるとプログラムが停滞し、プログラムの実行に役立たないことに注意してください。ユーザー入力に応答する必要がある場合は SDL_WaitEvent() を使用し、イベントに応答する必要がない場合は SDL_PollEvent() を使用することをお勧めします。

SDLスレッド関連のAPI

メインスレッドとサブスレッド間の共有変数に対する相互排他的な操作のサンプルコード:


	#include <SDL.h>
	#include <stdio.h>
	
	SDL_mutex *mutex = NULL;
	SDL_cond *cond = NULL;
	
	int thread_work(void *arg) {
    
    
	
	  printf("Thread-2 Lock Mutex Start\n");
	  SDL_LockMutex(mutex);
	  printf("Thread-2 Lock Mutex Success\n");
	
	  printf("Thread-2 Working with Mutex\n");
	  sleep(4);
	
	  printf("Thread-2 Wait Condition Start\n");
	  SDL_CondWait(cond, mutex);
	  printf("Thread-2 Wait Condition Success\n");
	
	  printf("Thread-2 Unlock Mutex\n");
	  SDL_UnlockMutex(mutex);
	
	  printf("Thread-2 Finish\n");
	
	  return 0;
	}
	
	#undef main
	int main() {
    
    
	
	  mutex = SDL_CreateMutex();
	  cond = SDL_CreateCond();
	
	  SDL_Thread *t = SDL_CreateThread(thread_work, "Thread-2", NULL);
	
	  printf("Thread-1 Working\n");
	  sleep(2);
	
	  printf("Thread-1 Lock Mutex Start\n");
	  SDL_LockMutex(mutex);
	  printf("Thread-1 Lock Mutex Success\n");
	
	  printf("Thread-1 Working with Mutex\n");
	  sleep(2);
	
	  printf("Thread-1 Send Condition Signal\n");
	  SDL_CondSignal(cond);
	
	  printf("Thread-1 Working with Mutex\n");
	  sleep(2);
	
	  printf("Thread-1 Unlock Mutex\n");
	  SDL_UnlockMutex(mutex);
	
	  printf("Thread-1 Wait Thread-2 Finish Start\n");
	  SDL_WaitThread(t, NULL);
	  printf("Thread-1 Wait Thread-2 Finish Success\n");
	
	  printf("Thread-1 Destroy Mutex Start\n");
	  printf("Thread-1 Destroy Condition Start\n");
	  SDL_DestroyMutex(mutex);
	  SDL_DestroyCond(cond);
	  printf("Thread-1 Destroy Mutex Success\n");
	  printf("Thread-1 Destroy Condition Success\n");
	
	  return 0;
	}


SDL_CreateThread

SDL_CreateThread 関数は、新しいスレッドを作成するために使用されますそのプロトタイプは次のとおりです。

SDL_Thread* SDL_CreateThread(SDL_ThreadFunction fn, const char* name, void* data);

その中にはfnスレッドによって実行される関数があり、関数ポインタの定義は次のとおりです。

typedef int (*SDL_ThreadFunction)(void* data);

現在のスレッドのパラメータ データを指す void ポインタを受け取ります。

nameはスレッド名です。

dataスレッド関数に渡されるデータパラメータです。

SDL_CreateThread関数を呼び出すと、新しいスレッドが作成され、fnその中でパラメータで指定されたスレッド実行関数が実行されます。作成が完了すると、関数はスレッドの ID や名前などの情報を含む SDL_Thread 構造体へのポインタを返します。

サンプルコード:

// 线程执行函数,接收一个void指针作为参数
int threadFunc(void *data)
{
    
    
    // 要执行的线程任务
    return 0;
}

// 在主线程中创建一个新线程
SDL_Thread* thread = SDL_CreateThread(threadFunc, "MyThread", NULL);

この例では、SDL_CreateThreadスレッド実行関数の実行に使用される関数を通じてメインスレッドに新しいスレッドを作成しますthreadFuncこの例では、関数はパラメータを渡さないため、最後の NULL はデータ パラメータが渡されないことを意味します。

SDL_WaitThread

SDL_WaitThread は、SDL ライブラリが提供するスレッド待機関数で、指定されたスレッドの実行が完了するのを待ちます関数のプロトタイプは次のとおりです。

int SDL_WaitThread(SDL_Thread* thread, int* status);

この関数の最初のパラメータは、待機するスレッドを示す SDL_Thread 型のポインタです。2 番目のパラメータは、スレッドの終了ステータスを格納するために使用される整数ポインタです。関数からの戻り値 0 はスレッドが正常に終了したことを示し、それ以外の値はエラーを示します。

SDL_WaitThread 関数は、現在のスレッドを一時停止し、指定されたスレッドの実行が完了するまで待機し、指定されたスレッドの戻りステータスを受け取ります。スレッドがすでに終了している場合、関数はすぐに戻り、ステータス ポインタが指すメモリにスレッドの終了ステータスを保存します。

SDL_CreateMutex

SDL_CreateMutex() は、ミューテックスを作成するための SDL ライブラリ内の関数ですMutex は共有リソースを保護するために使用される同期プリミティブで、データの競合や同時実行の問題を回避するために、一度に 1 つのスレッドだけが共有リソースにアクセスするようにすることができます。

SDL_CreateMutex() の関数プロトタイプは次のとおりです。

SDL_mutex* SDL_CreateMutex(void)

この関数はパラメータを取りません。新しく作成されたミューテックス (SDL_mutex* タイプ) へのポインタを返します。作成が失敗した場合は、NULL を返します。

SDL_LockMutex

SDL_LockMutex() は、ミューテックス (mutex) をロックするための

SDL_LockMutex() の関数プロトタイプは次のとおりです。

int SDL_LockMutex(SDL_mutex* mutex)

この関数のパラメータはミューテックス ポインタ (SDL_mutex* 型) であり、関数は関数呼び出しの結果を表す整数値を返します。関数がミューテックスを正常にロックした場合は 0 を返し、それ以外の場合はエラー コードを返します。

スレッドが SDL_LockMutex() 関数を実行するとき、ミューテックスが現在他のスレッドによってロックされていない場合、スレッドは直ちにミューテックスを取得し、保護された共有リソースにアクセスできます。ミューテックスが現在別のスレッドによってロックされている場合、スレッドはブロックされ、ミューテックスが解放されてスレッドが取得できるようになるまで待機します。

ミューテックスを使用する場合は、「誰が適用して誰が解放するか」の原則に従う必要があることに注意してください。つまり、SDL_LockMutex() 関数を使用してミューテックスをロックするスレッドは、SDL_UnlockMutex() 関数を使用してミューテックスを解放する必要があります。共有リソースにアクセスした後のミューテックス そうしないと、他のスレッドが共有リソースにアクセスするためのロックを取得できなくなります。

以下は、SDL_LockMutex() 関数を使用してミューテックスをロックし、複数のスレッドでの共有リソースでの同時実行の問題を回避する方法を示す簡単なサンプル コードです。

#include <SDL.h>

// 定义一个全局变量作为共享的资源
int shared_data = 0;

SDL_mutex* mutex;

void some_function(void) {
    
    
    // 等待并锁定互斥锁
    SDL_LockMutex(mutex);

    // 访问受保护的共享资源
    shared_data += 1;

    // 解锁互斥锁
    SDL_UnlockMutex(mutex);
}

int main() {
    
    
    // 初始化SDL库
    SDL_Init(SDL_INIT_EVERYTHING);

    // 创建互斥锁
    mutex = SDL_CreateMutex();

    // 启动多个线程访问共享资源
    // ...

    // 最后释放互斥锁
    SDL_DestroyMutex(mutex);

    // 退出SDL库
    SDL_Quit();
    return 0;
}

SDL_UnlockMutex

SDL_LockMutex()は、ミューテックス(mutex)を解放するためにSDLライブラリで使用される

SDL_UnlockMutex関数の関数プロトタイプは次のとおりです。

int SDL_UnlockMutex(SDL_mutex* mutex);

SDL_DestroyMutex

SDL_LockMutex() は、SDL ライブラリでミューテックス (ミューテックス) を破棄するために使用される

SDL_DestroyMutex関数の関数プロトタイプは次のとおりです。

void SDL_DestroyMutex(SDL_mutex* mutex);

SDL_CreateCond

SDL_CreateCond() は、条件変数を作成するための SDL ライブラリ内の関数です条件変数は、スレッド間同期プリミティブであり、スレッドが実行を続行する前に別のスレッドが特定の条件を満たすのを待機できるようにするため、スレッドの実行順序と同時実行性をより適切に制御できます。

SDL_CreateCond() の関数プロトタイプは次のとおりです。

SDL_cond* SDL_CreateCond(void)

この関数にはパラメータがなく、新しく作成された条件変数へのポインタ (SDL_cond* 型) を返すか、作成が失敗した場合は NULL を返します。

SDL_CondSignal

SDL_CondSignal() は、条件変数を通知するための SDL ライブラリ内の関数です。

SDL_CondSignal() の関数プロトタイプは次のとおりです。

int SDL_CondSignal(SDL_cond* cond)

この関数のパラメータは条件変数 (SDL_cond* 型) へのポインタであり、関数は関数呼び出しの結果を表す整数値を返します。関数が条件変数の通知に成功した場合は 0 を返し、それ以外の場合はエラー コードを返します。

SDL_CondWait

SDL_CondWait()は、条件変数(条件変数)信号を待つためにSDLライブラリで使用される関数です。

DL_CondWait() 関数を使用すると、スレッドが条件変数を待機している間にミューテックスのロックを解除できるため、他のスレッドが共有リソースにアクセスし続けることができます。

SDL_CondWait() の関数プロトタイプは次のとおりです。

int SDL_CondWait(SDL_cond* cond, SDL_mutex* mutex)

この関数のパラメータは条件変数ポインタ(SDL_cond型)とミューテックスロックポインタ(SDL_mutex型)であり、関数呼び出しの結果を表す整数値を返します。条件変数がシグナルを正常に受信した場合は 0 を返し、それ以外の場合はエラー コードを返します。

スレッドが SDL_CondWait() 関数を呼び出すと、スレッドはまずミューテックスのロックを解除し (独自のロックを解除するため、SDL_CondWait 関数を使用する前にロックを取得する必要があります)、次にブロックして、条件変数 (SDL_CondSignal またはSDL_CondBroadcast) は、信号が条件変数に送信されるまで続きます。シグナル受信後にスレッドがウェイクアップすると、スレッドはミューテックスを再取得します(再取得とは取得を試みることで、他のスレッドがロックを解放しない場合、シグナルを受信して​​もダウンは実行されません)。共有リソースにアクセスします。

SDL_DestroyCond

SDL_DestroyCond() は、条件変数を破棄するための SDL ライブラリ内の関数です。

SDL_DestroyCond() の関数プロトタイプは次のとおりです。

void SDL_DestroyCond(SDL_cond* cond)

この関数の引数は条件変数ポインタ(SDL_cond*型)であり、戻り値はありません。条件変数を破棄するときは、その条件変数がどのスレッドによっても待機されていないことを確認してから解放する必要があります。

SDLオーディオAPI

オーディオを再生する基本的なプロセス

  1. オーディオデバイスを開く
  2. オーディオパラメータを設定する
  3. オーディオ コールバック関数を通じてサウンド カードのバッファにデータを充填します。
  4. オーディオを再生する
  5. デバイスの電源を切ります

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-a2a9Kbk1-1681661235964) (F:\vivo\records\audio and videodevelopment\pictures) \player\オーディオプレーヤー 簡単な処理.png)]

注意点は2か所

  • サウンド カードは、ユーザーがデータをサウンド カードに積極的にプッシュするのではなく、データを要求します。
  • データ量はオーディオパラメータによって決まります。

サウンド カードはデータを要求します。これは、サウンド カードが 1 秒あたりに再生するデータ量を計算できるためです。つまり、チャンネル数、サンプル数、およびサンプル数から 1 秒間に送信するデータ量を計算できるからです。すぐ。彼はデータが必要であることを伝える通知をコールバックし、それはあなたが作成したコールバック関数に転送されます。このコールバック関数では、サウンド カードによって指定されたバフにデータを入れる必要があり、サウンド カードはバフからデータを取得します。サウンドカードのデータバッファサイズはそれぞれ異なり、それぞれに一定の制限があり、一度に大量のデータをプッシュすると処理が困難になります。データを聞いてみませんか。必要なだけ入れてみましょう。

SDL_OpenAudio

オーディオ デバイスを開いてオーディオ処理を開始するために使用されますこの関数には次のプロトタイプがあります。

int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)

この関数は、予期されるオーディオ パラメータと実際に取得されたオーディオ パラメータの 2 つのパラメータを渡す必要があります。その中で、desired期待されるオーディオパラメータを指定することは、obtained実際のオーディオパラメータが取得されるか、

関数の戻り値は整数型で、成功の場合は 0、失敗の場合は -1 です。戻り値が -1 の場合は、SDL_GetError() 関数を呼び出してエラー メッセージを取得できます。

SDL_OpenAudio 関数を呼び出すと、SDL は必要なオーディオ デバイスを開いてオーディオ ストリームを作成しようとします。

SDL_OpenAudioDevice

SDL_OpenAudioDevice関数は、SDL オーディオ デバイスを開くために使用される関数であり、そのプロトタイプは次のとおりです。

SDL_AudioDeviceID SDL_OpenAudioDevice(
    						const char* device, 
    						int iscapture, 
    						const SDL_AudioSpec* desired, 
    						SDL_AudioSpec* obtained, 
    						int allowed_changes)

パラメータの説明:

  • device: 開くオーディオ デバイスの名前。NULL にすることもできます。これは、デフォルトのオーディオ デバイスを開くことを意味します。
  • iscapture: 録画デバイスであるかどうかを示します。0 の場合は再生デバイスの電源がオンになることを意味し、1 の場合は録音デバイスの電源がオンになることを意味します。
  • desired: 希望するオーディオ形式やサンプリングレートなどの情報。NULL の場合は、デフォルトのオーディオ形式、サンプリング レート、その他の情報を使用することを意味します。
  • 取得: 実際の音声フォーマットやサンプリングレートなどの情報を取得します。NULLの場合は、実際に取得した情報を取得する必要がないことを意味します。
  • allowed_changes: オーディオ形式やサンプリングレートなどの情報の変更が許可されています。0 の場合は変更が許可されていないことを意味し、-1 の場合はすべての変更が許可されていることを意味し、正の整数の場合は指定された数の変更が許可されていることを意味します。

戻り値はオーディオ デバイスの ID で、オーディオ デバイスを開いた結果を示します。0 が返された場合は、オーディオ デバイスのオープンに失敗したことを意味します。

この関数を使用して、マルチスレッド環境でオーディオデバイスを開きます。

SDL_CloseAudio

SDL_CloseAudio は、オーディオ デバイスを閉じるための SDL ライブラリの関数ですSDL_OpenAudio を使用してオーディオ デバイスを開いた後、オーディオ デバイスが不要になった場合、アプリケーションは SDL_CloseAudio 関数を呼び出してオーディオ デバイスを閉じることができます。関数のプロトタイプは次のとおりです。

void SDL_CloseAudio(void);

SDL によって使用されるすべてのオーディオ デバイスがプログラムの終了時に確実に閉じられるようにする必要がある場合は、プログラムが終了する前に SDL_CloseAudio 関数を呼び出すことができます。

SDL_CloseAudio 関数が呼び出されると、SDL ライブラリはオーディオの再生が完了するのを待ってオーディオ バッファをクリアしてから、オーディオ デバイスを閉じることに注意してください。したがって、SDL_CloseAudio 関数を呼び出した後、アプリケーションはプログラムを終了する前に、オーディオ バッファ内のデータが再生されるまで一定時間待機する必要がありますたとえば、SDL_Delay 関数を使用して、すべてのオーディオ データが再生されたことを確認するために終了する前に一定時間待機することができます。

SDL_CloseAudioDevice

SDL_CloseAudioDevice 関数は、SDL オーディオ デバイスを閉じるために使用される関数であり、そのプロトタイプは次のとおりです。

void SDL_CloseAudioDevice(SDL_AudioDeviceID dev);

パラメータの説明:

  • dev: オーディオ デバイスの ID。閉じるオーディオ デバイスを示します。

オーディオ デバイスを使用した後、SDL_CloseAudioDevice 関数を呼び出してオーディオ デバイスを閉じる必要があります。オーディオ デバイスが閉じられると、SDL はオーディオ データを取得するためにコールバック関数を呼び出すことがなくなり、オーディオ デバイスのバッファもクリアされます。

SDL_CloseAudioDevice 関数を呼び出す前に、SDL_PauseAudioDevice 関数を使用してオーディオ デバイスを一時停止し、オーディオ デバイスのバッファ内のオーディオ データをクリアする必要があることに注意してください。そうしないと、オーディオ デバイスのバッファーに未再生のオーディオ データがある場合、これらのオーディオ データは破棄され、データが失われます。

また、SDL_CloseAudioDevice関数を呼び出してオーディオデバイスを閉じる際、オーディオデバイスのバッファ内に未再生のオーディオデータがある場合、それらのオーディオデータも破棄されるので注意してください。したがって、オーディオ デバイスを閉じる前に、オーディオ デバイスがすべてのオーディオ データを再生するまで待つか、SDL_Delay 関数を使用して一定期間遅延させて、すべてのオーディオ データが確実に再生されるようにする必要があります。

SDL_一時停止オーディオ

SDL_PauseAudio は、オーディオ再生を一時停止または再開するためにSDL ライブラリで提供される関数ですこの関数のプロトタイプは次のとおりです。

void SDL_PauseAudio(int pause_on);

このうち、パラメータpause_onは整数であり、オーディオ再生を一時停止するかどうかを示します。値が 1 の場合は再生が一時停止されます (オーディオ デバイスの出力ストリームを一時停止します)。値が 0 の場合は再生が継続されます (入力用バッファーから音声データを継続的に取り出すことができます)

SDL_OpenAudio 関数を使用してオーディオ デバイスを開いた後、アプリケーションは SDL_PauseAudio 関数を呼び出してオーディオの再生を一時停止または再開できます。オーディオの再生が一時停止されると、オーディオ デバイスはバッファへのデータの充填を停止し、次の SDL_PauseAudio 関数の呼び出しを受信したときに再生を再開します。パラメータpause_onが0の場合、オーディオバッファ内のデータは一時停止されず、再生が再開されたときに最後の位置から再生を続けます。

たとえば、アプリケーションでオーディオを再生する必要があり、オーディオの再生中にユーザーが一時停止ボタンを押した場合、ユーザーが続行ボタンをクリックしたときに SDL_PauseAudio(1) 関数を呼び出してオーディオの再生を一時停止できます。 、SDL_PauseAudio(0) 関数を呼び出してオーディオ再生を再開できます。これにより、オーディオ再生の一時停止と再開の制御が可能になります。

SDL_PauseAudioDevice

SDL_PauseAudioDevice関数は、SDL オーディオ デバイスを開始または一時停止するために使用される関数であり、そのプロトタイプは次のとおりです。

void SDL_PauseAudioDevice(SDL_AudioDeviceID dev, int pause_on);

パラメータの説明:

  • dev: オーディオ デバイスの ID。開始または一時停止するオーディオ デバイスを示します。
  • 一時停止_オン: オーディオ デバイスを一時停止するかどうかを示します。0 の場合はオーディオ デバイスの開始を意味し、1 の場合はオーディオ デバイスの一時停止を意味します。

SDL_OpenAudioDevice 関数を使用してオーディオ デバイスを開いた後、SDL_PauseAudioDevice 関数を使用してオーディオ デバイスを開始または一時停止する必要があります。オーディオ デバイスが起動すると、SDL はコールバック関数の呼び出しを開始してオーディオ データを取得し、それをオーディオ デバイスのバッファに書き込みますオーディオ デバイスが一時停止されると、SDL はコールバック関数を呼び出さなくなり、オーディオ デバイスのバッファにはオーディオ データが書き込まれなくなります。

SDL_OpenAudioDevice 関数を使用してオーディオ デバイスを開いた後、オーディオ デバイスはデフォルトで一時停止状態になり、オーディオ デバイスを開始するには SDL_PauseAudioDevice 関数を使用する必要があることに注意してください。オーディオ デバイスを開始するために SDL_PauseAudioDevice 関数が呼び出されない場合、オーディオ デバイスはオーディオ データを再生しません。

また、SDL_PauseAudioDevice 関数を使用してオーディオ デバイスを一時停止する場合、オーディオ デバイスのバッファーに未再生のオーディオ データがある場合、それらのオーディオ データは破棄されることに注意してください。したがって、データの損失を避けるために、オーディオ デバイスを一時停止する前に、オーディオ デバイスのバッファ内のオーディオ データをクリアする必要があります。

SDL_MixAudio

SDL_MixAudio 関数は、SDL ライブラリのオーディオ処理関数** であり、主に 2 つのオーディオ バッファーのデータを混合するために使用されます**。(バッファ内のデータは、サウンド カードがデータを読み取りたいバッファにコピーされることがわかります)。関数は次のように定義されます。

void SDL_MixAudio(uint8_t *dst, const uint8_t *src, uint32_t len, int volume);

このうち、パラメータはdst、ミックスされたオーディオデータを格納するために使用されるターゲットバッファのポインタを示し、パラメータは、srcミックスされるオーディオデータを取得するために使用されるソースバッファのポインタを示し、パラメータは、len長さを示す処理されるデータのバイト単位; パラメータはvolume混合後のボリュームを示します。

SDL_MixAudio の主な機能は、2 つのバッファ内のオーディオ データを混合することです。これにより、複数の音源の混合を実現し、より良い音響効果を実現できます。特定の実装では、SDL_MixAudio は、指定されたボリュームに従ってソース バッファーのデータとターゲット バッファーのデータを混合し、混合結果をターゲット バッファーに保存します

SDL_MixAudio によって操作される 2 つのバッファのオーディオ データ形式は、サンプリング レート、チャンネル数、データ タイプを含めて一貫している必要があることに注意してください。さらに、ミキシング後の音量も、オーディオデータの品質の劣化や、システムが耐えられなくなるほどの過剰な出力音量を避けるために、特定のアプリケーションシナリオに応じて合理的に設定する必要があります。

オーディオコールバック関数

SDL オーディオ コールバック関数は、SDL オーディオ デバイスにオーディオ データを入力し、オーディオ再生を実現するために使用される特別なコールバック関数です。これはオーディオ ストリームを処理するための中心的なメカニズムであり、すべてのオーディオ デバイスはこのコールバック関数を使用してオーディオ データを入力し、オーディオ デバイスに出力する必要があります。

SDL オーディオ コールバック関数のプロトタイプは次のとおりです。

void (*SDL_AudioCallback)(void *userdata, Uint8 *stream, int len);

パラメータの説明:

  • userdata: コールバック関数のユーザー データ ポインター。追加のパラメーターをコールバック関数に渡すために使用されます。
  • stream: オーディオ デバイスにオーディオ データを埋めるために使用されるバッファへのポインタ。
  • len: 埋めるデータの長さ(単位: バイト)。

コールバック関数のメカニズムは次のとおりです。再生デバイスがオーディオ データを必要とする場合、SDL は登録されたコールバック関数を呼び出し、バッファ ポインタと埋められるデータの長さを渡しますデータを受信した後、コールバック関数は、データをバッファに迅速に埋め、制御権を SDL オーディオ システムに返し、埋められたオーディオ データを対応するオーディオ デバイスに出力できるようにする必要があります。

具体的には、コールバック関数は次のタスクを実行する必要があります。

  1. 「ユーザーデータ ポインター」から必要なデータを読み取ります。
  2. バッファに書き込むデータの量を計算します。通常は len を超えないようにしてください。
  3. 音声データをバッファに書き込みます。データが不足している場合は、不足しているデータの代わりに「サイレント」データを埋める必要があります。
  4. SDL オーディオ システムに制御を返します。

SDL では、コールバック関数の制限と要件がより厳しくなります。コールバック関数は、特別なスレッド (通常は SDL オーディオ スレッド) から呼び出す必要があります。さらに、コールバック関数は、SDL オーディオ システムの要求に時間内に応答するために、長時間にわたる計算やブロック操作を回避するように努める必要があります。

SDL_CreateMutex

SDL_CreateMutex は、ミューテックスを作成するためのSDL ライブラリ内の関数です

関数のプロトタイプは次のとおりです。

SDL_mutex* SDL_CreateMutex(void);

この関数は、ミューテックスへのアクセスに使用できる SDL_mutex 型のポインターを返します。ミューテックスの作成に失敗した場合は NULL を返します。

たとえば、ミューテックスを作成するには、次のコードを使用できます。

SDL_mutex* mutex = SDL_CreateMutex();
if (mutex == NULL) {
    
    
    // 创建互斥锁失败
} else {
    
    
    // 使用互斥锁
    // ...
    // 销毁互斥锁
    SDL_DestroyMutex(mutex);
}

使用後、SDL_DestroyMutex() 関数を呼び出してミューテックス オブジェクトを破棄する必要があります。

SDL_DestroyMutex

SDL_DestroyMutex は、ミューテックスを破棄するSDL ライブラリ内の関数です

関数のプロトタイプは次のとおりです。

void SDL_DestroyMutex(SDL_mutex* mutex);

関数パラメータは SDL_mutex 型のポインタで、破棄されるミューテックスを指します。ミューテックスを破棄する前に、そのミューテックスを使用しているスレッドがないことを確認する必要があります。

その他のAPI

SDL_遅延

DL_Delay は SDL ライブラリの関数で、プログラムを一定期間一時停止するために使用されます。この関数のプロトタイプは次のとおりです。

void SDL_Delay(Uint32 ms);

このうち、msパラメータはプログラムを一時停止する必要がある時間をミリ秒単位で示します。たとえば、パラメータが 1000 の場合、プログラムを 1 秒間一時停止する必要があることを意味します。関数が戻ると、プログラムは実行を再開します。

SDL_memset

SDL_memset 関数は、メモリ ブロック内の各バイトを指定された値に設定するために使用されます。関数は次のように定義されます。

void *SDL_memset(void *dst, int value, size_t len);

このうち、パラメータはdst設定する必要があるメモリ ブロックへのポインタです。パラメータはvalueメモリ ブロックの各バイトの設定に使用される値 (通常は 0 または 255) を示します。パラメータはlenメモリ ブロックのサイズ (バイト単位) を示します。 。

SDL関連の構造

SDL_Rect

SDL_Rect SDL2において長方形領域を定義する構造体であり、通常はウィンドウ内に長方形領域を定義するために使用されSDL_Rect次のように定義されています。

typedef struct SDL_Rect
{
    
    
    int x, y;
    int w, h;
} SDL_Rect;

このうち、 、xy長方形の左上隅の座標を表し、wh長方形の幅と高さを表します。次の図に示すように、これらを使用して長方形の領域を記述することができます。

SDL_Rectゲーム プログラミングでは、通常、ゲーム オブジェクトの位置とサイズを表すために使用します。SDL_Rectたとえば、次のように、プレーヤー キャラクターの長方形の領域を表す構造体を定義できます。

SDL_Rect playerRect = {
    
    0, 0, 50, 50};

上記の定義はプレイヤーキャラクターの長方形領域を表しており、左上隅の座標は(0,0)、長方形の幅と高さはともに50です。

SDL_テクスチャ

SDL_Textureテクスチャ オブジェクト (テクスチャ) を表すピクセル データを格納するために使用される構造体タイプですテクスチャ オブジェクトは、高速レンダリングに使用できる GPU メモリ内の事前レンダリングされたイメージです。

通常、ビットマップ (ビットマップ) または画像をメモリにロードし、テクスチャ オブジェクトとして作成します。次に、この関数を使用してSDL_RenderCopyそのテクスチャ オブジェクトをレンダー ターゲット上に描画し、必要に応じてアルファ ブレンディングやクリッピングなどを行うことができます。

SDL_Texture次のような多くのテクスチャ オブジェクトに必要な情報が含まれています。

  • wh: テクスチャの幅と高さ、つまりピクセル数を示します。
  • access: テクスチャのアクセス権を示します。テクスチャオブジェクトを使用する場合、SDL_QueryTexture最初に関数を呼び出してアクセス権を取得する必要があります。より一般的に使用される権限はSDL_TEXTUREACCESS_STATIC、(静的アクセス、読み取りのみ可能) とSDL_TEXTUREACCESS_STREAMING(ストリーミング アクセス、読み取りおよび書き込み可能) です。
  • format: RGBA、BGRA、RGB などのテクスチャのピクセル形式を示します。
  • id: テクスチャ オブジェクトを識別するために使用される一意のゼロ以外の整数 ID。
  • renderer:このテクスチャ オブジェクトに対応するSDL_Rendererレンダラ (タイプ) へのポインタ。

SDL_ウィンドウ

SDL_Window は、メイン メモリに格納されるオブジェクトであるウィンドウの論理概念を表します。そのため、SDL API を呼び出してウィンドウを作成しても、ウィンドウは表示されません。

SDL_表面

SDL レンダリングの仕組み。つまり、SDL_Render オブジェクトにはビデオ バッファがあり、これを SDL_Surface と呼び、ピクセルに従って画像を保存します通常、トゥルーカラー ピクセルを RGB24 データと呼びます。つまり、各ピクセルは 24 ビットで構成され、各 8 ビットが色を表し、ピクセルの最終的な色は RGB の 3 色を混合することによって形成されます。

SDL_テクスチャ

SDL がテクスチャ オブジェクトと呼ぶものは、それがそのままのものです。

SDL_Texture は SDL_Surface に似ており、バッファでもあります。ただ、保存されるのは実際のピクセルデータではなく、保存された画像の説明情報ですこれらの記述情報は、OpenGL、D3D、または Metal などのテクノロジーを通じて GPU を動作させ、SDL_Surface と同じグラフィックスを描画し、より効率的です (GPU ハードウェアによって計算されるため)。

SDL_レンダー

SDL_Render はレンダラであり、メイン メモリ内のオブジェクトでもあります。レンダリング操作は実際には 2 つの段階に分かれています。

1. レンダリング段階。この段階で、ユーザーはさまざまなグラフィックを描画し、SDL_Surface または SDL_Texture にレンダリングできます。

2つ目は展示ステージ。SDL_Textureをデータとして参照し、OpenGL経由でGPUを動作させ、最終的にSDL_SurfceまたはSDL_Textureのデータをディスプレイに出力します。

SDL_オーディオスペック

SDL_AudioSpec は、SDL でオーディオ仕様を記述するために使用される構造体です。これには、SDL がオーディオ データを処理する方法を制御する一連のパラメータが含まれています構造は次のように定義されます。

typedef struct SDL_AudioSpec {
    
    
    int freq;                   // 采样率
    Uint16 format;              // 采样格式
    Uint8  channels;            // 声道数
    Uint8  silence;             // 静音值,用于表示需要填充到缓冲区中的静音值。
    Uint16 samples;             // 缓冲区中的采样数
    Uint16 padding;             // 对齐位。在有些系统上,需要严格对齐缓冲区指针
    Uint32 size;                // 缓冲区大小,单位是字节
    void (*callback)(void *userdata, Uint8 *stream, int len);  // 回调函数
    void *userdata;             // 回调函数参数
} SDL_AudioSpec;

パラメータの説明:

  • freq: サンプリング レート。1 秒あたりのサンプル数を示します。
  • format: サンプリング形式。各サンプリングポイントが占めるビット数と符号およびその他の情報を示します。たとえば、SDL でサポートされている形式には、S8、S16LSB、S16MSB、U16LSB、U16MSB、S32LSB、S32MSB などが含まれます。
  • チャネル: チャネルの数。サンプリングされたチャネルの数を示します。デュアルチャネル (2) またはモノラルチャネル (1) です。SDL では、1 ~ 65535 チャネルがサポートされます。一般に、バイノーラルはモノラルよりも相対的に立体的でリアルです。
  • 無音: 無音値。バッファーに入れる必要がある無音値を示すために使用されます。
  • サンプル: バッファ内のサンプル数。バッファが保持できるサンプルの数を示します。
  • パディング: アライメント ビット。この変数は、バッファ ポインタをどの値にアライメントする必要があるかを設定するために使用されます。システムが異なれば、要件も異なる場合があります。
  • size: バッファ サイズ (バイト単位)。
  • callback: バッファを埋めるために使用されるコールバック関数。SDL はこの関数を自動的に呼び出します。
  • userdata: コールバック関数のコンテキスト。追加のパラメーターをコールバック関数に渡すために使用されます。

SDL_AudioSpec 構造体は SDL のオーディオ処理の中核であり、オーディオ仕様のカスタマイズやオーディオ コールバック関数の実装に使用できます。開発者は、SDL_AudioSpec 構造体を入力して構成することで、オーディオ デバイスを制御および管理できます。

SDL_ミューテックス

SDL_mutex は相互排他ロックを意味し、 SDL ライブラリによって提供されるスレッド同期メカニズムであり、複数のスレッドが共有リソースにアクセスするときに相互排他と同期に使用されます。

SDL_mutex 構造体は SDL_mutex.h ヘッダー ファイルで定義されており、次のメンバーが含まれています。

typedef struct SDL_mutex {
    
    
    void *id;           // 同步机制的底层实现句柄,不同平台实现不同
} SDL_mutex;

SDL_Cond

SDL_Cond タイプは、スレッドの調整と対話のためのスレッド間同期プリミティブである条件変数を表します。条件変数を使用すると、1 つ以上のスレッドが条件が満たされるまで待機してから実行を続行できます。

参考

おすすめ

転載: blog.csdn.net/qq_38056514/article/details/130190866