2010年6月1日火曜日

Cygwin+Opengl+Makefile

ここんところこんなのばっかですね。SDLもいいけど、結局Windows用とX用にそれぞれべた書きしたほうがシンプルでいいんじゃないかという気がしてきた。今win32apiのほうのウィンドウを作成しているところです。

まずは、ビルドしたいソースファイル一式。

main.cpp
01#include <windows.h>
02#include <GL/gl.h>
03#include "utilGL.hpp"
04 
05namespace
06{
07const char *APP_NAME = "Hoge";
08const int APP_W = 400;
09const int APP_H = 300;
10}
11 
12LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
13{
14   switch(msg)
15   {
16      case WM_DESTROY:
17         PostQuitMessage(0);
18         return 0;
19   }
20   return DefWindowProc(hWnd, msg, wp, lp);
21}
22 
23int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
24{
25   WNDCLASS wc;
26   memset(&wc, 0, sizeof(wc));
27   wc.lpfnWndProc   = MyWndProc;
28   wc.hInstance     = hInst;
29   wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
30   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
31   wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
32   wc.lpszClassName = APP_NAME;
33   if(!RegisterClass(&wc)) return -1;
34 
35   RECT r;
36   SetRect(&r, 0, 0, APP_W, APP_H);
37   AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
38    
39   HWND hWnd = CreateWindow(wc.lpszClassName, wc.lpszClassName,
40                            WS_OVERLAPPEDWINDOW,
41                            CW_USEDEFAULT, CW_USEDEFAULT,
42                            r.right - r.left, r.bottom - r.top,
43                            NULL, NULL, wc.hInstance, NULL);
44   ShowWindow(hWnd, SW_SHOW);
45   UpdateWindow(hWnd);
46 
47   while(true)
48   {
49      MSG msg;
50      while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0)
51      {
52         DispatchMessage(&msg);
53      }
54      if(msg.message == WM_QUIT) break;
55 
56 
57      HDC hdc = GetGLDC(hWnd);
58      glClear(GL_COLOR_BUFFER_BIT);
59      glBegin(GL_POLYGON);
60      glColor3f(1, 0, 0); glVertex2f(-0.8f, -0.8f);
61      glColor3f(0, 1, 0); glVertex2f( 0.8f,  0.8f);
62      glColor3f(0, 0, 1); glVertex2f( 0.8f, -0.8f);
63      glEnd();
64      glFlush();
65      SwapBuffers(hdc);
66      ReleaseGLDC(hWnd, hdc);
67   }
68   ExitGL();
69   return 0;
70}
utilGL.hpp
01#ifndef UTILGL_HPP_4bf0ab006de93374665ede990dbc4458
02#define UTILGL_HPP_4bf0ab006de93374665ede990dbc4458
03#include <windows.h>
04#include <GL/gl.h>
05 
06HDC GetGLDC(HWND hWnd);
07void ReleaseGLDC(HWND hWnd, HDC hdc);
08void ExitGL();
09 
10#endif//UTILGL_HPP_4bf0ab006de93374665ede990dbc4458
utilGL.cpp
01#include "utilGL.hpp"
02 
03static HGLRC hGLRC = NULL;
04 
05HDC GetGLDC(HWND hWnd)
06{
07   HDC hdc;
08   int pf;
09   static PIXELFORMATDESCRIPTOR pfd =
10      {
11         sizeof(PIXELFORMATDESCRIPTOR), 1,
12         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
13         PFD_TYPE_RGBA,
14         24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0,
15         PFD_MAIN_PLANE, 0, 0, 0, 0
16      };
17   hdc = GetDC(hWnd);
18   pf = ChoosePixelFormat(hdc, &pfd);
19   SetPixelFormat(hdc, pf, &pfd);
20   if(!hGLRC) hGLRC = wglCreateContext(hdc);
21   wglMakeCurrent(hdc, hGLRC);
22 
23   return hdc;
24}
25 
26void ReleaseGLDC(HWND hWnd, HDC hdc)
27{
28   wglMakeCurrent(hdc, 0);
29   ReleaseDC(hWnd, hdc);
30}
31 
32void ExitGL()
33{
34   if(!hGLRC) wglDeleteContext(hGLRC);
35}
Makefile
01program = glvertex
02srcs = $(wildcard *.cpp)
03objs = $(subst .cpp,.o,$(srcs))
04 
05CC := g++
06CPPFLAGS = -I /usr/include/opengl
07CXXFLAGS = -mno-cygwin
08LDFLAGS = -mno-cygwin -lopengl32 -lgdi32
09 
10$(program): $(objs)
11    @echo $(objs)
12    $(CXX) $^ $(LDFLAGS) $(OUTPUT_OPTION)
13 
14%.o: %.cpp
15    @echo $(srcs)
16    $(COMPILE.C) $<
17 
18.PHONY: clean
19 
20clean:
21    $(RM) $(program) $(objs) *~

以上4ファイル。


実行結果
さて、ここから覚え書き。

Makefileにある
$(CXX) $^ $(LDFLAGS) $(OUTPUT_OPTION)
ですが、こいつは展開されると、
g++ main.o utilGL.o -mno-cygwin -lopengl32 -lgdi32 -o glvertex
になります。

実はこの行、修正したものでして、修正前の状態だと
$(LINK.o) $^ $(OUTPUT_OPTION)
でした。これは、展開されると
$(CC) $(LDFLAGS) $(TARGET_ARCH) $(OUTPUT_OPTION)
g++ -mno-cygwin -lopengl32 -lgdi32 main.o utilGL.o -o glvertex
となり、リンクエラーを起こしてしまいます。原因はおそらく、リンクするオブジェクト(main.o utilGL.o)より前に-lopengl32 -lgdi32を書いてしまったことかと思います。


詳しくはよくわからないのですが、-lオプションをつけた依存ファイルは、ローカルの依存ファイル(main.o utilGL.o)より後ろに書いておくのが正解なようです。

参考サイト
Win32API+OpenGL(GLUTに頼らない方法)
GDI関係のライブラリ解決に役立った
GNU Make関数リファレンス
GNU Makeの使い方

0 件のコメント:

コメントを投稿