1a8251cf6SPhilippe Houdoin // sample BGLView app from the Be Book, modified to stress direct mode support.
2a8251cf6SPhilippe Houdoin
3a8251cf6SPhilippe Houdoin
4a8251cf6SPhilippe Houdoin #include <stdio.h>
5a8251cf6SPhilippe Houdoin
6a8251cf6SPhilippe Houdoin #include <Application.h>
7a8251cf6SPhilippe Houdoin #include <DirectWindow.h>
8a8251cf6SPhilippe Houdoin #include <CheckBox.h>
9a8251cf6SPhilippe Houdoin #include <GLView.h>
10895eb46bSPhilippe Houdoin #include <GL/glu.h>
11895eb46bSPhilippe Houdoin
12895eb46bSPhilippe Houdoin #define REDRAW_MSG 'rdrw'
13a8251cf6SPhilippe Houdoin
14a8251cf6SPhilippe Houdoin class SampleGLView : public BGLView
15a8251cf6SPhilippe Houdoin {
16a8251cf6SPhilippe Houdoin public:
17a8251cf6SPhilippe Houdoin SampleGLView(BRect frame, uint32 type);
18a8251cf6SPhilippe Houdoin virtual void AttachedToWindow(void);
19a8251cf6SPhilippe Houdoin virtual void FrameResized(float newWidth, float newHeight);
20895eb46bSPhilippe Houdoin virtual void MessageReceived(BMessage * msg);
21*25f1f961SJackBurton virtual void KeyDown(const char* bytes, int32 numBytes);
22a8251cf6SPhilippe Houdoin
23a8251cf6SPhilippe Houdoin void Render(void);
24a8251cf6SPhilippe Houdoin
25a8251cf6SPhilippe Houdoin private:
26a8251cf6SPhilippe Houdoin void gInit(void);
27895eb46bSPhilippe Houdoin void gDraw(float rotation = 0);
28a8251cf6SPhilippe Houdoin void gReshape(int width, int height);
29a8251cf6SPhilippe Houdoin
30a8251cf6SPhilippe Houdoin float width;
31a8251cf6SPhilippe Houdoin float height;
32895eb46bSPhilippe Houdoin float rotate;
33a8251cf6SPhilippe Houdoin };
34a8251cf6SPhilippe Houdoin
35a8251cf6SPhilippe Houdoin
36a8251cf6SPhilippe Houdoin
37a8251cf6SPhilippe Houdoin class SampleGLWindow : public BDirectWindow
38a8251cf6SPhilippe Houdoin {
39a8251cf6SPhilippe Houdoin public:
40a8251cf6SPhilippe Houdoin SampleGLWindow(BRect frame, uint32 type);
41895eb46bSPhilippe Houdoin ~SampleGLWindow();
42895eb46bSPhilippe Houdoin
43a8251cf6SPhilippe Houdoin virtual bool QuitRequested();
44a8251cf6SPhilippe Houdoin virtual void DirectConnected( direct_buffer_info *info );
45a8251cf6SPhilippe Houdoin
46a8251cf6SPhilippe Houdoin private:
47a8251cf6SPhilippe Houdoin SampleGLView *theView;
48895eb46bSPhilippe Houdoin BMessageRunner *updateRunner;
49a8251cf6SPhilippe Houdoin };
50a8251cf6SPhilippe Houdoin
51a8251cf6SPhilippe Houdoin
52a8251cf6SPhilippe Houdoin class SampleGLApp : public BApplication
53a8251cf6SPhilippe Houdoin {
54a8251cf6SPhilippe Houdoin public:
55a8251cf6SPhilippe Houdoin SampleGLApp();
56a8251cf6SPhilippe Houdoin private:
57a8251cf6SPhilippe Houdoin SampleGLWindow *theWindow;
58a8251cf6SPhilippe Houdoin };
59a8251cf6SPhilippe Houdoin
60a8251cf6SPhilippe Houdoin
SampleGLApp()61a8251cf6SPhilippe Houdoin SampleGLApp::SampleGLApp()
62e2947e53SStephan Aßmus : BApplication("application/x-vnd.Haiku-GLDirectMode")
63a8251cf6SPhilippe Houdoin {
64a8251cf6SPhilippe Houdoin BRect windowRect;
65895eb46bSPhilippe Houdoin uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH;
66a8251cf6SPhilippe Houdoin
67a8251cf6SPhilippe Houdoin windowRect.Set(50, 50, 350, 350);
68a8251cf6SPhilippe Houdoin
69a8251cf6SPhilippe Houdoin theWindow = new SampleGLWindow(windowRect, type);
70a8251cf6SPhilippe Houdoin }
71a8251cf6SPhilippe Houdoin
72a8251cf6SPhilippe Houdoin
73a8251cf6SPhilippe Houdoin
SampleGLWindow(BRect frame,uint32 type)74a8251cf6SPhilippe Houdoin SampleGLWindow::SampleGLWindow(BRect frame, uint32 type)
750795ca4aSPhilippe Houdoin : BDirectWindow(frame, "GLDirectMode", B_TITLED_WINDOW, 0)
76a8251cf6SPhilippe Houdoin {
770795ca4aSPhilippe Houdoin float minWidth = 0.0f;
780795ca4aSPhilippe Houdoin float maxWidth = 0.0f;
790795ca4aSPhilippe Houdoin float minHeight = 0.0f;
800795ca4aSPhilippe Houdoin float maxHeight = 0.0f;
810795ca4aSPhilippe Houdoin
820795ca4aSPhilippe Houdoin GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
830795ca4aSPhilippe Houdoin SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight);
840795ca4aSPhilippe Houdoin
85a8251cf6SPhilippe Houdoin BRect r = Bounds();
86a8251cf6SPhilippe Houdoin
87a8251cf6SPhilippe Houdoin r.InsetBy(10, 10);
88a8251cf6SPhilippe Houdoin theView = new SampleGLView(r, type);
89a8251cf6SPhilippe Houdoin AddChild(theView);
90a8251cf6SPhilippe Houdoin Show();
91895eb46bSPhilippe Houdoin
92895eb46bSPhilippe Houdoin updateRunner = new BMessageRunner(BMessenger(theView),
93895eb46bSPhilippe Houdoin new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */);
94895eb46bSPhilippe Houdoin
95a8251cf6SPhilippe Houdoin theView->Render();
96a8251cf6SPhilippe Houdoin }
97a8251cf6SPhilippe Houdoin
98a8251cf6SPhilippe Houdoin
~SampleGLWindow()99895eb46bSPhilippe Houdoin SampleGLWindow::~SampleGLWindow()
100895eb46bSPhilippe Houdoin {
101895eb46bSPhilippe Houdoin delete updateRunner;
102895eb46bSPhilippe Houdoin }
103895eb46bSPhilippe Houdoin
104895eb46bSPhilippe Houdoin
QuitRequested()105a8251cf6SPhilippe Houdoin bool SampleGLWindow::QuitRequested()
106a8251cf6SPhilippe Houdoin {
107a8251cf6SPhilippe Houdoin theView->EnableDirectMode(false);
108a8251cf6SPhilippe Houdoin be_app->PostMessage(B_QUIT_REQUESTED);
109a8251cf6SPhilippe Houdoin return true;
110a8251cf6SPhilippe Houdoin }
111a8251cf6SPhilippe Houdoin
112a8251cf6SPhilippe Houdoin
DirectConnected(direct_buffer_info * info)113a8251cf6SPhilippe Houdoin void SampleGLWindow::DirectConnected(direct_buffer_info *info)
114a8251cf6SPhilippe Houdoin {
115a8251cf6SPhilippe Houdoin theView->DirectConnected(info);
116a8251cf6SPhilippe Houdoin theView->EnableDirectMode(true);
117a8251cf6SPhilippe Houdoin }
118a8251cf6SPhilippe Houdoin
119895eb46bSPhilippe Houdoin // ----
120a8251cf6SPhilippe Houdoin
SampleGLView(BRect frame,uint32 type)121a8251cf6SPhilippe Houdoin SampleGLView::SampleGLView(BRect frame, uint32 type)
122895eb46bSPhilippe Houdoin : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0)
123a8251cf6SPhilippe Houdoin {
124a8251cf6SPhilippe Houdoin width = frame.right-frame.left;
125a8251cf6SPhilippe Houdoin height = frame.bottom-frame.top;
126a8251cf6SPhilippe Houdoin }
127a8251cf6SPhilippe Houdoin
128a8251cf6SPhilippe Houdoin
AttachedToWindow(void)129a8251cf6SPhilippe Houdoin void SampleGLView::AttachedToWindow(void)
130a8251cf6SPhilippe Houdoin {
131a8251cf6SPhilippe Houdoin BGLView::AttachedToWindow();
1326dfe2237SStefano Ceccherini LockGL();
133a8251cf6SPhilippe Houdoin gInit();
134a8251cf6SPhilippe Houdoin gReshape(width, height);
135a8251cf6SPhilippe Houdoin UnlockGL();
136*25f1f961SJackBurton MakeFocus();
137a8251cf6SPhilippe Houdoin }
138a8251cf6SPhilippe Houdoin
139a8251cf6SPhilippe Houdoin
FrameResized(float newWidth,float newHeight)140a8251cf6SPhilippe Houdoin void SampleGLView::FrameResized(float newWidth, float newHeight)
141a8251cf6SPhilippe Houdoin {
142a8251cf6SPhilippe Houdoin BGLView::FrameResized(newWidth, newHeight);
143a8251cf6SPhilippe Houdoin
144a8251cf6SPhilippe Houdoin LockGL();
145a8251cf6SPhilippe Houdoin
146a8251cf6SPhilippe Houdoin width = newWidth;
147a8251cf6SPhilippe Houdoin height = newHeight;
148a8251cf6SPhilippe Houdoin
149a8251cf6SPhilippe Houdoin gReshape(width,height);
150a8251cf6SPhilippe Houdoin
151a8251cf6SPhilippe Houdoin UnlockGL();
152a8251cf6SPhilippe Houdoin Render();
153a8251cf6SPhilippe Houdoin }
154a8251cf6SPhilippe Houdoin
155a8251cf6SPhilippe Houdoin
gInit(void)156a8251cf6SPhilippe Houdoin void SampleGLView::gInit(void)
157a8251cf6SPhilippe Houdoin {
158a8251cf6SPhilippe Houdoin glClearColor(0.0, 0.0, 0.0, 0.0);
159895eb46bSPhilippe Houdoin glEnable(GL_DEPTH_TEST);
160895eb46bSPhilippe Houdoin glDepthMask(GL_TRUE);
161a8251cf6SPhilippe Houdoin }
162a8251cf6SPhilippe Houdoin
163a8251cf6SPhilippe Houdoin
164a8251cf6SPhilippe Houdoin
gDraw(float rotation)165895eb46bSPhilippe Houdoin void SampleGLView::gDraw(float rotation)
166a8251cf6SPhilippe Houdoin {
167895eb46bSPhilippe Houdoin /* Clear the buffer, clear the matrix */
168895eb46bSPhilippe Houdoin glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
169895eb46bSPhilippe Houdoin glLoadIdentity();
170a8251cf6SPhilippe Houdoin
171895eb46bSPhilippe Houdoin /* A step backward, then spin the cube */
172895eb46bSPhilippe Houdoin glTranslatef(0, 0, -5);
173895eb46bSPhilippe Houdoin glRotatef(rotation, 0, 0, 1);
174895eb46bSPhilippe Houdoin glRotatef(rotation, 1, 0.6, 0);
175a8251cf6SPhilippe Houdoin
176895eb46bSPhilippe Houdoin /* We tell we want to draw quads */
177895eb46bSPhilippe Houdoin glBegin (GL_QUADS);
178a8251cf6SPhilippe Houdoin
179895eb46bSPhilippe Houdoin /* Every four calls to glVertex, a quad is drawn */
180895eb46bSPhilippe Houdoin glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
181895eb46bSPhilippe Houdoin glColor3f (0, 0, 1); glVertex3f (-1, -1, 1);
182895eb46bSPhilippe Houdoin glColor3f (0, 1, 1); glVertex3f (-1, 1, 1);
183895eb46bSPhilippe Houdoin glColor3f (0, 1, 0); glVertex3f (-1, 1, -1);
184a8251cf6SPhilippe Houdoin
185895eb46bSPhilippe Houdoin glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
186895eb46bSPhilippe Houdoin glColor3f (1, 0, 1); glVertex3f ( 1, -1, 1);
187895eb46bSPhilippe Houdoin glColor3f (1, 1, 1); glVertex3f ( 1, 1, 1);
188895eb46bSPhilippe Houdoin glColor3f (1, 1, 0); glVertex3f ( 1, 1, -1);
189a8251cf6SPhilippe Houdoin
190895eb46bSPhilippe Houdoin glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
191895eb46bSPhilippe Houdoin glColor3f (0, 0, 1); glVertex3f (-1, -1, 1);
192895eb46bSPhilippe Houdoin glColor3f (1, 0, 1); glVertex3f ( 1, -1, 1);
193895eb46bSPhilippe Houdoin glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
194a8251cf6SPhilippe Houdoin
195895eb46bSPhilippe Houdoin glColor3f (0, 1, 0); glVertex3f (-1, 1, -1);
196895eb46bSPhilippe Houdoin glColor3f (0, 1, 1); glVertex3f (-1, 1, 1);
197895eb46bSPhilippe Houdoin glColor3f (1, 1, 1); glVertex3f ( 1, 1, 1);
198895eb46bSPhilippe Houdoin glColor3f (1, 1, 0); glVertex3f ( 1, 1, -1);
199a8251cf6SPhilippe Houdoin
200895eb46bSPhilippe Houdoin glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
201895eb46bSPhilippe Houdoin glColor3f (0, 1, 0); glVertex3f (-1, 1, -1);
202895eb46bSPhilippe Houdoin glColor3f (1, 1, 0); glVertex3f ( 1, 1, -1);
203895eb46bSPhilippe Houdoin glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
204a8251cf6SPhilippe Houdoin
205895eb46bSPhilippe Houdoin glColor3f (0, 0, 1); glVertex3f (-1, -1, 1);
206895eb46bSPhilippe Houdoin glColor3f (0, 1, 1); glVertex3f (-1, 1, 1);
207895eb46bSPhilippe Houdoin glColor3f (1, 1, 1); glVertex3f ( 1, 1, 1);
208895eb46bSPhilippe Houdoin glColor3f (1, 0, 1); glVertex3f ( 1, -1, 1);
209a8251cf6SPhilippe Houdoin
210895eb46bSPhilippe Houdoin /* No more quads */
211a8251cf6SPhilippe Houdoin glEnd ();
212a8251cf6SPhilippe Houdoin
213895eb46bSPhilippe Houdoin /* End */
214895eb46bSPhilippe Houdoin glFlush ();
215a8251cf6SPhilippe Houdoin }
216a8251cf6SPhilippe Houdoin
217a8251cf6SPhilippe Houdoin
gReshape(int width,int height)218a8251cf6SPhilippe Houdoin void SampleGLView::gReshape(int width, int height)
219a8251cf6SPhilippe Houdoin {
220a8251cf6SPhilippe Houdoin glViewport(0, 0, width, height);
2210795ca4aSPhilippe Houdoin if (height) { // Avoid Divide By Zero error...
222a8251cf6SPhilippe Houdoin glMatrixMode(GL_PROJECTION);
223a8251cf6SPhilippe Houdoin glLoadIdentity();
224895eb46bSPhilippe Houdoin gluPerspective(45, width / (float) height, 1, 500);
225a8251cf6SPhilippe Houdoin glMatrixMode(GL_MODELVIEW);
226a8251cf6SPhilippe Houdoin }
2270795ca4aSPhilippe Houdoin }
228a8251cf6SPhilippe Houdoin
229a8251cf6SPhilippe Houdoin
Render(void)230a8251cf6SPhilippe Houdoin void SampleGLView::Render(void)
231a8251cf6SPhilippe Houdoin {
232a8251cf6SPhilippe Houdoin LockGL();
233895eb46bSPhilippe Houdoin gDraw(rotate);
234a8251cf6SPhilippe Houdoin SwapBuffers();
235a8251cf6SPhilippe Houdoin UnlockGL();
236a8251cf6SPhilippe Houdoin }
237a8251cf6SPhilippe Houdoin
MessageReceived(BMessage * msg)238895eb46bSPhilippe Houdoin void SampleGLView::MessageReceived(BMessage * msg)
239895eb46bSPhilippe Houdoin {
240895eb46bSPhilippe Houdoin switch (msg->what) {
241895eb46bSPhilippe Houdoin case REDRAW_MSG:
242895eb46bSPhilippe Houdoin Render();
243895eb46bSPhilippe Houdoin /* Rotate a bit more */
244895eb46bSPhilippe Houdoin rotate++;
245895eb46bSPhilippe Houdoin break;
246895eb46bSPhilippe Houdoin
247895eb46bSPhilippe Houdoin default:
248895eb46bSPhilippe Houdoin BGLView::MessageReceived(msg);
249895eb46bSPhilippe Houdoin }
250895eb46bSPhilippe Houdoin }
251895eb46bSPhilippe Houdoin
KeyDown(const char * bytes,int32 numBytes)252*25f1f961SJackBurton void SampleGLView::KeyDown(const char *bytes, int32 numBytes)
253*25f1f961SJackBurton {
254*25f1f961SJackBurton static bool moved = false;
255*25f1f961SJackBurton switch (bytes[0]) {
256*25f1f961SJackBurton case B_SPACE:
257*25f1f961SJackBurton if (moved) {
258*25f1f961SJackBurton MoveBy(-30, -30);
259*25f1f961SJackBurton moved = false;
260*25f1f961SJackBurton } else {
261*25f1f961SJackBurton MoveBy(30, 30);
262*25f1f961SJackBurton moved = true;
263*25f1f961SJackBurton }
264*25f1f961SJackBurton break;
265*25f1f961SJackBurton default:
266*25f1f961SJackBurton BView::KeyDown(bytes, numBytes);
267*25f1f961SJackBurton break;
268*25f1f961SJackBurton }
269*25f1f961SJackBurton }
270a8251cf6SPhilippe Houdoin
main(int argc,char * argv[])271a8251cf6SPhilippe Houdoin int main(int argc, char *argv[])
272a8251cf6SPhilippe Houdoin {
273a8251cf6SPhilippe Houdoin SampleGLApp *app = new SampleGLApp;
274a8251cf6SPhilippe Houdoin app->Run();
275a8251cf6SPhilippe Houdoin delete app;
276a8251cf6SPhilippe Houdoin return 0;
277a8251cf6SPhilippe Houdoin }
278