void Mesh::surfRev(int numSlices, Vector3 linePoints[], int numPoints) { float angleBetween = ToRadian(360 / numSlices); Matrix rotate; Identity(&rotate); RotateY(&rotate,angleBetween); Vector3* originalPoints = linePoints; //arrays of the points for the caps if they are necessary //in the event the shap has a hole in one of the ends Vector3* topCap = new Vector3[numSlices]; Vector3* bottomCap = new Vector3[numSlices]; for(int i = 0; i < numSlices; i++) { topCap[i] = originalPoints[numPoints-1]; bottomCap[i] = originalPoints[0]; Vector3* newPoints = new Vector3[numPoints]; for(int k = 0; k < numPoints; k++) { Vector4 point = Vector4(originalPoints[k].x,originalPoints[k].y,originalPoints[k].z,1); D3DXVec3Transform(&point,&originalPoints[k],&rotate); newPoints[k] = Vector3(point.x,point.y,point.z); } for(int j = 0; j < numPoints; j++) { Vector3* side = new Vector3[4]; side[0] = originalPoints[j]; if((j+1)<numPoints) { side[1] = originalPoints[j+1]; side[2] = newPoints[j+1]; } else { side[1] = originalPoints[0]; side[2] = newPoints[0]; } side[3] = newPoints[j]; makePolygon(side,4,j); //set the texture coordinates vertices[vertices.size()-4].texC = Vector2((i*numSlices*(1/360)),0); vertices[vertices.size()-3].texC = Vector2((i*numSlices*2*(1/360)),0); vertices[vertices.size()-2].texC = Vector2((i*numSlices*2*(1/260)),1); vertices[vertices.size()-1].texC = Vector2((i*numSlices*(1/360)),1); } originalPoints = newPoints; //delete[] newPoints; } //add end cap if necessary if(linePoints[numPoints-1].x!=0) { makePolygon(topCap,numSlices,0); } if(linePoints[0].x!=0) { makePolygon(bottomCap,numSlices,0); } delete[] topCap; }
/* * Called when the user clicked (or released) a mouse buttons inside the window. */ void mouse_clicked(int button, int state, int x, int y) { // guard against both left and right buttons being pressed at the same time, // by only responding when a mouse button is pressed while another one // hasn't been pressed yet if (state == GLUT_DOWN && mouse_mode == 0) { if (button == GLUT_LEFT_BUTTON) { mouse_mode = GLUT_LEFT_BUTTON; num_vertices++; /* Convert clicked mouse point to world vertex. */ draw_vertices[num_vertices].x = x * (world_x / reso_x); draw_vertices[num_vertices].y = (reso_y - y) * (world_y / reso_y); if (num_vertices > 0) { float distance = calcDistance(draw_vertices[num_vertices].x, draw_vertices[num_vertices].y, draw_vertices[num_vertices - 1].x, draw_vertices[num_vertices - 1].y); if (distance < 0.01) { num_vertices--; } } if (num_vertices == max_vertices - 1) { makePolygon(1, 0, 0, draw_vertices, num_vertices + 1, num_created_bodies++); } // printf("num_vertices = %d, max_vertices = %d\n", num_vertices, max_vertices); } else if (button == GLUT_RIGHT_BUTTON) { mouse_mode = GLUT_RIGHT_BUTTON; if (num_vertices > 1) { makePolygon(1, 0, 0, draw_vertices, num_vertices + 1, num_created_bodies++); } /* Possible TODO: Remove the point? */ } } else if (state == GLUT_UP && button == mouse_mode) { // pressed button released mouse_mode = 0; } }
/* * Load a given world, i.e. read the world from the `levels' data structure and * convert it into a Box2D world. */ void load_world(unsigned int level) { // Pause the game when loading a new level play = 0; if (level >= num_levels) { // Note that level is unsigned but we still use %d so -1 is shown as // such. printf("Warning: level %d does not exist.\n", level); return; } // Create a Box2D world and populate it with all bodies for this level // (including the ball). current_level = level + 1; cur_level = &(levels[level]); init(cur_level->num_joints); b2Vec2 gravity (0, -9.81); bool do_sleep = true; world = new b2World(gravity); world->SetAllowSleeping(do_sleep); // printf("num_polygons = %i\n", levels[0].num_polygons); // printf("is_Dynamic = %d\n", levels[0].polygons[0].is_dynamic); // Create ground b2BodyDef groundBodyDef; groundBodyDef.position.Set(0.0f, -world_y / 2); ground = world->CreateBody(&groundBodyDef); // addBodyToCreatedBodies(ground, num_created_bodies++); b2PolygonShape groundBox; groundBox.SetAsBox(world_x, world_y / 2); ground->CreateFixture(&groundBox, 0.0f); // Setup rest of level. for (unsigned int i = 0; i < cur_level->num_polygons; i++) { b2Vec2 *vertices = new b2Vec2[cur_level->polygons[i].num_verts]; for (unsigned int j = 0; j < cur_level->polygons[i].num_verts; j ++) { vertices[j].Set(cur_level->polygons[i].verts[j].x, cur_level->polygons[i].verts[j].y); } makePolygon(cur_level->polygons[i].is_dynamic, cur_level->polygons[i].position.x, cur_level->polygons[i].position.y, vertices, cur_level->polygons[i].num_verts, num_created_bodies++); delete[] vertices; } // Create ball b2BodyDef ballBodyDef; ballBodyDef.type = b2_dynamicBody; ballBodyDef.position.Set(cur_level->start.x, cur_level->start.y); ball = world->CreateBody(&ballBodyDef); b2CircleShape dynamicCircle; dynamicCircle.m_radius = ball_radius; b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicCircle; fixtureDef.density = 1.0f; fixtureDef.friction = 0.3f; ball->CreateFixture(&fixtureDef); // Setup joints. for (unsigned int i = 0; i < cur_level->num_joints; i++) { if (cur_level->joints[i].joint_type == JOINT_REVOLUTE) { b2RevoluteJointDef jointDef; // jointDef.anchorPoint = objectA->GetPosition(); b2Body *objectA = created_bodies[cur_level->joints[i].objectA]; b2Body *objectB = created_bodies[cur_level->joints[i].objectB]; b2Vec2 anchorPoint(cur_level->joints[i].anchor.x, cur_level->joints[i].anchor.y); jointDef.Initialize(objectA, objectB, anchorPoint); world->CreateJoint(&jointDef); } else if (cur_level->joints[i].joint_type == JOINT_PULLEY) { b2Vec2 anchorPoint1(cur_level->joints[i].anchor.x, cur_level->joints[i].anchor.x); b2Vec2 anchorPoint2(cur_level->joints[i].pulley.anchor2.x, cur_level->joints[i].pulley.anchor2.x); b2Vec2 groundAnchor1(cur_level->joints[i].pulley.ground1.x, cur_level->joints[i].pulley.ground1.y); b2Vec2 groundAnchor2(cur_level->joints[i].pulley.ground2.x, cur_level->joints[i].pulley.ground2.y); float ratio = cur_level->joints[i].pulley.ratio; b2Body *objectA = created_bodies[cur_level->joints[i].objectA]; b2Body *objectB = created_bodies[cur_level->joints[i].objectB]; b2PulleyJointDef jointDef; jointDef.Initialize(objectA, objectB, groundAnchor1, groundAnchor2, anchorPoint1, anchorPoint2, ratio); world->CreateJoint(&jointDef); } } }
int main() { int pmap[NUMTHREAD][WIDTH][HEIGHT]; //fill all member = -1 memset(pmap, -1, sizeof(pmap) ); // polygons std::vector<polygon> polygons; std::vector<value> values; for (int i = 0; i < NUMPOLYGON; i++) { polygon p = makePolygon(WIDTH, HEIGHT); bg::correct(p); polygons.push_back(p); } //std::cout<<polygons.size()<<std::endl; // display polygons // std::cout << "generated polygons:" << std::endl; // BOOST_FOREACH(polygon const & p, polygons) // std::cout << bg::wkt<polygon>(p) << std::endl; std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); // fill the spatial index for ( int i = 0 ; i < polygons.size() ; ++i ) { // calculate polygon bounding box box b = bg::return_envelope<box>(polygons[i]); // insert new value values.push_back(std::make_pair(b, i)); } RTREE rtree(values.begin(), values.end()); std::thread threads[NUMTHREAD]; for (int i = 0; i < NUMTHREAD; i++) { threads[i] = std::thread([i, &rtree, &polygons, &pmap]() { DrawPolygon2(i, rtree, polygons, pmap[i]); }); } for (int i = 0; i < NUMTHREAD; i++) { threads[i].join(); } //concatenate int mapresult[WIDTH][HEIGHT]; memset(mapresult,-1,sizeof(mapresult)); for (int index = NUMTHREAD - 1; index >= 0; index--) { int xmin, ymin, xmax, ymax; box b; findCorner(xmin, ymin, xmax, ymax, b, index); for (int i = xmin; i < xmax; i++) { for (int j = ymin; j < ymax; j++) { int id = pmap[index][i][j]; if (id != -1) { mapresult[i][j] = id; } } } } std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); float duration = (float)(std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count()) / 1000; std::cout << "duration : " << duration << std::endl; //random color std::vector<int> colors; int size = polygons.size(); for ( int i = 0 ; i < size ; ++i ) { colors.push_back(i % 3 + 1); } //Draw pixel // t1 = std::chrono::high_resolution_clock::now(); cv::Mat mat(HEIGHT, WIDTH, CV_8UC4); mat = cv::Scalar(0, 0, 0, 0); for (int i = 0; i < WIDTH; i++) for (int j = 0; j < HEIGHT; j++) { if (mapresult[i][j] != -1) { int c = colors[mapresult[i][j]]; auto color = c == 1 ? RED : c == 2 ? GREEN : BLUE; line( mat, cv::Point(i, j), cv::Point(i, j), color, 2, 8); } } line(mat, cv::Point(10, 10), cv::Point(251, 240), cv::Scalar(0, 0, 0, 255), 1, 8); std::vector<int> compression_params; compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); imwrite("DrawPolygon7.png", mat, compression_params); return 0; }
int main() { int pmap[WIDTH][HEIGHT]; //fill all member = -1 memset(pmap, -1, sizeof(pmap) ); // polygons std::vector<polygon> polygons; std::vector<value> values; // create some polygons for ( unsigned i = 0 ; i < 10 ; ++i ) { // create a polygon polygon p; for ( float a = 0 ; a < 6.28316f ; a += 1.04720f ) { int x = 30 * i + int(20 *::cos(a)); int y = 30 * i + int(20 *::sin(a)); p.outer().push_back(point(x, y)); } // add polygon polygons.push_back(p); } for(int i=0;i<100;i++) { polygon p = makePolygon(WIDTH,HEIGHT); polygons.push_back(p); } // display polygons std::cout << "generated polygons:" << std::endl; BOOST_FOREACH(polygon const & p, polygons) std::cout << bg::wkt<polygon>(p) << std::endl; // fill the spatial index for ( unsigned i = 0 ; i < polygons.size() ; ++i ) { // calculate polygon bounding box box b = bg::return_envelope<box>(polygons[i]); // insert new value values.push_back(std::make_pair(b, i)); } RTREE rtree(values.begin(), values.end()); for (int i = 0; i < WIDTH; i++) for (int j = 0; j < HEIGHT; j++) { if (pmap[i][j] == -1) { std::vector<value> returned_values; point sought = point(i, j); for ( RTREE::const_query_iterator it = rtree.qbegin(bgi::nearest(sought, 1) ) ; it != rtree.qend() ; ++it ) { if (!bg::within(sought, polygons[it->second])) { break; } returned_values.push_back(*it); } if (returned_values.size() > 0) { int count = 0; int id = returned_values[0].second; pmap[i][j] = id; point pmin = returned_values[0].first.min_corner(); point pmax = returned_values[0].first.max_corner(); std::cout<<pmin.get<0>()<<", "<<pmin.get<1>()<<" "<<pmax.get<0>()<<", "<<pmax.get<1>() <<std::endl; // for (int w = pmin.get<0>(); w < pmax.get<0>(); w++) // for (int h = pmin.get<1>(); h < pmax.get<1>(); h++) // { // if (w >= WIDTH || h >= HEIGHT) // continue; // if (bg::within(point(w, h), polygons[id]) != 0) // { // pmap[w][h] = id; // } // } for (int w = 0; w < WIDTH; w++) for (int h = 0; h < HEIGHT; h++) { if (w >= WIDTH || h >= HEIGHT) continue; if (bg::within(point(w, h), polygons[id]) != 0) { pmap[w][h] = id; } } } } } //random mau std::vector<int> colors; for ( unsigned i = 0 ; i < polygons.size() ; ++i ) { colors.push_back(i % 3 + 1); } //DrawHinh std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); cv::Mat mat(HEIGHT, WIDTH, CV_8UC4); mat = cv::Scalar(0, 0, 0, 0); for (int i = 0; i < WIDTH; i++) for (int j = 0; j < HEIGHT; j++) { if (pmap[i][j] != -1) { int c = colors[pmap[i][j]]; auto color = c == 1 ? RED : c == 2 ? GREEN : BLUE; line( mat, cv::Point(i, j), cv::Point(i, j), color , 1, 8 ); } } std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); float duration = (float)(std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count()) / 1000; std::cout << "duration DrawPolygon: " << duration << std::endl; std::vector<int> compression_params; compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); imwrite("DrawPolygon2.png", mat, compression_params); // find 5 nearest values to a point std::vector<value> result_n; rtree.query(bgi::nearest(point(0, 0), 1), std::back_inserter(result_n)); // note: in Boost.Geometry the WKT representation of a box is polygon // note: the values store the bounding boxes of polygons // the polygons aren't used for querying but are printed std::cout << "knn query point:" << std::endl; std::cout << bg::wkt<point>(point(0, 0)) << std::endl; std::cout << "knn query result:" << std::endl; BOOST_FOREACH(value const & v, result_n) std::cout << bg::wkt<polygon>(polygons[v.second]) << std::endl; return 0; }
int main (int argc, char **argv) { // GLUT init osgInit(argc, argv); osgLog().setLogLevel ( OSG::LOG_DEBUG ); FieldContainerPtr pProto = Geometry::getClassType().getPrototype(); GeometryPtr pGeoProto = GeometryPtr::dcast(pProto); if(pGeoProto != NullFC) { pGeoProto->setDlistCache(true); } glutInit(&argc, argv); glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); UInt32 id = glutCreateWindow("OpenSG"); glutKeyboardFunc(key); glutReshapeFunc(resize); glutDisplayFunc(display); // glutMouseFunc(mouse); // glutMotionFunc(motion); glutIdleFunc(display); // create a material (need that to test textures) ChunkMaterialPtr mat; beginEditCP(mat); mat = ChunkMaterial::create(); MaterialChunkPtr mc = MaterialChunk::create(); beginEditCP(mc); mc->setDiffuse( Color4f( 1,.8,.8,1 ) ); mc->setAmbient( Color4f( 0.1,0.1,0.1,1 ) ); mc->setSpecular( Color4f( 1,1,1,1 ) ); mc->setShininess( 20 ); mc->setBackMaterial(true); mc->setBackColorMaterial(GL_DIFFUSE); mc->setBackDiffuse( Color4f( 1,0,0,1 ) ); mc->setBackAmbient( Color4f( 0.1,0.1,0.1,1 ) ); mc->setBackSpecular( Color4f( 0,1,0,1 ) ); mc->setBackShininess( 10 ); mc->setLit(true); endEditCP(mc); mat->addChunk(mc); // Texture chunk UChar8 imgdata[] = { 255,0,0,128, 0,255,0,128, 0,0,255,255, 255,255,255,255 }; ImagePtr pImage = Image::create(); pImage->set( Image::OSG_RGBA_PF, 2, 2, 1, 1, 1, 0, imgdata ); if ( argc > 1 ) pImage->read( argv[1] ); TextureChunkPtr xchunk; xchunk = TextureChunk::create(); xchunk->setImage( pImage ); xchunk->setMinFilter( GL_NEAREST ); xchunk->setMagFilter( GL_NEAREST ); xchunk->setWrapS( GL_REPEAT ); xchunk->setWrapT( GL_REPEAT ); xchunk->setEnvMode( GL_MODULATE ); mat->addChunk( xchunk ); endEditCP(mat); objects[0] = makePolygon(ccwSquare, sizeof(ccwSquare)/sizeof(double[3])); objects[1] = makePolygon(ccwSquare, sizeof(ccwSquare)/sizeof(double[3])); objects[2] = makePolygon(star, sizeof(star)/sizeof(double[3])); objects[3] = makePolygon(star, sizeof(star)/sizeof(double[3])); objects[4] = makePolygon(cwSquare, sizeof(cwSquare)/sizeof(double[3])); objects[5] = makePolygon(cwSquare, sizeof(cwSquare)/sizeof(double[3])); objects[6] = makePolygon(doubleEight, sizeof(doubleEight)/sizeof(double[3])); objects[7] = makePolygon(doubleEight, sizeof(doubleEight)/sizeof(double[3])); //tesselate every second object for(int i = 1; i < nobjects; i+=2) { GeometryPtr::dcast(objects[i]->getCore())->setMaterial( mat ); std::cerr << "Polygon Node: " << std::hex << objects[i] << std::endl; // try to create convex primitives OSG::GeometryPtr pGeo = GeometryPtr::dcast(objects[i]->getCore()); std::cerr << "Tesselating polygon : " << i << std::endl; createConvexPrimitives(pGeo); } // normal material SimpleMaterialPtr nmat; nmat = SimpleMaterial::create(); beginEditCP(nmat); nmat->setEmission( Color3f( 0,1,0 ) ); endEditCP(nmat); for ( UInt16 i = 0; i < nobjects; i++ ) { normalobjects[i] = calcVertexNormalsGeo( GeometryPtr::dcast(objects[i]->getCore()), .5); GeometryPtr::dcast(normalobjects[i]->getCore())->setMaterial(nmat); } // // The action win = GLUTWindow::create(); win->setId(id); win->init(); glEnable( GL_LIGHT0 ); float p[4]={0,0,1,0}; glLightfv(GL_LIGHT0, GL_POSITION, p); float c[4]={1,1,1,1}; glLightfv(GL_LIGHT0, GL_DIFFUSE, c); glLightfv(GL_LIGHT0, GL_SPECULAR, c); glPointSize( 3 ); glEnable( GL_DEPTH_TEST ); glEnable( GL_LIGHTING ); glClearColor( .3, .3, .8, 1 ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60, 1, 0.1, 10 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); gluLookAt( 3, 3, 3, 0, 0, 0, 0, 0, 1 ); dact = DrawAction::create(); dact->setWindow(get_pointer(win)); dact->setFrustumCulling( false ); glutMainLoop(); return 0; }
void Esh3DRenderer::render(const EshShape& in_shape, EshRendererContext& in_rendererContext,MfGdiBrush *in_brush) { ChLOG_DEBUG_START_FN; if (!setUp(in_shape, in_rendererContext)) { return; } // temporary pen & brush so I can see what I'm doing! //ChAutoPtr<MfGdiBrush> pBrush = m_driver.CreateSolidBrush(CsColour(0x88, 0x88, 0x88)); //ChAutoPtr<MfGdiPen> pPen = m_driver.CreatePen(MfGdiPen::Style_Solid, 4, CsColour(0,0,0), ChVector<ChFLT8>()); //ChAutoPtr<MfGdiBrush> pBrush = EshGdiObjectFactory::makeNullBrush(m_driver); ChAutoPtr<MfGdiPen> pPen(EshGdiObjectFactory::makeNullPen(m_driver)); // LINUX_PORT // TODO - pen must be null pen, but because faces aren't being shaded according to normal angle, an // outline is being drawn to figure out where the faces are //in_rendererContext.getDeviceContextReference().SetBrush(*pBrush); //in_rendererContext.getDeviceContextReference().TakeBrush(pBrush.giveUpOwnership()); in_rendererContext.getDeviceContextReference().TakePen(pPen.giveUpOwnership()); if (in_rendererContext.hasTransformation()) { // 2D rotation must be done before any 3D rotation/skew, so multiply on right of current // 3D world transform, which at this point will have the skew and rotation already m_worldTransform = m_worldTransform * CsMatrix3D<ChFLT8>(in_rendererContext.getTransformationMatrix()); } m_pPathData = ChNEW EshPathRendererData(*m_pGeometry, in_rendererContext); m_pPathData->init(); MfGdiDeviceContext& deviceContext = in_rendererContext.getDeviceContextReference(); // use non-const verion of method to have geometry add implied segments const EshPathCommandTable& pathCommands = m_pPathData->getPathCommandsReference(); if (pathCommands.size() == 0) { return; } bool skip = true; bool isFirstSegmentDrawn = false; CsPoint<ChFLT8> startPosition(0,0); CsPoint<ChFLT8> position(0,0); CsPoint<ChFLT8> nextPosition(0,0); const EshPathCommand* pCurrentPathCommand; const EshPathCommand* pNextPathCommand; ChUINT2 j = 0; /** * TODO - is it possible for the first path param to be an editing command? */ pNextPathCommand = &pathCommands[0]; EshPathCommandTypeEnums nextPathCommandType = pNextPathCommand->m_type; CsPlanarPolygon<ChFLT8> frontFace; CsPlanarPolygon<ChFLT8> extrusion; for (ChUINT4 i=1; i <= pathCommands.size(); i++) { pCurrentPathCommand = pNextPathCommand; // Skip editing commands skip = true; while ( skip && i < pathCommands.size()) { skip = (ESH_PATH_CMD_HA <= pathCommands[i].m_type && pathCommands[i].m_type <= ESH_PATH_CMD_HI); if(skip) { ++i; } } if (i == pathCommands.size()) { nextPathCommandType = ESH_PATH_CMD_E; } else { pNextPathCommand = &pathCommands[i]; nextPathCommandType = pNextPathCommand->m_type; } bool isLastCommand = (nextPathCommandType == ESH_PATH_CMD_E); bool isEnd = isLastCommand; switch (pCurrentPathCommand->m_type) { case ESH_PATH_CMD_L: // Line to // openClosedPath(deviceContext); for (j=0; j < pCurrentPathCommand->m_unCount; j++) { isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); m_pPathData->getPoint(nextPosition); //m_pPathData->getPoint(nextPosition); if (!isFirstSegmentDrawn) { startPosition = position; frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth)); isFirstSegmentDrawn = true; } if (m_isFilled) { frontFace.addPoint(m_worldTransform * ChPoint3DF8(nextPosition, m_lForeDepth)); } // TODO - linecap stuff makePolygon(position, nextPosition, extrusion); m_tree.insert(extrusion); position = nextPosition; } break; case ESH_PATH_CMD_C: // Cubic curve // openClosedPath(deviceContext); for (j=0; j < pCurrentPathCommand->m_unCount; j++) { ChPoint3DF8 p0(position.getX(), position.getY(), m_lForeDepth); ChPoint3DF8 p1(m_pPathData->getPointF8(), m_lForeDepth); // 1st control point ChPoint3DF8 p2(m_pPathData->getPointF8(), m_lForeDepth); // 2nd control point m_pPathData->getPoint(nextPosition); ChPoint3DF8 p3(nextPosition, m_lForeDepth); // endpoint if (!isFirstSegmentDrawn) { startPosition = position; if (m_isFilled) { frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth)); } isFirstSegmentDrawn = true; } divideBezier(p0, p1, p2, p3, frontFace); position = nextPosition; } break; case ESH_PATH_CMD_M: // Move to - count is always 1 ChASSERT(pCurrentPathCommand->m_unCount == 1); m_pPathData->getPoint(position); break; case ESH_PATH_CMD_X: // Close path nextPosition = startPosition; if (position != nextPosition) { makePolygon(position, nextPosition, extrusion); m_tree.insert(extrusion); position = nextPosition; } if (m_isFilled) { m_faces.push_back(frontFace); frontFace.clear(); } isFirstSegmentDrawn = false; break; case ESH_PATH_CMD_E: // End path data attribute /* Freeform paths will not have a close path command, however, if the path is filled, we still need a polygon for that line segment. */ if (m_isFilled && position != startPosition) { makePolygon(position, startPosition, extrusion); m_tree.insert(extrusion); position = startPosition; m_faces.push_back(frontFace); frontFace.clear(); } break; case ESH_PATH_CMD_AE: // Angle ellipse to for (j=0; j < pCurrentPathCommand->m_unCount; j++) { isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); if (!isFirstSegmentDrawn) { startPosition = makeAngleEllipse(in_rendererContext, position, false, j, frontFace); isFirstSegmentDrawn = true; } else { makeAngleEllipse(in_rendererContext, position, false, j, frontFace); } } break; case ESH_PATH_CMD_AL: // Angle ellipse for (j=0; j < pCurrentPathCommand->m_unCount; j++) { isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); if (!isFirstSegmentDrawn) { startPosition = makeAngleEllipse(in_rendererContext, position, true, j, frontFace); isFirstSegmentDrawn = true; } else { makeAngleEllipse(in_rendererContext, position, true, j, frontFace); } } break; case ESH_PATH_CMD_AT: // Arc to for (j=0; j < pCurrentPathCommand->m_unCount; j++) { isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); if (!isFirstSegmentDrawn) { startPosition = makeArc(position, false, j, false, frontFace); isFirstSegmentDrawn = true; } else { makeArc(position, false, j, false, frontFace); } } break; case ESH_PATH_CMD_AR: // Arc for (j=0; j < pCurrentPathCommand->m_unCount; j++) { isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); if (!isFirstSegmentDrawn) { startPosition = makeArc(position, true, j, false, frontFace); frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth)); isFirstSegmentDrawn = true; } else { makeArc(position, true, j, false, frontFace); } } break; case ESH_PATH_CMD_WA: // Clockwise arc to for (j=0; j < pCurrentPathCommand->m_unCount; j++) { isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); if (!isFirstSegmentDrawn) { startPosition = makeArc(position, false, j, true, frontFace); isFirstSegmentDrawn = true; } else { makeArc(position, false, j, true, frontFace); } } break; case ESH_PATH_CMD_WR: // Clockwise arc for (j=0; j < pCurrentPathCommand->m_unCount; j++) { isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); if (!isFirstSegmentDrawn) { startPosition = makeArc(position, true, j, true, frontFace); frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth)); isFirstSegmentDrawn = true; } else { makeArc(position, true, j, true, frontFace); } } break; case ESH_PATH_CMD_QX: // Elliptical quadrant x for (j=0; j < pCurrentPathCommand->m_unCount; j++) { if (!isFirstSegmentDrawn) { startPosition = position; isFirstSegmentDrawn = true; } isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); makeQuadrantArc(position, j % 2 == 0, frontFace); } break; case ESH_PATH_CMD_QY: // Elliptical quadrant y for (j=0; j < pCurrentPathCommand->m_unCount; j++) { if (!isFirstSegmentDrawn) { startPosition = position; frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth)); isFirstSegmentDrawn = true; } isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1); makeQuadrantArc(position, j % 2 == 1, frontFace); } break; } } // Draw the actual shape. m_tree.render(m_driver, in_rendererContext); if (m_isFilled) { ChBYTE opacity = 255; const EshFill &fill = in_shape.getFill(); if (fill.isOpacitySet()) { opacity = fill.getOpacity() >> 8; } renderPrimaryFaces(deviceContext,in_brush,opacity); }
int main(int argc, char** argv) { bool timeit = FALSE; QApplication app(argc,argv); bool scrollbars=FALSE; for (int arg=1; arg<argc; arg++) { if (0==strcmp(argv[arg],"-bounce")) { bouncers=atoi(argv[++arg]); } else if (0==strcmp(argv[arg],"-help") || 0==strcmp(argv[arg],"--help")) { showtext=FALSE; } else if (0==strcmp(argv[arg],"-redraws")) { showredraws=TRUE; } else if (0==strcmp(argv[arg],"-lines")) { showlines=TRUE; } else if (0==strcmp(argv[arg],"-btext")) { btext=FALSE; } else if (0==strcmp(argv[arg],"-dsprite")) { dsprite=FALSE; } else if (0==strcmp(argv[arg],"-dpoly")) { dpoly=!dpoly; } else if (0==strcmp(argv[arg],"-delay")) { refresh_delay=atoi(argv[++arg]); } else if (0==strcmp(argv[arg],"-sb")) { scrollbars=TRUE; } else if (0==strcmp(argv[arg],"-noopt")) { QPixmap::setDefaultOptimization( QPixmap::NoOptim ); } else if (0==strcmp(argv[arg],"-bestopt")) { QPixmap::setDefaultOptimization( QPixmap::BestOptim ); #ifdef _WS_WIN_ } else if (0==strcmp(argv[arg],"-bsm")) { extern bool qt_bitblt_bsm; qt_bitblt_bsm=TRUE; #endif } else if (0==strcmp(argv[arg],"-iter")) { iterations=atoi(argv[++arg]); timeit = TRUE; } else { warning("Bad param %s", argv[arg]); } } QMainWindow m; MySpriteField field(IMG_BACKGROUND,scrollbars ? WIDTH*3 : WIDTH, scrollbars ? HEIGHT*3 : HEIGHT); Example example(scrollbars,field,&m); QMenuBar* menu = m.menuBar(); QPopupMenu* file = new QPopupMenu; file->insertItem("New view", &example, SLOT(makeSlave()), CTRL+Key_N); file->insertSeparator(); file->insertItem("Quit", qApp, SLOT(quit()), CTRL+Key_Q); menu->insertItem("&File", file); QPopupMenu* edit = new QPopupMenu; edit->insertItem("New polygon", &example, SLOT(makePolygon())); edit->insertItem("New ellipse", &example, SLOT(makeEllipse())); edit->insertItem("New rectangle", &example, SLOT(makeRectangle())); menu->insertItem("&Edit", edit); MyPopupMenu* options = new MyPopupMenu; options->insertCheckItem("Show help text", &showtext, CTRL+Key_H); options->insertCheckItem("Show bouncing text", &btext, CTRL+Key_T); options->insertCheckItem("Show polygon", &dpoly, CTRL+Key_P); options->insertCheckItem("Show drawn sprite", &dsprite, CTRL+Key_D); options->insertCheckItem("Show redraw areas", &showredraws, CTRL+Key_A); options->insertCheckItem("Show foreground lines", &showlines, CTRL+Key_L); options->insertSeparator(); options->insertRadioItem("1 bouncer", &bouncers, 1); options->insertRadioItem("3 bouncers", &bouncers, 3); options->insertRadioItem("10 bouncers", &bouncers, 10); options->insertRadioItem("30 bouncers", &bouncers, 30); options->insertRadioItem("100 bouncers", &bouncers, 100); options->insertRadioItem("1000 bouncers", &bouncers, 1000); options->insertSeparator(); options->insertRadioItem("No delay", &refresh_delay, 0); options->insertRadioItem("500 fps", &refresh_delay, 2); options->insertRadioItem("100 fps", &refresh_delay, 10); options->insertRadioItem("72 fps", &refresh_delay, 14); options->insertRadioItem("30 fps", &refresh_delay, 33); options->insertRadioItem("10 fps", &refresh_delay, 100); options->insertRadioItem("5 fps", &refresh_delay, 200); options->insertSeparator(); options->insertRadioItem("1/10 speed", &speed, 2); options->insertRadioItem("1/2 speed", &speed, 10); options->insertRadioItem("1x speed", &speed, 20); options->insertRadioItem("2x speed", &speed, 40); options->insertRadioItem("5x speed", &speed, 100); menu->insertItem("&Options",options); m.statusBar(); QObject::connect(options, SIGNAL(variableChanged(bool*)), &example, SLOT(refresh())); QObject::connect(options, SIGNAL(variableChanged(int*)), &example, SLOT(refresh())); QObject::connect(&example, SIGNAL(status(const char*)), m.statusBar(), SLOT(message(const char*))); m.setCentralWidget(&example); app.setMainWidget(&m); m.show(); QTime t; t.start(); app.exec(); if ( timeit ) debug("%dms",t.elapsed()); return 0; }