質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.36%

  • C

    4217questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4081questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Win32 API

    263questions

    Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

  • OpenGL

    187questions

    OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

WGLの初期化 プロシージャの記法について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 82

Weapon

score 48

前提・実現したいこと

stack overflow:How to make an OpenGL rendering context with transparent background?に記載されているコードを実行したところうまく動作しましたがWM_CREATEにおいて何も宣言されておらずほとんどの動作がWM_SIZEで記述されているところやグローバル変数で記述されている点を書き直してみましたがうまく動作しません.

1)glEnable等のgl関数の記述・初期化場所はあっていますか?
2)glEnableで有効化されているものは全部必要なのでしょうか?
3)何が原因で表示がされないのでしょうか?
4)WM_CREATEのCreateDIBSectionの第二引数でBITMAPHEADERINFO*BITMAPINFO*に変更していますがこれはBITMAPHEADERINFO*の頭のBITMAPINFO*を強引に入れたものでしょうか?
5)stack overflowのコードではassert.hでエラーチェック押しているようですが日本語ではあまり見かけない気がします.どんなメリットがあるのでしょうか?

該当のソースコード

#define UNICODE

#pragma comment(lib,"opengl32.lib")

#include <windows.h>
#include <gl/GL.h>

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);

const wchar_t CLASS_NAME[] = L"CLASS";

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR nCmdLine, int nCmdShow) {
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(nCmdLine);

    WNDCLASSEX wc = {
        sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW, WindowProc,
        0, 0, hInstance,
        NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(WHITE_BRUSH),
        NULL, CLASS_NAME, NULL
    };

    RegisterClassEx(&wc);

    HWND hwnd = CreateWindowEx(
        0, CLASS_NAME, L"Template", WS_OVERLAPPEDWINDOW,
        50, 50, 960, 525,
        NULL, NULL, hInstance, NULL
    );

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    MSG msg = {};

    while (GetMessage(&msg, NULL, 0, 0) != 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        static RECT rc;
        static int iwidth;
        static int iheight;
        static BITMAPINFOHEADER bih;
        static HDC pdcDIB;
        static HGLRC m_hrc;
    case WM_CREATE: 
    {
        GetClientRect(hwnd, &rc);
        iwidth = rc.right - rc.left;
        iheight = rc.bottom - rc.top;

        int iSize = sizeof(BITMAPINFOHEADER);
        memset(&bih, 0, iSize);

        bih.biSize = iSize;
        bih.biPlanes = 1;
        bih.biBitCount = 24;
        bih.biCompression = BI_RGB;
        bih.biWidth = iwidth;
        bih.biHeight = iheight;

        pdcDIB = CreateCompatibleDC(NULL);

        void* pv;
        HBITMAP hbmpDIB = CreateDIBSection(pdcDIB, (BITMAPINFO*)&bih, DIB_RGB_COLORS, &pv, NULL, 0);

        SelectObject(pdcDIB, hbmpDIB);


        /* CreateHGLRC */
        PIXELFORMATDESCRIPTOR pfd =
        {
            sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA, 32,
            0, 0, 0, 0, 0, 0, 0, 0,
            0,
            0, 0, 0, 0,
            24, //Number of bits for the depthbuffer
            8, //Number of bits for the stencilbuffer
            0, //Number of Aux buffers in the framebuffer.
            PFD_MAIN_PLANE,
            0,
            0, 0, 0
        };

        int format = ChoosePixelFormat(pdcDIB, &pfd);

        if (format == 0) {
            MessageBox(hwnd, L"pixel format error", L"Caution", MB_OK);
            return -1;
        }

        if (SetPixelFormat(pdcDIB, format, &pfd) == FALSE) {
            MessageBox(hwnd, L"Set error", L"Caution", MB_OK);
            return -1;
        }

        /* MakeCurrent */

        wglMakeCurrent(pdcDIB, m_hrc);

        /* init glfunc */
        glEnable(GL_ALPHA_TEST);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_COLOR_MATERIAL);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glClearColor(0, 0, 0, 0);

    }
        break;

    case WM_SIZE:
    {
        iwidth = LOWORD(lParam);
        iheight = HIWORD(lParam);
        glViewport(0, 0, iwidth, iheight);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        InvalidateRect(hwnd, NULL, TRUE);
    }


        break;

    case WM_PAINT:
    {
        PAINTSTRUCT ps = {};
        HDC hdc = BeginPaint(hwnd, &ps);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glPushMatrix();

        glColor3f(0, 1, 1);

        glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex3f(0.0f, 1.0f, 0.0f);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, 0.0f);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(1.0f, -1.0f, 0.0f);
        glEnd();

        glPopMatrix();
        glFlush();

        EndPaint(hwnd, &ps);
    }
    break;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}


ウィンドウの透過処理(WS_EX_RAYERED,SetLeyeredWindowAttribute)はしていません.

補足情報

Windows10 Pro
VisualStudio2017 Community

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

1)glEnable等のgl関数の記述・初期化場所はあっていますか?
3)何が原因で表示がされないのでしょうか?

合わせて回答します。元のソースから改変しすぎて、けっこう間違っています。

1.wglCreateContext を呼び出してください。

2.PIXELFORMATDESCRIPTOR の内容に誤りがあります。
PFD_DOUBLEBUFFER は不要です。これは OpenGL 側に裏画面を管理させる方法であるため、メモリ DC に対して指定してはなりません。
cColorBits メンバがメモリ DC で選択しているビットマップのビット数と一致していません。

3.WM_PAINT で OpenGL から HDC に対する描画処理が足りていません。
元のソースは裏画面(と一般的に呼ばれているもの)を OpenGL で更新しており、ウィンドウ側への反映は WM_PAINT で実施してあります。 wglMakecurrent で選択されているメモリ DC から BeginPaint で取得した ウィンドウ DC に対して単純に BitBlt してコピーしている部分が抜けています。

上記の修正でとりあえず動作するようにはなるはずです。
動作したら

他に動作には影響しませんが以下の問題があります。

・WM_SIZE
サイズ変更を考えないならすべての OpenGL 処理 WM_CREATE に移動するべきです。WM_SIZE でビューポートのサイズを設定しても、メモリビットマップのサイズが変更されていないため、正常には動作しません。
WM_SIZEの問題

・PIXELFORMATDESCRIPTOR
ステンシルバッファは使用していないので、cStencilBits は不要です。

・WM_DESTROY
WGL コンテキストの解放処理が抜けています。作成処理も抜けているのである意味問題ありませんが。

2)glEnableで有効化されているものは全部必要なのでしょうか?

描画内容によります。
提示されているコードで言うと GL_COLOR_MATERIAL と GL_BLEND の指定で問題ありません。
GL_COLOR_MATERIAL は頂点の色の指定に使用しています。
GL_BLEND は glBlendFunc で使用しています。
他は未使用です。

4)WM_CREATEのCreateDIBSectionの第二引数でBITMAPHEADERINFO*をBITMAPINFO*に変更していますがこれはBITMAPHEADERINFO*の頭のBITMAPINFO*を強引に入れたものでしょうか?

強引に入れたものかどうかという質問に対しては Yes となります。
それが可能な理由としては 24 ビットビットマップにおいては BITMAPINFO の bmiColors が使用されることはないため、その領域のメモリを確保する必要がないためです。

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER    bmiHeader;
    RGBQUAD             bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO; 

5)stack overflowのコードではassert.hでエラーチェック押しているようですが日本語ではあまり見かけない気がします.どんなメリットがあるのでしょうか?

ご自身で調べられた内容を記載した後、わからない部分を追記してください。
以前にも指摘した通り、1つの質問に複数のカテゴリの質問を混ぜると回答者が回答しづらい質問になります。異なるカテゴリの質問は質問を分けましょう。assert.h に関しては OpenGL タグも Win32 API タグも関係がありません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    4217questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4081questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Win32 API

    263questions

    Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

  • OpenGL

    187questions

    OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。