#include <stdio.h>
#include <Application.h>
#include <DirectWindow.h>
#include <CheckBox.h>
#include <GLView.h>
#include <GL/glu.h>
#define REDRAW_MSG 'rdrw'
class SampleGLView : public BGLView
{
public:
SampleGLView(BRect frame, uint32 type);
virtual void AttachedToWindow(void);
virtual void FrameResized(float newWidth, float newHeight);
virtual void MessageReceived(BMessage * msg);
virtual void KeyDown(const char* bytes, int32 numBytes);
void Render(void);
private:
void gInit(void);
void gDraw(float rotation = 0);
void gReshape(int width, int height);
float width;
float height;
float rotate;
};
class SampleGLWindow : public BDirectWindow
{
public:
SampleGLWindow(BRect frame, uint32 type);
~SampleGLWindow();
virtual bool QuitRequested();
virtual void DirectConnected( direct_buffer_info *info );
private:
SampleGLView *theView;
BMessageRunner *updateRunner;
};
class SampleGLApp : public BApplication
{
public:
SampleGLApp();
private:
SampleGLWindow *theWindow;
};
SampleGLApp::SampleGLApp()
: BApplication("application/x-vnd.Haiku-GLDirectMode")
{
BRect windowRect;
uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH;
windowRect.Set(50, 50, 350, 350);
theWindow = new SampleGLWindow(windowRect, type);
}
SampleGLWindow::SampleGLWindow(BRect frame, uint32 type)
: BDirectWindow(frame, "GLDirectMode", B_TITLED_WINDOW, 0)
{
float minWidth = 0.0f;
float maxWidth = 0.0f;
float minHeight = 0.0f;
float maxHeight = 0.0f;
GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight);
BRect r = Bounds();
r.InsetBy(10, 10);
theView = new SampleGLView(r, type);
AddChild(theView);
Show();
updateRunner = new BMessageRunner(BMessenger(theView),
new BMessage(REDRAW_MSG), 1000000/60 );
theView->Render();
}
SampleGLWindow::~SampleGLWindow()
{
delete updateRunner;
}
bool SampleGLWindow::QuitRequested()
{
theView->EnableDirectMode(false);
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
void SampleGLWindow::DirectConnected(direct_buffer_info *info)
{
theView->DirectConnected(info);
theView->EnableDirectMode(true);
}
SampleGLView::SampleGLView(BRect frame, uint32 type)
: BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0)
{
width = frame.right-frame.left;
height = frame.bottom-frame.top;
}
void SampleGLView::AttachedToWindow(void)
{
BGLView::AttachedToWindow();
LockGL();
gInit();
gReshape(width, height);
UnlockGL();
MakeFocus();
}
void SampleGLView::FrameResized(float newWidth, float newHeight)
{
BGLView::FrameResized(newWidth, newHeight);
LockGL();
width = newWidth;
height = newHeight;
gReshape(width,height);
UnlockGL();
Render();
}
void SampleGLView::gInit(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
}
void SampleGLView::gDraw(float rotation)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -5);
glRotatef(rotation, 0, 0, 1);
glRotatef(rotation, 1, 0.6, 0);
glBegin (GL_QUADS);
glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
glColor3f (0, 0, 1); glVertex3f (-1, -1, 1);
glColor3f (0, 1, 1); glVertex3f (-1, 1, 1);
glColor3f (0, 1, 0); glVertex3f (-1, 1, -1);
glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
glColor3f (1, 0, 1); glVertex3f ( 1, -1, 1);
glColor3f (1, 1, 1); glVertex3f ( 1, 1, 1);
glColor3f (1, 1, 0); glVertex3f ( 1, 1, -1);
glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
glColor3f (0, 0, 1); glVertex3f (-1, -1, 1);
glColor3f (1, 0, 1); glVertex3f ( 1, -1, 1);
glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
glColor3f (0, 1, 0); glVertex3f (-1, 1, -1);
glColor3f (0, 1, 1); glVertex3f (-1, 1, 1);
glColor3f (1, 1, 1); glVertex3f ( 1, 1, 1);
glColor3f (1, 1, 0); glVertex3f ( 1, 1, -1);
glColor3f (0, 0, 0); glVertex3f (-1, -1, -1);
glColor3f (0, 1, 0); glVertex3f (-1, 1, -1);
glColor3f (1, 1, 0); glVertex3f ( 1, 1, -1);
glColor3f (1, 0, 0); glVertex3f ( 1, -1, -1);
glColor3f (0, 0, 1); glVertex3f (-1, -1, 1);
glColor3f (0, 1, 1); glVertex3f (-1, 1, 1);
glColor3f (1, 1, 1); glVertex3f ( 1, 1, 1);
glColor3f (1, 0, 1); glVertex3f ( 1, -1, 1);
glEnd ();
glFlush ();
}
void SampleGLView::gReshape(int width, int height)
{
glViewport(0, 0, width, height);
if (height) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, width / (float) height, 1, 500);
glMatrixMode(GL_MODELVIEW);
}
}
void SampleGLView::Render(void)
{
LockGL();
gDraw(rotate);
SwapBuffers();
UnlockGL();
}
void SampleGLView::MessageReceived(BMessage * msg)
{
switch (msg->what) {
case REDRAW_MSG:
Render();
rotate++;
break;
default:
BGLView::MessageReceived(msg);
}
}
void SampleGLView::KeyDown(const char *bytes, int32 numBytes)
{
static bool moved = false;
switch (bytes[0]) {
case B_SPACE:
if (moved) {
MoveBy(-30, -30);
moved = false;
} else {
MoveBy(30, 30);
moved = true;
}
break;
default:
BView::KeyDown(bytes, numBytes);
break;
}
}
int main(int argc, char *argv[])
{
SampleGLApp *app = new SampleGLApp;
app->Run();
delete app;
return 0;
}