1// sample BGLView app from the Be Book, modified to stress direct mode support.
2
3
4#include <stdio.h>
5
6#include <Application.h>
7#include <DirectWindow.h>
8#include <CheckBox.h>
9#include <GLView.h>
10#include <GL/glu.h>
11
12#define REDRAW_MSG	'rdrw'
13
14class SampleGLView : public BGLView
15{
16public:
17   SampleGLView(BRect frame, uint32 type);
18   virtual void   AttachedToWindow(void);
19   virtual void   FrameResized(float newWidth, float newHeight);
20   virtual void   MessageReceived(BMessage * msg);
21   virtual void   KeyDown(const char* bytes, int32 numBytes);
22
23   void         Render(void);
24
25private:
26   void         gInit(void);
27   void         gDraw(float rotation = 0);
28   void         gReshape(int width, int height);
29
30   float        width;
31   float        height;
32   float		rotate;
33};
34
35
36
37class SampleGLWindow : public BDirectWindow
38{
39public:
40   SampleGLWindow(BRect frame, uint32 type);
41   ~SampleGLWindow();
42
43   virtual bool QuitRequested();
44   virtual void DirectConnected( direct_buffer_info *info );
45
46private:
47   SampleGLView   *theView;
48   BMessageRunner *updateRunner;
49};
50
51
52class SampleGLApp : public BApplication
53{
54public:
55   SampleGLApp();
56private:
57   SampleGLWindow      *theWindow;
58};
59
60
61SampleGLApp::SampleGLApp()
62   : BApplication("application/x-vnd.Haiku-GLDirectMode")
63{
64   BRect windowRect;
65   uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH;
66
67   windowRect.Set(50, 50, 350, 350);
68
69   theWindow = new SampleGLWindow(windowRect, type);
70}
71
72
73
74SampleGLWindow::SampleGLWindow(BRect frame, uint32 type)
75   : BDirectWindow(frame, "GLDirectMode", B_TITLED_WINDOW, 0)
76{
77   float minWidth = 0.0f;
78   float maxWidth = 0.0f;
79   float minHeight = 0.0f;
80   float maxHeight = 0.0f;
81
82   GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
83   SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight);
84
85   BRect r = Bounds();
86
87   r.InsetBy(10, 10);
88   theView = new SampleGLView(r, type);
89   AddChild(theView);
90   Show();
91
92   updateRunner = new BMessageRunner(BMessenger(theView),
93   		new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */);
94
95   theView->Render();
96}
97
98
99SampleGLWindow::~SampleGLWindow()
100{
101	delete updateRunner;
102}
103
104
105bool SampleGLWindow::QuitRequested()
106{
107	theView->EnableDirectMode(false);
108	be_app->PostMessage(B_QUIT_REQUESTED);
109	return true;
110}
111
112
113void SampleGLWindow::DirectConnected(direct_buffer_info *info)
114{
115	theView->DirectConnected(info);
116	theView->EnableDirectMode(true);
117}
118
119// ----
120
121SampleGLView::SampleGLView(BRect frame, uint32 type)
122   : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0)
123{
124   width = frame.right-frame.left;
125   height = frame.bottom-frame.top;
126}
127
128
129void SampleGLView::AttachedToWindow(void)
130{
131   BGLView::AttachedToWindow();
132   LockGL();
133   gInit();
134   gReshape(width, height);
135   UnlockGL();
136   MakeFocus();
137}
138
139
140void SampleGLView::FrameResized(float newWidth, float newHeight)
141{
142   BGLView::FrameResized(newWidth, newHeight);
143
144   LockGL();
145
146   width = newWidth;
147   height = newHeight;
148
149   gReshape(width,height);
150
151   UnlockGL();
152   Render();
153}
154
155
156void SampleGLView::gInit(void)
157{
158   glClearColor(0.0, 0.0, 0.0, 0.0);
159   glEnable(GL_DEPTH_TEST);
160   glDepthMask(GL_TRUE);
161}
162
163
164
165void SampleGLView::gDraw(float rotation)
166{
167  /* Clear the buffer, clear the matrix */
168  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
169  glLoadIdentity();
170
171  /* A step backward, then spin the cube */
172  glTranslatef(0, 0, -5);
173  glRotatef(rotation, 0, 0, 1);
174  glRotatef(rotation, 1, 0.6, 0);
175
176  /* We tell we want to draw quads */
177  glBegin (GL_QUADS);
178
179  /* Every four calls to glVertex, a quad is drawn */
180  glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
181  glColor3f (0, 0, 1); glVertex3f (-1, -1,  1);
182  glColor3f (0, 1, 1); glVertex3f (-1,  1,  1);
183  glColor3f (0, 1, 0); glVertex3f (-1,  1, -1);
184
185  glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
186  glColor3f (1, 0, 1); glVertex3f ( 1, -1,  1);
187  glColor3f (1, 1, 1); glVertex3f ( 1,  1,  1);
188  glColor3f (1, 1, 0); glVertex3f ( 1,  1, -1);
189
190  glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
191  glColor3f (0, 0, 1); glVertex3f (-1, -1,  1);
192  glColor3f (1, 0, 1); glVertex3f ( 1, -1,  1);
193  glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
194
195  glColor3f (0, 1, 0); glVertex3f (-1,  1, -1);
196  glColor3f (0, 1, 1); glVertex3f (-1,  1,  1);
197  glColor3f (1, 1, 1); glVertex3f ( 1,  1,  1);
198  glColor3f (1, 1, 0); glVertex3f ( 1,  1, -1);
199
200  glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
201  glColor3f (0, 1, 0); glVertex3f (-1,  1, -1);
202  glColor3f (1, 1, 0); glVertex3f ( 1,  1, -1);
203  glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
204
205  glColor3f (0, 0, 1); glVertex3f (-1, -1,  1);
206  glColor3f (0, 1, 1); glVertex3f (-1,  1,  1);
207  glColor3f (1, 1, 1); glVertex3f ( 1,  1,  1);
208  glColor3f (1, 0, 1); glVertex3f ( 1, -1,  1);
209
210  /* No more quads */
211  glEnd ();
212
213  /* End */
214  glFlush ();
215}
216
217
218void SampleGLView::gReshape(int width, int height)
219{
220   glViewport(0, 0, width, height);
221   if (height) {  // Avoid Divide By Zero error...
222      glMatrixMode(GL_PROJECTION);
223      glLoadIdentity();
224      gluPerspective(45, width / (float) height, 1, 500);
225      glMatrixMode(GL_MODELVIEW);
226   }
227}
228
229
230void SampleGLView::Render(void)
231{
232   LockGL();
233   gDraw(rotate);
234   SwapBuffers();
235   UnlockGL();
236}
237
238void SampleGLView::MessageReceived(BMessage * msg)
239{
240	switch (msg->what) {
241	case REDRAW_MSG:
242		Render();
243		/* Rotate a bit more */
244		rotate++;
245		break;
246
247	default:
248		BGLView::MessageReceived(msg);
249	}
250}
251
252void SampleGLView::KeyDown(const char *bytes, int32 numBytes)
253{
254	static bool moved = false;
255	switch (bytes[0]) {
256	case B_SPACE:
257		if (moved) {
258			MoveBy(-30, -30);
259			moved = false;
260		} else {
261			MoveBy(30, 30);
262			moved = true;
263		}
264		break;
265	default:
266		BView::KeyDown(bytes, numBytes);
267		break;
268	}
269}
270
271int main(int argc, char *argv[])
272{
273   SampleGLApp *app = new SampleGLApp;
274   app->Run();
275   delete app;
276   return 0;
277}
278