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
14 class SampleGLView : public BGLView
15 {
16 public:
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
25 private:
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
37 class SampleGLWindow : public BDirectWindow
38 {
39 public:
40 SampleGLWindow(BRect frame, uint32 type);
41 ~SampleGLWindow();
42
43 virtual bool QuitRequested();
44 virtual void DirectConnected( direct_buffer_info *info );
45
46 private:
47 SampleGLView *theView;
48 BMessageRunner *updateRunner;
49 };
50
51
52 class SampleGLApp : public BApplication
53 {
54 public:
55 SampleGLApp();
56 private:
57 SampleGLWindow *theWindow;
58 };
59
60
SampleGLApp()61 SampleGLApp::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
SampleGLWindow(BRect frame,uint32 type)74 SampleGLWindow::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
~SampleGLWindow()99 SampleGLWindow::~SampleGLWindow()
100 {
101 delete updateRunner;
102 }
103
104
QuitRequested()105 bool SampleGLWindow::QuitRequested()
106 {
107 theView->EnableDirectMode(false);
108 be_app->PostMessage(B_QUIT_REQUESTED);
109 return true;
110 }
111
112
DirectConnected(direct_buffer_info * info)113 void SampleGLWindow::DirectConnected(direct_buffer_info *info)
114 {
115 theView->DirectConnected(info);
116 theView->EnableDirectMode(true);
117 }
118
119 // ----
120
SampleGLView(BRect frame,uint32 type)121 SampleGLView::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
AttachedToWindow(void)129 void SampleGLView::AttachedToWindow(void)
130 {
131 BGLView::AttachedToWindow();
132 LockGL();
133 gInit();
134 gReshape(width, height);
135 UnlockGL();
136 MakeFocus();
137 }
138
139
FrameResized(float newWidth,float newHeight)140 void 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
gInit(void)156 void 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
gDraw(float rotation)165 void 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
gReshape(int width,int height)218 void 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
Render(void)230 void SampleGLView::Render(void)
231 {
232 LockGL();
233 gDraw(rotate);
234 SwapBuffers();
235 UnlockGL();
236 }
237
MessageReceived(BMessage * msg)238 void 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
KeyDown(const char * bytes,int32 numBytes)252 void 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
main(int argc,char * argv[])271 int main(int argc, char *argv[])
272 {
273 SampleGLApp *app = new SampleGLApp;
274 app->Run();
275 delete app;
276 return 0;
277 }
278