Super Graphics Library

Super Graphics Library(SGL)とは、VideoLogicが同社のPowerVR向けに開発した3D APIです。なお末期の公式マニュアルでは「PowerSGL」となっています。

同時期に登場したDirect3D (3.0および5.0)が非常に低レベルにポリゴンを1枚1枚を描画するものなのに対して、SGLはプリミティブ(3Dモデル)、マテリアル(テクスチャ)、カメラなどの要素を組み合わせて「シーン」を組み上げて一気にレンダリングする非常に高レベルなものでした。

SGLではテクスチャなどのリソースの管理も全自動化されていました。メモリリークの心配もなしです。

SGLは昨今の高レベルなゲーム開発向けのフレームワークゲームエンジンと比較しても遜色のない完成度であり、Direct3Dは3Dの深い知識がないとクソみたいなパフォーマンスしか出せないのに対して、SGLはポンコツプログラマーでも3D入門書レベルの知識でそこそこのパフォーマンスを発揮できるという特徴がありました。

ただSGLには「PowerVRでしか動かない」という絶望的な欠点がありました。 末期のPC-9821シリーズ向けのPC 3DEngine くらいしかビデオカードが存在しない状況ではどうにもなりませんでした。

その後 編集

後に「PowerVR SDK」としてOpenGL ESVulkanをバックエンドとしPowerVR以外でも利用できる普通のフレームワークになりました。UnityUE5などのゲームエンジンを使うと重すぎて無理すぎる超小型デバイスで人気があるようです。

簡単な使い方 編集

SGLの基本はviewportとcameraを作ってrenderを呼ぶだけです。バカみたいに簡単ですね。

void SetupScene() {
    device = sgl_create_screen_device(0, 640, 480, sgl_device_16bit, FALSE);
    viewport = sgl_create_viewport(device, 0, 0, 640, 480,100.0f, 0.0f, 580.0f, 480.0f);
    SetupCameras();
}

void SetupCameras(){
    sgl_create_list(UNAMED_ITEM,TRUE,FALSE);
        sgl_translate (0.0, 50.0f, -150.0f);
        camTran = sgl_create_transform(TRUE);
        camera  = sgl_create_camera (3.0f,10.0f,0.0f);
    sgl_to_parent();
}

void UpdateScene() {
    sgl_modify_transform (camTran, TRUE);
    sgl_translate (0.0,0.0, frame*5-150);
}

void DrawScene() {
    sgl_render(viewport, camera, TRUE);
}


SGLはEntity Component System(ECS)みたいな構造になっており、いわゆるオブジェクトは「リスト」と呼ばれる構造に格納されます。ECSでいうエンティティにコンポーネントを追加するのとほぼ同じです。カメラも背景もモデルも全部リストです。リストを作ってそれらしい要素を追加すると勝手に描画されます。

void SetupAmbient(){
    sgl_create_list(UNAMED_ITEM,TRUE,FALSE);
        sgl_set_fog(camera, Blue, 0.00075f);
        sgl_set_background_colour(camera,Blue);
    sgl_to_parent();
}

void SetupGround() {
    sgl_2d_vec uv1,  uv2,  uv3;
    sgl_vector groundPnt = {0.0f,-1.0f,  20.0f };	
    sgl_vector point2	 = {10.0f,-1.0f, 20.0f };	
    sgl_vector point3	 = {0.0f,-1.0f,  10.0f };	
    sgl_vector groundNrm = {0.0f,  1.0f, 0.0f };	
        
    /* UV vectors for texturing */
    uv1[0]=0.00f;
    uv1[1]=0.50f;
    
    uv2[0]=0.00f;
    uv2[1]=0.545f;

    uv3[0]=0.045f;
    uv3[1]=0.50f;

    sgl_create_list(UNAMED_ITEM,TRUE,FALSE);
        sgl_qual_generate_shadows (FALSE);
        sgl_set_texture_map       (GroundTex, TRUE, TRUE);
        sgl_set_ambient           (White);
        sgl_set_diffuse           (White); 
        sgl_set_opacity           (0.7f);
        sgl_set_texture_effect    (TRUE, TRUE, TRUE, FALSE);
        sgl_add_plane             (groundPnt,point2,point3, VISIBLE, NULL,NULL,NULL,uv1,uv2,uv3); 
    sgl_to_parent();
}

void SetupSky(void)
{
    sgl_2d_vec uv1,  uv2,  uv3;
    sgl_vector groundPnt = {0.0f,500.0f, 500.0f };	
    sgl_vector point2	 = {-120.0f,500.0f, 500.0f };	
    sgl_vector point3	 = {0.0f,500.0f, 620.0f };	

    uv1[0]=0.01f;
    uv1[1]=0.00f;

    uv2[0]=0.2f;
    uv2[1]=0.055f;

    uv3[0]=0.055f;
    uv3[1]=0.00f;

    sgl_create_list(UNAMED_ITEM,TRUE,FALSE);
        SkyTran = sgl_create_transform (NAMED_ITEM); 
        sgl_qual_generate_shadows  (FALSE);
        sgl_set_texture_map        (SkyTex,FALSE,FALSE);
        sgl_set_ambient            (White);
        sgl_set_specular           (Black, 0);
        sgl_set_glow               (White);
        sgl_set_diffuse            (Blue); 
        sgl_set_texture_effect     (TRUE, TRUE, TRUE, TRUE);            
        sgl_add_plane              (groundPnt,point2,point3, VISIBLE, NULL,NULL,NULL,uv1,uv2,uv3); 
    sgl_to_parent();
}