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