CB的global compiler settings -> compiler settings -> Other options 填-fexceptions
#defines填FREEGLUT_STATIC
link libraries加入libFreeGLUT.a libGLUI.a GlU32(GlU32.Lib) Gdi32(Gdi32.Lib) OpenGL32(OpenGL32.Lib) User32(User32.Lib) WinMM(WinMM.Lib)
多加一個libBox2D.a
main.cpp
#include "gluiDraw.h" #include "glui/GL/glui.h" #include "myBox2D.h" MyBox2D mybox2d; GluiDraw draw; GLint mainWindow; GLint winWidth = 640; GLint winHeight = 640; int tx, ty, tw, th; float viewCenterX=0,viewCenterY=0; GLUI *glui; int framePeriod = 16; float viewZoom = 1.0f; NeoVec2 mp,pre_mp; bool isMouseRightPressed = false; bool isMouseLeftPressed = false; void Resize(int32 newWidth, int32 newHeight) { winWidth = newWidth; winHeight = newHeight; GLUI_Master.get_viewport_area(&tx, &ty, &tw, &th); glViewport(tx, ty, tw, th); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float32 ratio = float32(tw) / float32(th); b2Vec2 extents(ratio * 25.0f, 25.0f); extents *= viewZoom; b2Vec2 lower(viewCenterX-extents.x,viewCenterY-extents.y); b2Vec2 upper(viewCenterX+extents.x,viewCenterY+extents.y); // L/R/B/T gluOrtho2D(lower.x, upper.x, lower.y, upper.y); } void Mouse(int button, int state, int x, int y) { // Use the mouse to move things around. if (button == GLUT_LEFT_BUTTON) { int specialKey = glutGetModifiers(); if (state == GLUT_DOWN) { if (specialKey == GLUT_ACTIVE_SHIFT) { // cout << "GLUT_LEFT_BUTTON click with SHIFT" << endl; } else { // cout << "GLUT_LEFT_BUTTON click" << endl; } } if (state == GLUT_UP) { // cout << "GLUT_LEFT_BUTTON release" << endl; } } else if (button == GLUT_RIGHT_BUTTON) { if (state == GLUT_DOWN) { isMouseRightPressed = true; // cout << "GLUT_RIGHT_BUTTON click" << endl; } if (state == GLUT_UP) { isMouseRightPressed = false; // cout << "GLUT_RIGHT_BUTTON release" << endl; } } } b2Vec2 ConvertScreenToWorld(int32 x, int32 y) { float32 u = x / float32(tw); float32 v = (th - y) / float32(th); float32 ratio = float32(tw) / float32(th); b2Vec2 extents(ratio * 25.0f, 25.0f); extents *= viewZoom; b2Vec2 lower(viewCenterX-extents.x,viewCenterY-extents.y); b2Vec2 upper(viewCenterX+extents.x,viewCenterY+extents.y); b2Vec2 p; p.x = (1.0f - u) * lower.x + u * upper.x; p.y = (1.0f - v) * lower.y + v * upper.y; return p; } void MouseMotion(int x, int y) { b2Vec2 p = ConvertScreenToWorld(x, y); if(isMouseRightPressed) { float distanceX = p.x - pre_mp.x; float distanceY = p.y - pre_mp.y; viewCenterX -= distanceX; viewCenterY -= distanceY; Resize(winWidth, winHeight); p = ConvertScreenToWorld(x, y); pre_mp.x = p.x; pre_mp.y = p.y; glutPostRedisplay(); //要求重畫視窗 } //cout << "Mouse clicked and x=" << mp.x << ",y=" << mp.y << endl; } void MouseWheel(int wheel, int direction, int x, int y) { B2_NOT_USED(wheel); B2_NOT_USED(x); B2_NOT_USED(y); if (direction > 0) { viewZoom /= 1.1f; } else { viewZoom *= 1.1f; } Resize(winWidth, winHeight); } void Keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; case 'a': mybox2d.m_bodies[2]->ApplyForce(b2Vec2(-400,0), mybox2d.m_bodies[2]->GetWorldPoint(b2Vec2(1,1))); break; case 'd': mybox2d.m_bodies[2]->ApplyForce(b2Vec2(400,0), mybox2d.m_bodies[2]->GetWorldPoint(b2Vec2(-1,1))); break; default: break; } } void KeyboardSpecial(int key, int x, int y) { B2_NOT_USED(x); B2_NOT_USED(y); switch (key) { case GLUT_ACTIVE_SHIFT: // Press left to pan left. case GLUT_KEY_LEFT: viewCenterX -= 0.5f; Resize(winWidth, winHeight); break; // Press right to pan right. case GLUT_KEY_RIGHT: viewCenterX += 0.5f; Resize(winWidth, winHeight); break; // Press down to pan down. case GLUT_KEY_DOWN: viewCenterY -= 0.5f; Resize(winWidth, winHeight); break; // Press up to pan up. case GLUT_KEY_UP: viewCenterY += 0.5f; Resize(winWidth, winHeight); break; } } void drawWholeBody(b2World* world,b2Body* m_bodies[]) { int32 bodyCount = world->GetBodyCount(); for(int number = 0; number < bodyCount; number++) //扣掉地面一個body { const b2Transform& xf = m_bodies[number]->GetTransform(); for (b2Fixture* fixture = m_bodies[number]->GetFixtureList();fixture; fixture = fixture->GetNext()) { switch (fixture->GetType()) { case b2Shape::e_circle: { b2CircleShape* circle = (b2CircleShape*)fixture->GetShape(); b2Vec2 center = b2Mul(xf, circle->m_p); float32 radius = circle->m_radius; b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f)); //還沒用到 draw.DrawSolidCircle(NeoVec2(center.x,center.y),radius,NeoVec2(axis.x,axis.y),NeoColor(1,1,1)); } break; case b2Shape::e_edge: { b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape(); b2Vec2 v1 = b2Mul(xf, edge->m_vertex1); b2Vec2 v2 = b2Mul(xf, edge->m_vertex2); draw.DrawLine(NeoVec2(v1.x,v1.y),NeoVec2(v2.x,v2.y),NeoColor(0,1,0)); } break; case b2Shape::e_chain: { b2ChainShape* chain = (b2ChainShape*)fixture->GetShape(); int32 count = chain->GetVertexCount(); const b2Vec2* vertices = chain->GetVertices(); b2Vec2 v1 = b2Mul(xf, vertices[0]); for (int32 i = 1; i < count; ++i) { b2Vec2 v2 = b2Mul(xf, vertices[i]); draw.DrawLine(NeoVec2(v1.x,v1.y),NeoVec2(v2.x,v2.y),NeoColor(1,1,1)); draw.DrawCircle(NeoVec2(v1.x,v1.y),0.01,NeoColor(1,1,1)); v1 = v2; } } break; case b2Shape::e_polygon: { b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape(); int32 vertexCount = poly->m_vertexCount; b2Assert(vertexCount <= b2_maxPolygonVertices); b2Vec2 vertices[b2_maxPolygonVertices]; NeoVec2 v[b2_maxPolygonVertices]; for (int32 i = 0; i < vertexCount; ++i) { vertices[i] = b2Mul(xf, poly->m_vertices[i]); v[i] = NeoVec2(vertices[i].x,vertices[i].y); } draw.DrawSolidPolygon(v,vertexCount,NeoColor(1,1,1)); } break; default: break; } } } } void display() { //glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); int32 bodyCount = mybox2d.m_world->GetBodyCount(); float32 timeStep = 1.0f / 60.0f; int32 velocityIterations = 6; int32 positionIterations = 2; mybox2d.m_world->Step(timeStep, velocityIterations, positionIterations); drawWholeBody(mybox2d.m_world, mybox2d.m_bodies); glPopMatrix(); glutSwapBuffers(); glFlush(); } void Timer(int) { glutSetWindow(mainWindow); glutPostRedisplay(); //要求重畫視窗 glutTimerFunc(framePeriod, Timer, 0); //Do Repeat } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(winWidth, winHeight); mainWindow = glutCreateWindow("Neo Box2D"); glutDisplayFunc(display); GLUI_Master.set_glutReshapeFunc(Resize); GLUI_Master.set_glutSpecialFunc(KeyboardSpecial); GLUI_Master.set_glutKeyboardFunc(Keyboard); GLUI_Master.set_glutMouseFunc(Mouse); glutMouseWheelFunc(MouseWheel); glutMotionFunc(MouseMotion); glutTimerFunc(framePeriod, Timer, 0); //glui->set_main_gfx_window( mainWindow ); glutMainLoop(); return 0; }
myBox2d.h
#ifndef MYBOX2D_H #define MYBOX2D_H #include <Box2D/Box2D.h> class MyBox2D : public b2ContactListener { public: b2World* m_world; b2Body* m_groundBody; b2Body* m_bodies[4]; b2Joint* m_joints[8]; MyBox2D() { b2Vec2 gravity(0.0f, -10.0f); bool doSleep = true; m_world = new b2World(gravity, doSleep); //宣告static物體定義 b2BodyDef staticBodyDef; staticBodyDef.type = b2_staticBody; //宣告dynamic物體定義 b2BodyDef dynamicBodyDef; dynamicBodyDef.type = b2_dynamicBody; //註冊地面(先新增shape,再利用BodyDef給出location) //shape b2EdgeShape groundShape; groundShape.Set(b2Vec2(-50,0), b2Vec2(50,0)); //材質 b2FixtureDef groundFixtureDef; groundFixtureDef.shape = &groundShape; groundFixtureDef.density = 1.0f; groundFixtureDef.friction = 1.0f; //location staticBodyDef.position.Set(0, -20); m_groundBody = m_world->CreateBody(&staticBodyDef); m_groundBody->CreateFixture(&groundFixtureDef); m_bodies[0] = m_groundBody; //球shape b2CircleShape dynamicCircle; dynamicCircle.m_p.Set(0.0f, 0.0f); dynamicCircle.m_radius = 3.0f; //location dynamicBodyDef.position.Set(2, 20); m_bodies[1] = m_world->CreateBody(&dynamicBodyDef); m_bodies[1]->CreateFixture(&dynamicCircle,1.0f); b2PolygonShape dynamicBox; dynamicBox.SetAsBox(2, 2); dynamicBodyDef.position.Set(0.0f, 10.0f); m_bodies[2] = m_world->CreateBody(&dynamicBodyDef); m_bodies[2]->CreateFixture(&dynamicBox, 1.0f); /* b2Vec2 vs[4]; vs[0].Set(0.7f, 0.0f); vs[1].Set(1.0f, 0.02); vs[2].Set(0.0f, 0.0f); vs[3].Set(-0.7f, 0.4f); b2ChainShape chain; chain.CreateChain(vs, 4); bodyDef.position.Set(0.0f, 0.0f); m_bodies[4] = m_world->CreateBody(&bodyDef); m_bodies[4]->CreateFixture(&chain, 0.01f); */ } virtual ~MyBox2D() { delete m_world; m_world = NULL; } }; #endif
gluiDraw.h
#ifndef GLUIDRAW_H #define GLUIDRAW_H #include <math.h> #include <glui/GL/glui.h> #define PI 3.141592653 const float deg2Rad = PI / 180.; const float rad2Deg = 180. / PI; struct NeoColor { float r, g, b; NeoColor(){} NeoColor(float r_,float g_,float b_) : r(r_), g(g_), b(b_){} void Set(float r_,float g_,float b_) {r = r_; g = g_; b = b_;} }; struct NeoVec2 { float x, y; NeoVec2(){} NeoVec2(float x_,float y_) : x(x_), y(y_){} void Set(float x_,float y_) {x = x_; y = y_;} }; inline NeoVec2 operator + (const NeoVec2 &v1, const NeoVec2 &v2) { return NeoVec2(v1.x + v2.x, v1.y + v2.y); } inline NeoVec2 operator * (float a, const NeoVec2 &v) { return NeoVec2(v.x * a, v.y * a); } class GluiDraw { public: GluiDraw(){} ~GluiDraw(){} void DrawLine(const NeoVec2 &v1,const NeoVec2 &v2,const NeoColor &color) { glBegin(GL_LINES); glColor3f(color.r,color.g,color.b); glVertex2f(v1.x,v1.y); glVertex2f(v2.x,v2.y); glEnd(); } void DrawCircle(const NeoVec2 ¢er, const float radius, const NeoColor &color) { const float segments = 16.; const float inc = 2 * PI / 16.; float theta = 0; glBegin(GL_LINE_LOOP); glColor3f(color.r,color.g,color.b); for (int i=0;i < segments;++i) { NeoVec2 real_v = center + radius * NeoVec2(cosf(theta),sinf(theta)); glVertex2f(real_v.x,real_v.y); theta += inc; } glEnd(); } void DrawSolidCircle(const NeoVec2 ¢er, const float radius,const NeoVec2 &axis, const NeoColor &color) { const float segments = 16.; const float inc = 2 * PI / 16.; float theta = 0; glBegin(GL_LINE_LOOP); glColor3f(color.r,color.g,color.b); for (int i=0;i < segments;++i) { NeoVec2 real_v = center + radius * NeoVec2(cosf(theta),sinf(theta)); glVertex2f(real_v.x,real_v.y); theta += inc; } glEnd(); DrawLine(center,center + (radius * axis),color); } void DrawPolygon(const NeoVec2* vertices, int vertexCount, const NeoColor& color) { glColor3f(color.r, color.g, color.b); glBegin(GL_LINE_LOOP); for (int i = 0; i < vertexCount; ++i) { glVertex2f(vertices[i].x, vertices[i].y); } glEnd(); } void DrawSolidPolygon(const NeoVec2* vertices, int vertexCount, const NeoColor& color) { glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f); glBegin(GL_TRIANGLE_FAN); for (int i = 0; i < vertexCount; ++i) { glVertex2f(vertices[i].x, vertices[i].y); } glEnd(); glDisable(GL_BLEND); glColor4f(color.r, color.g, color.b, 1.0f); glBegin(GL_LINE_LOOP); for (int i = 0; i < vertexCount; ++i) { glVertex2f(vertices[i].x, vertices[i].y); } glEnd(); } void DrawBox(const NeoVec2 ¢er,const float half_width,const float half_height, const NeoColor& color) { NeoVec2 list[4] = { NeoVec2(center.x-(half_width),center.y-(half_height)), NeoVec2(center.x+(half_width),center.y-(half_height)), NeoVec2(center.x+(half_width),center.y+(half_height)), NeoVec2(center.x-(half_width),center.y+(half_height)) }; DrawSolidPolygon(list, 4, color); } }; #endif
沒有留言:
張貼留言