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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

OpenGL

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

Win32 API

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

C++

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

Q&A

解決済

1回答

1167閲覧

wglMakeCurrentの位置

Weapon

総合スコア106

C

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

OpenGL

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

Win32 API

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

C++

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

0グッド

0クリップ

投稿2019/03/11 08:02

前提・実現したいこと

メモリバッファを用いないOpenGL(WGL)のコードですがwglMakeCurrentを呼ぶタイミングについての質問です.
メインスレッドでwglCreateContext直後にwglMakeCurrentを呼ぶと関数は成功するのですがGL_INVALID_OPERATIONとなり描画されません.glBegin~glEnd内に不正な関数がある場合のエラーで関係ないと思いますが別スレッドのglBegin前でwglMakeCurrentを呼ばない成功します.wglMakeCurrentをその位置で呼ばないとと失敗する理由とは何でしょうか?

ちなみに両方で呼ぶとスレッド内でのwglMakeCurrentは失敗します.

発生している問題

100行目のwglMakeCurrent(コメントアウトしてあります)と
143行目のwglMakeCurrent

該当のソースコード

C

1#pragma comment(lib, "OpenGL32.lib") 2 3#define UNICODE 4 5#include <windows.h> 6#include <process.h> 7#include <gl/GL.h> 8#include <gl/GLU.h> 9 10#define TM_CREATE WM_APP + WM_CREATE 11#define TM_PAINT WM_APP + WM_PAINT 12#define TM_DESTROY WM_APP + WM_DESTROY 13 14const wchar_t CLASS_NAME[] = L"OpenGL Line"; 15 16HDC hdc; 17HGLRC glrc; 18HANDLE hgl; 19 20HWND hWnd; 21 22unsigned thId; 23 24LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMes, WPARAM wParam, LPARAM lParam); 25DWORD WINAPI GLLoop(LPDWORD lpdata); 26 27int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 28{ 29 UNREFERENCED_PARAMETER(hPrevInstance); 30 UNREFERENCED_PARAMETER(lpCmdLine); 31 32 33 WNDCLASSEX wcex = { 34 sizeof(WNDCLASSEX), CS_OWNDC | CS_HREDRAW | CS_VREDRAW, WindowProc, 0, 0, 35 hInstance, NULL, NULL, 36 (HBRUSH)GetStockObject(WHITE_BRUSH), NULL, CLASS_NAME, NULL 37 }; 38 39 if (!RegisterClassEx(&wcex))return 0; 40 41 RECT rc = { 0, 0, 640, 480 }; 42 if (!(hWnd = CreateWindowEx(0, CLASS_NAME, L"WGL Sample Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL)))return 0; 43 44 ShowWindow(hWnd, nCmdShow); 45 46 MSG msg = {}; 47 48 while (GetMessage(&msg, NULL, 0, 0) >= 0) { 49 TranslateMessage(&msg); 50 DispatchMessage(&msg); 51 } 52 53 return 0; 54} 55 56LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMes, WPARAM wParam, LPARAM lParam) { 57 switch (uMes) { 58 case WM_ERASEBKGND: 59 return -1; 60 61 case WM_CREATE: 62 { 63 PIXELFORMATDESCRIPTOR pfd = 64 { 65 sizeof(PIXELFORMATDESCRIPTOR), 66 1, 67 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 68 PFD_TYPE_RGBA, 69 32, 70 0, 0, 0, 0, 0, 0, 71 0, 72 0, 73 0, 74 0, 0, 0, 0, 75 24, 76 8, 77 0, 78 PFD_MAIN_PLANE, 79 0, 80 0, 0, 0 81 }; 82 83 hdc = GetDC(hwnd); 84 int format = ChoosePixelFormat(hdc, &pfd); 85 86 if (format == 0) { 87 MessageBox(hwnd, L"Format Error", L"Alert", MB_OK); 88 return -1; 89 } 90 91 if (!SetPixelFormat(hdc, format, &pfd)) { 92 MessageBox(hwnd, L"Set Pixel Error", L"Alert", MB_OK); 93 return -1; 94 } 95 96 glrc = wglCreateContext(hdc); 97 98 99 /* 100 101 どうやらここでwglMakeCurrentを呼ぶことがおかしい模様 102 103 if (!wglMakeCurrent(hdc, glrc)) { 104 MessageBox(hwnd, L"Make Current Error", L"Alert", MB_OK); 105 return -1; 106 } 107 108 */ 109 110 if ((hgl = (HANDLE)_beginthreadex(NULL, 0, (_beginthreadex_proc_type)GLLoop, NULL, 0, &thId)) == NULL) { 111 MessageBox(hwnd, L"Thread error", L"Caution", MB_OK); 112 return -1; 113 } 114 115 DWORD dwExCode; 116 while (GetExitCodeThread(hgl, &dwExCode) && dwExCode == STILL_ACTIVE && !PostThreadMessage(thId, WM_NULL, 0, 0))Sleep(1); 117 } 118 break; 119 120 case WM_PAINT: 121 PostThreadMessage(thId, TM_PAINT, 0, 0); 122 break; 123 124 case WM_DESTROY: 125 PostThreadMessage(thId, TM_DESTROY, 0, 0); 126 WaitForSingleObject(hgl, INFINITY); 127 PostQuitMessage(0); 128 return 0; 129 130 default: 131 return DefWindowProc(hwnd, uMes, wParam, lParam); 132 } 133} 134 135DWORD WINAPI GLLoop(LPDWORD lpdata) { 136 MSG tMsg = {}; 137 while (GetMessage(&tMsg, NULL, 0, 0) > 0) { 138 139 switch (tMsg.message) { 140 141 case TM_PAINT: 142 { 143 wglMakeCurrent(hdc, glrc); 144 145 glClearColor(0.0f, 0.5f, 1.0f, 1.0f); 146 glClear(GL_COLOR_BUFFER_BIT); 147 148 glBegin(GL_LINE_STRIP); 149 glVertex2f(0, 0); 150 glVertex2f(0.2, 0.9); 151 glVertex2f(0.4, -0.9); 152 glEnd(); 153 154 GLenum glen = glGetError(); 155 156 switch (glen) { 157 case GL_INVALID_ENUM: 158 MessageBox(hWnd, L"ENUM", L"GL ERROE", MB_OK); 159 break; 160 161 case GL_INVALID_OPERATION: 162 MessageBox(hWnd, L"OPERATION", L"GL ERROE", MB_OK); 163 break; 164 } 165 166 glFlush(); 167 SwapBuffers(hdc); 168 wglMakeCurrent(NULL, NULL); 169 } 170 break; 171 172 case TM_DESTROY: 173 wglMakeCurrent(NULL, NULL); 174 wglDeleteContext(glrc); 175 ReleaseDC(hWnd, hdc); 176 177 _endthreadex(0); 178 return 0; 179 } 180 181 } 182}

補足情報

Windows10 Pro
VisualStudio2017 Community

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

wglMakeCurrentを呼び出しているスレッドとその後のOpenGLのファンクションを呼び出しているスレッドが違うからではないですか。

wglMakeCurrentのリファレンスには、

The wglMakeCurrent function makes a specified OpenGL rendering context the calling thread's current rendering context.

と書かれていますし。
OpenGLをマルチスレッドで使用した事はありませんが、私だったらそう解釈します。

投稿2019/03/11 12:49

katsuko

総合スコア3469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

atata0319

2019/03/11 17:34 編集

これ以上投稿しても katsuko さんの補足にしかならないのでコメントに記載しますが、WGL のドキュメントにはレンダリングコンテキストはスレッド単位でしか処理できないことが明記されています。 https://docs.microsoft.com/ja-jp/windows/desktop/OpenGL/rendering-contexts さらに経験上、GetDC もスレッド側でやるのがおすすめになります。描画に関連する処理は丸々スレッド側ってことですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問