Shape * DrawTools::drawSolidArc(double startRadius, double endRadius, double startAngle, double endAngle, int steps) { int vertCount = steps * 6; BoundedArray<GLfloat> verts(2 * vertCount); double delta = endAngle - startAngle; double step = delta / steps; int offset = 0; double angle = startAngle; for (int i=0; i<steps; ++i) { float tlx = endRadius * sin(angle); float tly = endRadius * cos(angle); float trx = endRadius * sin(angle+step); float trY = endRadius * cos(angle+step); float blx = startRadius * sin(angle); float bly = startRadius * cos(angle); float brx = startRadius * sin(angle+step); float bry = startRadius * cos(angle+step); verts[offset++] = tlx; verts[offset++] = tly; verts[offset++] = blx; verts[offset++] = bly; verts[offset++] = brx; verts[offset++] = bry; verts[offset++] = brx; verts[offset++] = bry; verts[offset++] = tlx; verts[offset++] = tly; verts[offset++] = trx; verts[offset++] = trY; angle += step; } return new Shape(verts,vertCount); }
void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 radius, const ColorI &color ) { VectorF uvec = tipPnt - basePnt; F32 height = uvec.len(); uvec.normalize(); MatrixF mat( true ); MathUtils::getMatrixFromUpVector( uvec, &mat ); mat.setPosition(basePnt); Point3F scale( radius, radius, height * 2 ); mat.scale(scale); GFXTransformSaver saver; mDevice->pushWorldMatrix(); mDevice->multWorld(mat); S32 numPoints = sizeof(circlePoints)/sizeof(Point2F); GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoints * 4 + 4, GFXBufferTypeVolatile); verts.lock(); for (S32 i=0; i<numPoints + 1; i++) { S32 imod = i % numPoints; verts[i].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0.5f); verts[i].color = color; verts[i + numPoints + 1].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0); verts[i + numPoints + 1].color = color; verts[2*numPoints + 2 + 2 * i].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0.5f); verts[2*numPoints + 2 + 2 * i].color = color; verts[2*numPoints + 2 + 2 * i + 1].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0); verts[2*numPoints + 2 + 2 * i + 1].color = color; } verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders( GFXDevice::GSModColorTexture ); mDevice->drawPrimitive( GFXTriangleFan, 0, numPoints ); mDevice->drawPrimitive( GFXTriangleFan, numPoints + 1, numPoints ); mDevice->drawPrimitive( GFXTriangleStrip, 2 * numPoints + 2, 2 * numPoints); mDevice->popWorldMatrix(); }
void GFXDrawUtil::drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI &color ) { GFXVertexBufferHandle<GFXVertexPC> verts( mDevice, 2, GFXBufferTypeVolatile ); verts.lock(); verts[0].point.set( x1, y1, z1 ); verts[1].point.set( x2, y2, z2 ); verts[0].color = color; verts[1].color = color; verts.unlock(); mDevice->setVertexBuffer( verts ); mDevice->setStateBlock( mRectFillSB ); mDevice->setupGenericShaders(); mDevice->drawPrimitive( GFXLineList, 0, 1 ); }
Line * DrawTools::drawArc(double radius, double beginAngle, double endAngle, int steps) { int vertCount = steps + 1; BoundedArray<GLfloat> verts(2*vertCount); double delta = endAngle - beginAngle; double step = delta / steps; double angle = beginAngle; for (int i=0; i<=steps; ++i) { verts[i*2] = sin(angle) * radius; verts[i*2+1] = cos(angle) * radius; angle += step; } return new Line(verts,vertCount); }
void Face3::init() { if(myMesh != NULL) { components(0)=myMesh->edge(verts(0),verts(1)).id_; components(1)=myMesh->edge(verts(0),verts(2)).id_; components(2)=myMesh->edge(verts(1),verts(2)).id_; } for(int i=0; i < typeSpecyfic_.nComponents_; ++i) { myMesh->edges_.getById(components(i)).incRef(); } }
void GFXDrawUtil::_drawWirePolyhedron( const GFXStateBlockDesc &desc, const AnyPolyhedron &poly, const ColorI &color, const MatrixF *xfm ) { GFXDEBUGEVENT_SCOPE( GFXDrawUtil_DrawWirePolyhedron, ColorI::GREEN ); const U32 numEdges = poly.getNumEdges(); const Point3F* points = poly.getPoints(); const Polyhedron::Edge* edges = poly.getEdges(); // Allocate a temporary vertex buffer. GFXVertexBufferHandle< GFXVertexPC > verts( mDevice, numEdges * 2, GFXBufferTypeVolatile); // Fill it with the vertices for the edges. verts.lock(); for( U32 i = 0; i < numEdges; ++ i ) { const U32 nvert = i * 2; verts[ nvert + 0 ].point = points[ edges[ i ].vertex[ 0 ] ]; verts[ nvert + 0 ].color = color; verts[ nvert + 1 ].point = points[ edges[ i ].vertex[ 1 ] ]; verts[ nvert + 1 ].color = color; } if( xfm ) { for( U32 i = 0; i < numEdges; ++ i ) { xfm->mulP( verts[ i + 0 ].point ); xfm->mulP( verts[ i + 1 ].point ); } } verts.unlock(); // Render the line list. mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); mDevice->drawPrimitive( GFXLineList, 0, numEdges ); }
BOOL plDistributor::IDuplicate2Sided(plMaxNode* node, Mesh* mesh) const { Mtl* mtl = node->GetMtl(); BitArray faces(mesh->getNumFaces()); int num2Sided = 0; int origNumFaces = mesh->getNumFaces(); int i; for( i = 0; i < mesh->getNumFaces(); i++ ) { if( hsMaterialConverter::IsTwoSided(mtl, mesh->faces[i].getMatID()) ) { num2Sided++; faces.Set(i); } } if( !num2Sided ) return false; MeshDelta meshDelta(*mesh); meshDelta.CloneFaces(*mesh, faces); meshDelta.Apply(*mesh); BitArray verts(mesh->getNumVerts()); verts.SetAll(); const float kWeldThresh = 0.1f; meshDelta.WeldByThreshold(*mesh, verts, kWeldThresh); meshDelta.Apply(*mesh); hsAssert(origNumFaces + num2Sided == mesh->getNumFaces(), "Whoa, lost or gained, unexpected"); for( i = origNumFaces; i < mesh->getNumFaces(); i++ ) { meshDelta.FlipNormal(*mesh, i); } meshDelta.Apply(*mesh); return true; }
static int pyGeometrySpan_setVertices(pyGeometrySpan* self, PyObject* value, void*) { if (value == NULL || !PySequence_Check(value)) { PyErr_SetString(PyExc_TypeError, "vertices should be a sequence of TempVertex"); return -1; } size_t count = PySequence_Size(value); for (size_t i = 0; i < count; ++i) { if (!pyTempVertex_Check(PySequence_Fast_GET_ITEM(value, i))) { PyErr_SetString(PyExc_TypeError, "vertices should be a sequence of TempVertex"); return -1; } } std::vector<plGeometrySpan::TempVertex> verts(PySequence_Size(value)); for (size_t i = 0; i < verts.size(); ++i) verts[i] = *((pyTempVertex*)PySequence_Fast_GET_ITEM(value, i))->fThis; self->fThis->setVertices(verts); return 0; }
bool PymolWriter::handle_triangle(TriangleGeometry *g, Color color, std::string name) { setup(name, TRIANGLES); if (!open_type_) { get_stream() << "BEGIN, TRIANGLES, "; open_type_ = TRIANGLES; } Ints tri(3); tri[0] = 0; tri[1] = 1; tri[2] = 2; algebra::Vector3Ds verts(3); verts[0] = g->get_geometry().get_point(0); verts[1] = g->get_geometry().get_point(1); verts[2] = g->get_geometry().get_point(2); algebra::Vector3Ds normals = internal::get_normals(tri, verts); write_triangle(tri.begin(), tri.end(), verts, normals, color, get_stream()); return true; }
void GFXDrawUtil::_drawWireCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm ) { GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, 30, GFXBufferTypeVolatile); verts.lock(); Point3F halfSize = size * 0.5f; // setup 6 line loops U32 vertexIndex = 0; for(S32 i = 0; i < 6; i++) { for(S32 j = 0; j < 5; j++) { S32 idx = cubeFaces[i][j%4]; verts[vertexIndex].point = cubePoints[idx] * halfSize; verts[vertexIndex].color = color; vertexIndex++; } } // Apply xfm if we were passed one. if ( xfm != NULL ) { for ( U32 i = 0; i < 30; i++ ) xfm->mulP( verts[i].point ); } // Apply position offset for ( U32 i = 0; i < 30; i++ ) verts[i].point += pos; verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); for( U32 i=0; i<6; i++ ) mDevice->drawPrimitive( GFXLineStrip, i*5, 4 ); }
void GFXDrawUtil::_drawWireCapsule( const GFXStateBlockDesc &desc, const Point3F ¢er, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm ) { MatrixF mat; if ( xfm ) mat = *xfm; else mat = MatrixF::Identity; mat.scale( Point3F(radius,radius,height*0.5f) ); mat.setPosition(center); mDevice->pushWorldMatrix(); mDevice->multWorld(mat); S32 numPoints = sizeof(circlePoints)/sizeof(Point2F); GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoints, GFXBufferTypeVolatile); verts.lock(); for (S32 i=0; i< numPoints; i++) { S32 idx = i & (~1); // just draw the even ones F32 z = i & 1 ? 1.0f : -1.0f; verts[i].point = Point3F(circlePoints[idx].x,circlePoints[idx].y, z); verts[i].color = color; } verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); for (S32 i=0; i<numPoints; i += 2) mDevice->drawPrimitive(GFXLineStrip, i, 1); mDevice->popWorldMatrix(); Point3F sphereCenter; sphereCenter.z = center.z + 0.5f * height; drawSphere( desc, radius,sphereCenter,color,true,false); sphereCenter.z = center.z - 0.5f * height; drawSphere( desc, radius,sphereCenter,color,false,true); }
static int pyCullPoly_setVerts(pyCullPoly* self, PyObject* value, void*) { if (value == NULL) { self->fThis->setVerts(std::vector<hsVector3>()); return 0; } if (!PyList_Check(value)) { PyErr_SetString(PyExc_TypeError, "verts should be a list of hsVector3s"); return -1; } std::vector<hsVector3> verts(PyList_Size(value)); for (size_t i=0; i<verts.size(); i++) { PyObject* item = PyList_GetItem(value, i); if (!pyVector3_Check(item)) { PyErr_SetString(PyExc_TypeError, "verts should be a list of hsVector3s"); return -1; } verts[i] = *((pyVector3*)item)->fThis; } self->fThis->setVerts(verts); return 0; }
void CubicBezierCurve::Unpack() { // demo and test size_t n = 0; n = GetPointNumber(max_subdiv_count); DBG_PRINT_MSG("10, points: %ld", n); glm::vec2 p1(0.f, 0.f); glm::vec2 p2(100.f, 100.f); glm::vec2 p3(200.f, 100.f); glm::vec2 p4(300.f, 0.f); std::vector<GLfloat> verts(n * 3, 0.f); size_t index = 0; GenerateBezierCurveVertices(p1, p2, p3, p4, 0, &index, verts); buffer_.bind(); buffer_.set_data(sizeof(GLfloat) * verts.size(), &verts[0]); buffer_.reset(); }
void GFXDrawUtil::drawRectFill( const Point2F &upperLeft, const Point2F &lowerRight, const ColorI &color ) { // // Convert Box a----------x // | | // x----------b // Into Quad // v0---------v1 // | a x | // | | // | x b | // v2---------v3 // // NorthWest and NorthEast facing offset vectors Point2F nw(-0.5,-0.5); /* \ */ Point2F ne(0.5,-0.5); /* / */ GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, 4, GFXBufferTypeVolatile); verts.lock(); F32 ulOffset = 0.5f - mDevice->getFillConventionOffset(); verts[0].point.set( upperLeft.x+nw.x+ulOffset, upperLeft.y+nw.y+ulOffset, 0.0f ); verts[1].point.set( lowerRight.x+ne.x, upperLeft.y+ne.y+ulOffset, 0.0f ); verts[2].point.set( upperLeft.x-ne.x+ulOffset, lowerRight.y-ne.y, 0.0f ); verts[3].point.set( lowerRight.x-nw.x, lowerRight.y-nw.y, 0.0f ); for (S32 i=0; i<4; i++) verts[i].color = color; verts.unlock(); mDevice->setStateBlock(mRectFillSB); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 ); }
void GFXDrawUtil::drawSolidPlane( const GFXStateBlockDesc &desc, const Point3F &pos, const Point2F &size, const ColorI &color ) { GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, 4, GFXBufferTypeVolatile); verts.lock(); verts[0].point = pos + Point3F( -size.x / 2.0f, -size.y / 2.0f, 0 ); verts[0].color = color; verts[1].point = pos + Point3F( -size.x / 2.0f, size.y / 2.0f, 0 ); verts[1].color = color; verts[2].point = pos + Point3F( size.x / 2.0f, size.y / 2.0f, 0 ); verts[2].color = color; verts[3].point = pos + Point3F( size.x / 2.0f, -size.y / 2.0f, 0 ); verts[3].color = color; verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); mDevice->drawPrimitive( GFXTriangleFan, 0, 2 ); }
static PyObject* pyGBufferGroup_addVerts(pyGBufferGroup* self, PyObject* args) { PyObject* list; if (!PyArg_ParseTuple(args, "O", &list)) { PyErr_SetString(PyExc_TypeError, "addVertices expects a list of plGBufferVertex objects"); return NULL; } if (!PyList_Check(list)) { PyErr_SetString(PyExc_TypeError, "addVertices expects a list of plGBufferVertex objects"); return NULL; } std::vector<plGBufferVertex> verts(PyList_Size(list)); for (size_t i=0; i<verts.size(); i++) { if (!pyGBufferVertex_Check(PyList_GetItem(list, i))) { PyErr_SetString(PyExc_TypeError, "addVertices expects a list of plGBufferVertex objects"); return NULL; } verts[i] = *((pyGBufferVertex*)PyList_GetItem(list, i))->fThis; } self->fThis->addVertices(verts); Py_INCREF(Py_None); return Py_None; }
void GFXDrawUtil::drawPolygon( const GFXStateBlockDesc& desc, const Point3F* points, U32 numPoints, const ColorI& color, const MatrixF* xfm /* = NULL */ ) { const bool isWireframe = ( desc.fillMode == GFXFillWireframe ); const U32 numVerts = isWireframe ? numPoints + 1 : numPoints; GFXVertexBufferHandle< GFXVertexPC > verts( mDevice, numVerts, GFXBufferTypeVolatile ); verts.lock(); for( U32 i = 0; i < numPoints; ++ i ) { verts[ i ].point = points[ i ]; verts[ i ].color = color; } if( xfm ) { for( U32 i = 0; i < numPoints; ++ i ) xfm->mulP( verts[ i ].point ); } if( isWireframe ) { verts[ numVerts - 1 ].point = verts[ 0 ].point; verts[ numVerts - 1 ].color = color; } verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); if( desc.fillMode == GFXFillWireframe ) mDevice->drawPrimitive( GFXLineStrip, 0, numPoints ); else mDevice->drawPrimitive( GFXTriangleFan, 0, numPoints - 2 ); }
static PyObject* pyDrawableSpans_addVerts(pyDrawableSpans* self, PyObject* args) { int buf; PyObject* vlist; if (!PyArg_ParseTuple(args, "iO", &buf, &vlist)) { PyErr_SetString(PyExc_TypeError, "addVerts expects int, list"); return NULL; } if (!PyList_Check(vlist)) { PyErr_SetString(PyExc_TypeError, "addVerts expects int, list"); return NULL; } std::vector<plGBufferVertex> verts(PyList_Size(vlist)); for (size_t i=0; i<verts.size(); i++) { PyObject* vert = PyList_GetItem(vlist, i); if (!pyGBufferVertex_Check(vert)) { PyErr_SetString(PyExc_TypeError, "addVerts expects a list of plGBufferVertexes"); return NULL; } verts[i] = *((pyGBufferVertex*)vert)->fThis; } self->fThis->addVerts(buf, verts); Py_INCREF(Py_None); return Py_None; }
bool NFFParser::readFile() const{ ifstream input(fileLocation, ios::in); if (!input.good()){ std::cout << "Can't find my file!\n"; return false; } if (!input){ cout << "Unable to open file"; return false; } else{ std::string line; while (getline(input, line)){ std::vector<std::string> splitLine = split(line, ' '); std::string command = splitLine[0]; if (command == "s"){ Vec3f center = read3DVector(splitLine); float radius = static_cast<float>(atof(splitLine[4].c_str())); Sphere* s = new Sphere(center, radius); SceneObject* so = new SceneObject(scene->materialIndex, s); scene->octree->insertShape(so, scene->octree->root, 0); } else if (command == "c"){ float baseX = static_cast<float>(atof(splitLine[1].c_str())); float baseY = static_cast<float>(atof(splitLine[2].c_str())); float baseZ = static_cast<float>(atof(splitLine[3].c_str())); float baseRadius = static_cast<float>(atof(splitLine[4].c_str())); Vec3f base = Vec3f(baseX, baseY, baseZ); float apexX = static_cast<float>(atof(splitLine[5].c_str())); float apexY = static_cast<float>(atof(splitLine[6].c_str())); float apexZ = static_cast<float>(atof(splitLine[7].c_str())); float apexRadius = static_cast<float>(atof(splitLine[8].c_str())); Vec3f apex = Vec3f(apexX, apexY, apexZ); if (baseRadius == apexRadius){ Cylinder* c = new Cylinder(base, apex, baseRadius); SceneObject* so = new SceneObject(scene->materialIndex, static_cast<Primitive*>(c)); scene->octree->insertShape(so, scene->octree->root, 0); } else{ // @TODO cone code } } else if (command == "p"){ int numVerts = atoi(splitLine[1].c_str()); if (numVerts >= 3){ std::vector<Vec3f> verts(numVerts); for (int i = 0; i < numVerts; i++){ getline(input, line); std::vector<std::string> splitLine = split(line, ' '); verts[i] = read3DVector(splitLine); } Polygon* poly = new Polygon(verts); std::vector<Triangle*> triangles = poly->triangles; for (std::vector<int>::size_type itr = 0; itr != triangles.size(); itr++) { Triangle* t = triangles[itr]; SceneObject* so = new SceneObject(scene->materialIndex, static_cast<Primitive*>(t)); scene->octree->insertShape(so, scene->octree->root, 0); } } } else if (command == "pp"){ int numVerts = atoi(splitLine[1].c_str()); if (numVerts >= 3){ std::vector<Vec3f> verts(numVerts); std::vector<Vec3f> norms(numVerts); for (int i = 0; i < numVerts; i++){ getline(input, line); std::vector<std::string> splitLine = split(line, ' '); float x = static_cast<float>(atof(splitLine[0].c_str())); float y = static_cast<float>(atof(splitLine[1].c_str())); float z = static_cast<float>(atof(splitLine[2].c_str())); verts.push_back(Vec3f(x, y, z)); float nx = static_cast<float>(atof(splitLine[3].c_str())); float ny = static_cast<float>(atof(splitLine[4].c_str())); float nz = static_cast<float>(atof(splitLine[5].c_str())); norms.push_back(Vec3f(nx, ny, nz)); } Vec3f n = Vec3f(0.f, 0.f, 0.f); for (std::vector<int>::size_type itr = 0; itr != norms.size(); itr++) { n += norms[itr]; } n /= 3.f; Triangle* t = new Triangle(verts[0], verts[1], verts[2], n); SceneObject* so = new SceneObject(scene->materialIndex, static_cast<Primitive*>(t)); scene->octree->insertShape(so, scene->octree->root, 0); } } else if (command == "v"){ for (int i = 0; i < 6; i++){ getline(input, line); std::vector<std::string> splitLine = split(line, ' '); std::string command = splitLine[0]; if (command == "from"){ scene->from = read3DVector(splitLine); } else if (command == "at"){ scene->at = read3DVector(splitLine); } else if (command == "up"){ scene->up = read3DVector(splitLine); } else if (command == "angle"){ scene->fov =static_cast<float>(atof(splitLine[1].c_str())); } else if (command == "hither"){ scene->hither = static_cast<float>(atof(splitLine[1].c_str())); } else if (command == "resolution"){ scene->screenWidth = std::stoi(splitLine[1]); scene->screenHeight = std::stoi(splitLine[1]); } } } else if (command == "b"){ scene->bg = read3DVector(splitLine); } else if (command == "l"){ Light* const l = new Light(read3DVector(splitLine)); scene->lights.push_back(l); } else if (command == "f"){ float red = static_cast<float>(atof(splitLine[1].c_str())); float green = static_cast<float>(atof(splitLine[2].c_str())); float blue = static_cast<float>(atof(splitLine[3].c_str())); float kd = static_cast<float>(atof(splitLine[4].c_str())); float ks = static_cast<float>(atof(splitLine[5].c_str())); float shine = static_cast<float>(atof(splitLine[6].c_str())); float T = static_cast<float>(atof(splitLine[7].c_str())); float refraction = static_cast<float>(atof(splitLine[8].c_str())); Material* m = new Material(red, green, blue, kd, ks, shine, T, refraction); ++scene->materialIndex; // incrementation here on purpose scene->materials.push_back(m); } } printf("File reading done.\n"); input.close(); } return true; }
bool RawSaver::Save(DxRenderer* renderer, Mesh* mesh, const std::string& filename, std::string& errors) { if(!mesh){ errors += "Null mesh passed"; return false; } // get base name for all files const size_t dotPos = filename.rfind('.'); if(dotPos == filename.npos){ errors += "Invalid filename"; return false; } const std::string basepath = filename.substr(0, dotPos); std::string basename; const size_t slashPos = basepath.find_last_of("\\/"); if(slashPos != filename.npos){ basename = basepath.substr(slashPos + 1, basepath.size() - slashPos + 1); } else { basename = basepath; } // open index file std::ofstream fout(filename); if(!fout.is_open()){ errors += "Unable to create index file " + filename; return false; } // write vertices file std::string vertsPath = basepath + ".verts"; std::string vertsName = basename + ".verts"; std::ofstream verts(vertsPath, std::ios::binary); if(!verts.is_open()){ errors += "Unable to create vertices file"; return false; } ID3D11Buffer* vbuffer = mesh->GetVertexBuffer(); assert(vbuffer && "Missing vertex buffer"); HRESULT hr; // create a staging buffer to copy to ID3D11Buffer* vstaging; D3D11_BUFFER_DESC vdesc; vbuffer->GetDesc(&vdesc); vdesc.Usage = D3D11_USAGE_STAGING; vdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; vdesc.BindFlags = 0; hr = renderer->GetDevice()->CreateBuffer(&vdesc, nullptr, &vstaging); if(FAILED(hr)) { errors += "Unable to create staging vertex buffer"; return false; } ReleaseGuard<ID3D11Buffer> stguard(vstaging); renderer->GetImmediateContext()->CopyResource(vstaging, vbuffer); D3D11_MAPPED_SUBRESOURCE vmap = {0}; hr = renderer->GetImmediateContext()->Map(stguard.Get(), 0, D3D11_MAP_READ, 0, &vmap); if(FAILED(hr)) { errors += "Unable to map vertex buffer"; return false; } // write the data verts.write((char*)vmap.pData, vmap.RowPitch); renderer->GetImmediateContext()->Unmap(vbuffer, 0); fout << vertsName << std::endl; // write all subsets for(size_t i = 0; i < mesh->GetSubsetCount(); ++i) { std::ostringstream oss; oss << "_" << i << ".inds"; std::string subsetPath = basepath + oss.str(); std::string subsetName = basename + oss.str(); std::ofstream inds(subsetPath, std::ios::binary); if(!inds.is_open()){ errors += "Unable to create indices file"; return false; } ID3D11Buffer* ibuffer = mesh->GetSubset(i)->GetIndexBuffer(); assert(ibuffer && "Missing index buffer"); // create a staging buffer to copy to ID3D11Buffer* istaging; D3D11_BUFFER_DESC idesc; ibuffer->GetDesc(&idesc); idesc.Usage = D3D11_USAGE_STAGING; idesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; idesc.BindFlags = 0; hr = renderer->GetDevice()->CreateBuffer(&idesc, nullptr, &istaging); if(FAILED(hr)) { errors += "Unable to create staging index buffer"; return false; } ReleaseGuard<ID3D11Buffer> stindexguard(istaging); renderer->GetImmediateContext()->CopyResource(istaging, ibuffer); D3D11_MAPPED_SUBRESOURCE imap = {0}; hr = renderer->GetImmediateContext()->Map(stindexguard.Get(), 0, D3D11_MAP_READ, 0, &imap); if(FAILED(hr)) { errors += "Unable to map index buffer"; return false; } // write material std::ostringstream diffuseColorStr; const Material& material = mesh->GetSubset(i)->GetMaterial(); // diffuse color auto diffuseColor = material.GetDiffuseColor(); diffuseColorStr << diffuseColor.x << " " << diffuseColor.y << " " << diffuseColor.z; auto dcStr = diffuseColorStr.str(); unsigned strSize = dcStr.size(); inds.write((char*)&strSize, sizeof(unsigned)); inds.write((char*)dcStr.c_str(), dcStr.size()); // diffuse tex std::string texName = renderer->GetTextureManager().GetTextureName(material.GetDiffuse()); strSize = unsigned(texName.size()); inds.write((char*)&strSize, sizeof(unsigned)); inds.write((char*)texName.c_str(), texName.size()); // normal map std::string normalMapName = renderer->GetTextureManager().GetTextureName(material.GetNormalMap()); strSize = unsigned(normalMapName.size()); inds.write((char*)&strSize, sizeof(unsigned)); inds.write((char*)normalMapName.c_str(), normalMapName.size()); // alpha mask std::string maskMapName = renderer->GetTextureManager().GetTextureName(material.GetAlphaMask()); strSize = unsigned(maskMapName.size()); inds.write((char*)&strSize, sizeof(unsigned)); inds.write((char*)maskMapName.c_str(), maskMapName.size()); // spacular map std::string specularMapName = renderer->GetTextureManager().GetTextureName(material.GetSpecularMap()); strSize = unsigned(specularMapName.size()); inds.write((char*)&strSize, sizeof(unsigned)); inds.write((char*)specularMapName.c_str(), specularMapName.size()); // specular power const float power = material.GetSpecularPower(); inds.write((const char*)&power, sizeof(float)); // write the data inds.write((char*)imap.pData, imap.RowPitch); renderer->GetImmediateContext()->Unmap(ibuffer, 0); fout << subsetName << std::endl; } return true; }
void FontRenderBatcher::render( F32 rot, const Point2F &offset ) { if( mLength == 0 ) return; GFX->setStateBlock(mFontSB); for(U32 i = 0; i < GFX->getNumSamplers(); i++) GFX->setTexture(i, NULL); MatrixF rotMatrix; bool doRotation = rot != 0.f; if(doRotation) rotMatrix.set( EulerF( 0.0, 0.0, mDegToRad( rot ) ) ); // Write verts out. U32 currentPt = 0; GFXVertexBufferHandle<GFXVertexPCT> verts(GFX, mLength * 6, GFXBufferTypeVolatile); verts.lock(); for( S32 i = 0; i < mSheets.size(); i++ ) { // Do some early outs... if(!mSheets[i]) continue; if(!mSheets[i]->numChars) continue; mSheets[i]->startVertex = currentPt; const GFXTextureObject *tex = mFont->getTextureHandle(i); for( S32 j = 0; j < mSheets[i]->numChars; j++ ) { // Get some general info to proceed with... const CharMarker &m = mSheets[i]->charIndex[j]; const PlatformFont::CharInfo &ci = mFont->getCharInfo( m.c ); // Where are we drawing it? F32 drawY = offset.y + mFont->getBaseline() - ci.yOrigin * TEXT_MAG; F32 drawX = offset.x + m.x + ci.xOrigin; // Figure some values. const F32 texWidth = (F32)tex->getWidth(); const F32 texHeight = (F32)tex->getHeight(); const F32 texLeft = (F32)(ci.xOffset) / texWidth; const F32 texRight = (F32)(ci.xOffset + ci.width) / texWidth; const F32 texTop = (F32)(ci.yOffset) / texHeight; const F32 texBottom = (F32)(ci.yOffset + ci.height) / texHeight; const F32 fillConventionOffset = GFX->getFillConventionOffset(); const F32 screenLeft = drawX - fillConventionOffset; const F32 screenRight = drawX - fillConventionOffset + ci.width * TEXT_MAG; const F32 screenTop = drawY - fillConventionOffset; const F32 screenBottom = drawY - fillConventionOffset + ci.height * TEXT_MAG; // Build our vertices. We NEVER read back from the buffer, that's // incredibly slow, so for rotation do it into tmp. This code is // ugly as sin. Point3F tmp; tmp.set( screenLeft, screenTop, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texLeft, texTop ); currentPt++; tmp.set( screenLeft, screenBottom, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texLeft, texBottom ); currentPt++; tmp.set( screenRight, screenBottom, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texRight, texBottom ); currentPt++; tmp.set( screenRight, screenBottom, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texRight, texBottom ); currentPt++; tmp.set( screenRight, screenTop, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texRight, texTop ); currentPt++; tmp.set( screenLeft, screenTop, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texLeft, texTop ); currentPt++; } } verts->unlock(); AssertFatal(currentPt <= mLength * 6, "FontRenderBatcher::render - too many verts for length of string!"); GFX->setVertexBuffer(verts); GFX->setupGenericShaders( GFXDevice::GSAddColorTexture ); // Now do an optimal render! for( S32 i = 0; i < mSheets.size(); i++ ) { if(!mSheets[i]) continue; if(!mSheets[i]->numChars ) continue; GFX->setTexture( 0, mFont->getTextureHandle(i) ); GFX->drawPrimitive(GFXTriangleList, mSheets[i]->startVertex, mSheets[i]->numChars * 2); } }
void plSpanTemplate::prcParse(const pfPrcTag* tag) { if (tag->getName() != "plSpanTemplate") throw pfPrcTagException(__FILE__, __LINE__, tag->getName()); fFormat = tag->getParam("Format", "0").toUint(); const pfPrcTag* child = tag->getFirstChild(); while (child != NULL) { if (child->getName() == "Vertices") { fNumVerts = child->countChildren(); std::vector<Vertex> verts(fNumVerts); const pfPrcTag* vertChild = child->getFirstChild(); for (size_t i=0; i<fNumVerts; i++) { if (vertChild->getName() != "Vertex") throw pfPrcTagException(__FILE__, __LINE__, vertChild->getName()); verts[i].fColor1 = tag->getParam("Color1", "0").toUint(); verts[i].fColor2 = tag->getParam("Color2", "0").toUint(); verts[i].fWeightIdx = tag->getParam("WeightIdx", "0").toInt(); const pfPrcTag* subChild = vertChild->getFirstChild(); while (subChild != NULL) { if (subChild->getName() == "Position") { if (subChild->hasChildren()) verts[i].fPosition.prcParse(subChild->getFirstChild()); } else if (subChild->getName() == "Normal") { if (subChild->hasChildren()) verts[i].fNormal.prcParse(subChild->getFirstChild()); } else if (subChild->getName() == "UVWs") { if ((fFormat & kUVWMask) / 0x10 != subChild->countChildren()) throw pfPrcParseException(__FILE__, __LINE__, "Incorrect Number of UVW maps"); const pfPrcTag* uvwChild = subChild->getFirstChild(); for (size_t j=0; j<(size_t)((fFormat & kUVWMask) / 0x10); j++) { verts[i].fUVWs[j].prcParse(uvwChild); uvwChild = uvwChild->getNextSibling(); } } else if (subChild->getName() == "Weights") { std::list<plString> wgtList = subChild->getContents(); if (wgtList.size() != (fFormat & kWeightMask) / 0x100) throw pfPrcParseException(__FILE__, __LINE__, "Incorrect Number of Weights"); auto wgt = wgtList.begin(); for (size_t j=0; j<(size_t)((fFormat & kWeightMask) / 0x100); j++) verts[i].fWeights[j] = (*wgt++).toFloat(); } else { throw pfPrcTagException(__FILE__, __LINE__, subChild->getName()); } subChild = subChild->getNextSibling(); } vertChild = vertChild->getNextSibling(); } setVertices(verts); } else if (child->getName() == "Indices") { fNumTris = child->countChildren(); fIndices = new unsigned short[fNumTris * 3]; const pfPrcTag* idxChild = child->getFirstChild(); for (size_t i=0; i<(size_t)(fNumTris * 3); i += 3) { std::list<plString> idxList = idxChild->getContents(); if (idxList.size() != 3) throw pfPrcParseException(__FILE__, __LINE__, "Triangles should have exactly 3 indices"); auto idx_iter = idxList.begin(); fIndices[i] = (*idx_iter++).toUint(); fIndices[i+1] = (*idx_iter++).toUint(); fIndices[i+2] = (*idx_iter++).toUint(); idxChild = idxChild->getNextSibling(); } } else { throw pfPrcTagException(__FILE__, __LINE__, child->getName()); } child = child->getNextSibling(); } }
void ModelWriter::writeFace(SUMeshHelperRef mesh, const Transform& transform, bool front, bool textured) { size_t vertexCount=0; SUMeshHelperGetNumVertices(mesh,&vertexCount); vector<SUPoint3D> verts(vertexCount); SUMeshHelperGetVertices(mesh,vertexCount,verts.data(),&vertexCount); vector<SUVector3D> normals(vertexCount); SUMeshHelperGetNormals(mesh,vertexCount,normals.data(),&vertexCount); vector<SUPoint3D> textures(vertexCount); size_t triCount = 0; SUMeshHelperGetNumTriangles(mesh,&triCount); size_t gotIndices = 0; vector<size_t> indicies(triCount*3); SUResult res = SUMeshHelperGetVertexIndices(mesh,triCount*3,indicies.data(),&gotIndices); assert(res == SU_ERROR_NONE); if(textured) { if(front) { SUMeshHelperGetFrontSTQCoords(mesh,vertexCount,textures.data(),&vertexCount); } else { SUMeshHelperGetBackSTQCoords(mesh,vertexCount,textures.data(),&vertexCount); } } float normalScale = 1.0f; if(!front) { normalScale = -1.0f; } bool flip = !front; SUVector3D xFlipTest = xaxis * transform; if(xFlipTest.x < 0) { flip = !flip; } SUVector3D yFlipTest = yaxis * transform; if(yFlipTest.y < 0) { flip = !flip; } for(size_t t = 0; t < triCount; t++) { m_Faces << "f "; for(int i=0; i<3; i++) { int j = (t*3) + (flip ? 2-i : i); m_Faces << getIndexedPos(verts[indicies[j]]*transform) << "/"; if(textured) m_Faces << getIndexedTex(textures[indicies[j]]); m_Faces << "/" << getIndexedNormal(normals[indicies[j]]*normalScale*transform) << " "; } m_Faces << endl; } }
void copy_cells_archetypes(Complex2D & G_dst, GSRC const& G_src, VtxCorr& vtx_corr, CellCorr& cell_corr) { typedef grid_types<GSRC> src_gt; typedef typename src_gt::CellIterator src_cell_it; typedef typename src_gt::VertexOnCellIterator src_vertex_on_cell_it; typedef grid_types<Complex2D> gt; typedef gt::Cell Cell; typedef gt::cell_handle cell_handle; typedef gt::archetype_type dst_archetype; typedef typename src_gt::archetype_type src_archetype; typedef gt::archetype_handle src_arch_handle; typedef typename src_gt::archetype_handle dst_arch_handle; //typedef typename gt::BoundaryFacetIterator BdFacetIterator; friend_for_input cc(G_dst); // (2) copy archetypes typedef vertex_morphism<src_archetype, dst_archetype> arch_morphism; ::std::vector<arch_morphism> morphism; bijective_mapping<src_arch_handle, dst_arch_handle> arch_corr; typename src_gt::archetype_iterator arch_src = G_src.BeginArchetype(); for(; arch_src != G_src.EndArchetype() ; ++arch_src) { // dst_arch_handle a_dst = cc.add_archetype(); //G_dst.add_archetype(); src_arch_handle a_src = G_src.handle(arch_src); dst_archetype arch_dst; dst_arch_handle a_dst = cc.add_archetype(arch_dst, (*arch_src).NumOfVertices()); morphism.push_back(arch_morphism(*arch_src,G_dst.Archetype(a_dst))); ConstructGrid0(G_dst.Archetype(a_dst), G_src.Archetype(a_src), morphism.back()); arch_corr[a_src] = a_dst; } for(typename src_gt::CellIterator c_src = G_src.FirstCell(); ! c_src.IsDone(); ++c_src){ src_arch_handle a_src = G_src.archetype_of(*c_src); // dst_arch_handle a_dst = arch_corr(a_src); cell_handle pc = cc._new_cell(GrAL::size<typename src_gt::Vertex>(*c_src)); // correct arch gets selected automatically a_dst); cell_corr[c_src.handle()] = pc; gt::Cell c_dst(G_dst, pc); typedef cell2d_connectivity c2d; c2d::vertex_list& verts (cc._cell_vertices(pc)); src_vertex_on_cell_it vc_src((*c_src)); // .FirstVertex()); typename grid_types<src_archetype>::VertexIterator lv_src(G_src.Archetype(a_src).FirstVertex()); for(; ! vc_src.IsDone(); ++vc_src, ++lv_src) { int lv = morphism[a_src][lv_src.handle()]; verts [lv] = vtx_corr[vc_src.handle()]; } // initialize cell neighbors cell_handle boundary(cc.outer_cell_handle()); // invalid reference to a cell // (used to mark unknown neighbours) c2d::cell_list& neighb(cc._cell_neighbours(pc)); for(int ln = 0; ln < c_dst.NumOfFacets(); ++ln) neighb[ln] = boundary; // correct neighbour is calculated later } }
void POVPainter::drawColorMesh(const Mesh & mesh, int mode) { // Now we draw the given mesh to the OpenGL widget switch (mode) { case 0: // Filled triangles break; case 1: // Lines break; case 2: // Points break; } // Render the triangles of the mesh std::vector<Eigen::Vector3f> v = mesh.vertices(); std::vector<Eigen::Vector3f> n = mesh.normals(); std::vector<Color3f> c = mesh.colors(); // If there are no triangles then don't bother doing anything if (v.size() == 0 || v.size() != c.size()) return; QString vertsStr, ivertsStr, normsStr, texturesStr; QTextStream verts(&vertsStr); verts << "vertex_vectors{" << v.size() << ",\n"; QTextStream iverts(&ivertsStr); iverts << "face_indices{" << v.size() / 3 << ",\n"; QTextStream norms(&normsStr); norms << "normal_vectors{" << n.size() << ",\n"; QTextStream textures(&texturesStr); textures << "texture_list{" << c.size() << ",\n"; for(unsigned int i = 0; i < v.size(); ++i) { verts << "<" << v[i].x() << "," << v[i].y() << "," << v[i].z() << ">"; norms << "<" << n[i].x() << "," << n[i].y() << "," << n[i].z() << ">"; textures << "texture{pigment{rgbt<" << c[i].red() << "," << c[i].green() << "," << c[i].blue() << "," << 1.0 - d->color.alpha() << ">}}"; if (i != v.size()-1) { verts << ", "; norms << ", "; textures << ",\n"; } if (i != 0 && i%3 == 0) { verts << '\n'; norms << '\n'; } } // Now to write out the indices for (unsigned int i = 0; i < v.size(); i += 3) { iverts << "<" << i << "," << i+1 << "," << i+2 << ">"; iverts << "," << i << "," << i+1 << "," << i+2; if (i != v.size()-3) iverts << ", "; if (i != 0 && ((i+1)/3)%3 == 0) iverts << '\n'; } // Now to close off all the arrays verts << "\n}"; norms << "\n}"; iverts << "\n}"; textures << "\n}"; // Now to write out the full mesh - could be pretty big... *(d->output) << "mesh2 {\n" << vertsStr << '\n' << normsStr << '\n' << texturesStr << '\n' << ivertsStr << '\n' << "}\n\n"; }
void Postprocessing_DrawRainyGlass(Texture& renderTarget, Texture& scene) { Texture dropletTarget = RenderTexturePool::Get(256, 256); // Clear droplet render target to default front-facing direction const Color frontClearColor(0.5f /* x == 0 */, 0.5f /* y = 0 */, 1.0f /* z = 1 */, 0.0f); dropletTarget.BeginDrawing(&frontClearColor); // Evaporation if (rain->dropletBuffer.IsValid()) { if (rain->rainEvaporation > 0.02f) // Apply rain evaporation { rain->material.SetTechnique("rain_evaporation"); rain->rainEvaporation = 0; } else // Just copy previous buffer (skip evaporation step this time) { rain->material.SetTechnique("copy_texture"); } rain->material.SetTextureParameter("ColorMap", rain->dropletBuffer, Sampler::DefaultPostprocess); rain->material.DrawFullscreenQuad(); } // Droplets const Vec2 sizeScale( (float) dropletTarget.GetWidth(), (float) dropletTarget.GetHeight() ); while (rain->deltaTime > 0.0f) { const float stepDeltaTime = min(rain->deltaTime, 1 / 60.0f); rain->deltaTime -= stepDeltaTime; Postprocessing_UpdateRainyGlassStep(stepDeltaTime); const unsigned int numDroplets = rain->droplets.size(); if (!numDroplets) continue; std::vector<Vec2> verts(numDroplets * 4); std::vector<Vec2> tex(numDroplets * 4); std::vector<unsigned short> indices(numDroplets * 6); int currVertexIndex = 0; unsigned short* currIndex = &indices[0]; std::vector<RainyGlass::Droplet>::iterator dropletsEnd = rain->droplets.end(); for (std::vector<RainyGlass::Droplet>::iterator it = rain->droplets.begin(); it != dropletsEnd; ++it) { Vec2 size = Vec2(it->size, it->size); Vec2 pos = it->pos - size * 0.5f; size *= sizeScale; pos *= sizeScale; Vec2* currVertex = &verts[currVertexIndex]; *(currVertex++) = pos; *(currVertex++) = pos + Vec2(size.x, 0.0f); *(currVertex++) = pos + size; *(currVertex++) = pos + Vec2(0.0f, size.y); Vec2* currTex = &tex[currVertexIndex]; (currTex++)->Set(0.0f, 0.0f); (currTex++)->Set(1.0f, 0.0f); (currTex++)->Set(1.0f, 1.0f); (currTex++)->Set(0.0f, 1.0f); *(currIndex++) = currVertexIndex; *(currIndex++) = currVertexIndex + 1; *(currIndex++) = currVertexIndex + 2; *(currIndex++) = currVertexIndex; *(currIndex++) = currVertexIndex + 2; *(currIndex++) = currVertexIndex + 3; currVertexIndex += 4; } Shape::DrawParams drawParams; drawParams.SetGeometryType(Shape::Geometry::Type_Triangles); drawParams.SetNumVerts(verts.size()); drawParams.SetPosition(&verts[0], sizeof(Vec2)); drawParams.SetTexCoord(&tex[0], 0, sizeof(Vec2)); drawParams.SetIndices(indices.size(), &indices[0]); Material& defaultMaterial = App::GetDefaultMaterial(); defaultMaterial.SetTechnique("tex_col"); defaultMaterial.SetFloatParameter("Color", (const float*) &Color::White, 4); defaultMaterial.SetTextureParameter("ColorMap", rain->dropletTexture); defaultMaterial.Draw(&drawParams); } dropletTarget.EndDrawing(); // Swap droplet buffer if (rain->dropletBuffer.IsValid()) RenderTexturePool::Release(rain->dropletBuffer); rain->dropletBuffer = dropletTarget; // Apply droplet buffer distortion to scene renderTarget.BeginDrawing(); Sampler colorSampler = Sampler::DefaultPostprocess; colorSampler.minFilterLinear = true; colorSampler.magFilterLinear = true; rain->material.SetTechnique("rain_distortion"); rain->material.SetFloatParameter("DropletColor", (const float*) &rain->dropletColor, 4); rain->material.SetTextureParameter("ColorMap", scene, colorSampler); rain->material.SetTextureParameter("NormalMap", rain->dropletBuffer); rain->material.DrawFullscreenQuad(); renderTarget.EndDrawing(); }
void GuiMaterialCtrl::onRender( Point2I offset, const RectI &updateRect ) { Parent::onRender( offset, updateRect ); if ( !mMaterialInst ) return; // Draw a quad with the material assigned GFXVertexBufferHandle<GFXVertexPCT> verts( GFX, 4, GFXBufferTypeVolatile ); verts.lock(); F32 screenLeft = updateRect.point.x; F32 screenRight = (updateRect.point.x + updateRect.extent.x); F32 screenTop = updateRect.point.y; F32 screenBottom = (updateRect.point.y + updateRect.extent.y); const F32 fillConv = GFX->getFillConventionOffset(); verts[0].point.set( screenLeft - fillConv, screenTop - fillConv, 0.f ); verts[1].point.set( screenRight - fillConv, screenTop - fillConv, 0.f ); verts[2].point.set( screenLeft - fillConv, screenBottom - fillConv, 0.f ); verts[3].point.set( screenRight - fillConv, screenBottom - fillConv, 0.f ); verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI( 255, 255, 255, 255 ); verts[0].texCoord.set( 0.0f, 0.0f ); verts[1].texCoord.set( 1.0f, 0.0f ); verts[2].texCoord.set( 0.0f, 1.0f ); verts[3].texCoord.set( 1.0f, 1.0f ); verts.unlock(); GFX->setVertexBuffer( verts ); MatrixSet matSet; matSet.setWorld(GFX->getWorldMatrix()); matSet.setView(GFX->getViewMatrix()); matSet.setProjection(GFX->getProjectionMatrix()); MatrixF cameraMatrix( true ); F32 left, right, top, bottom, nearPlane, farPlane; bool isOrtho; GFX->getFrustum( &left, &right, &bottom, &top, &nearPlane, &farPlane, &isOrtho ); Frustum frust( isOrtho, left, right, top, bottom, nearPlane, farPlane, cameraMatrix ); SceneRenderState state ( gClientSceneGraph, SPT_Diffuse, SceneCameraState( GFX->getViewport(), frust, GFX->getWorldMatrix(), GFX->getProjectionMatrix() ), gClientSceneGraph->getDefaultRenderPass(), false ); SceneData sgData; sgData.init( &state ); sgData.wireframe = false; // Don't wireframe this. while( mMaterialInst->setupPass( &state, sgData ) ) { mMaterialInst->setSceneInfo( &state, sgData ); mMaterialInst->setTransforms( matSet, &state ); GFX->setupGenericShaders(); GFX->drawPrimitive( GFXTriangleStrip, 0, 2 ); } // Clean up GFX->setShader( NULL ); GFX->setTexture( 0, NULL ); }
bool PhysicsGeometry::load(FS::IFile& file) { Header header; file.read(&header, sizeof(header)); if (header.m_magic != HEADER_MAGIC || header.m_version > (uint32)Versions::LAST) { return false; } auto* phy_manager = m_resource_manager.get(ResourceManager::PHYSICS); PhysicsSystem& system = static_cast<PhysicsGeometryManager*>(phy_manager)->getSystem(); uint32 num_verts; Array<Vec3> verts(getAllocator()); file.read(&num_verts, sizeof(num_verts)); verts.resize(num_verts); file.read(&verts[0], sizeof(verts[0]) * verts.size()); m_is_convex = header.m_convex != 0; if (!m_is_convex) { physx::PxTriangleMeshGeometry* geom = LUMIX_NEW(getAllocator(), physx::PxTriangleMeshGeometry)(); m_geometry = geom; uint32 num_indices; Array<uint32> tris(getAllocator()); file.read(&num_indices, sizeof(num_indices)); tris.resize(num_indices); file.read(&tris[0], sizeof(tris[0]) * tris.size()); physx::PxTriangleMeshDesc meshDesc; meshDesc.points.count = num_verts; meshDesc.points.stride = sizeof(physx::PxVec3); meshDesc.points.data = &verts[0]; meshDesc.triangles.count = num_indices / 3; meshDesc.triangles.stride = 3 * sizeof(physx::PxU32); meshDesc.triangles.data = &tris[0]; OutputStream writeBuffer(getAllocator()); system.getCooking()->cookTriangleMesh(meshDesc, writeBuffer); InputStream readBuffer(writeBuffer.data, writeBuffer.size); geom->triangleMesh = system.getPhysics()->createTriangleMesh(readBuffer); } else { physx::PxConvexMeshGeometry* geom = LUMIX_NEW(getAllocator(), physx::PxConvexMeshGeometry)(); m_geometry = geom; physx::PxConvexMeshDesc meshDesc; meshDesc.points.count = verts.size(); meshDesc.points.stride = sizeof(Vec3); meshDesc.points.data = &verts[0]; meshDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX; OutputStream writeBuffer(getAllocator()); bool status = system.getCooking()->cookConvexMesh(meshDesc, writeBuffer); if (!status) { LUMIX_DELETE(getAllocator(), geom); m_geometry = nullptr; return false; } InputStream readBuffer(writeBuffer.data, writeBuffer.size); physx::PxConvexMesh* mesh = system.getPhysics()->createConvexMesh(readBuffer); geom->convexMesh = mesh; } m_size = file.size(); return true; }
/* ================ idRenderWorldLocal::ParseModel ================ */ idRenderModel* idRenderWorldLocal::ParseModel( idLexer* src, const char* mapName, ID_TIME_T mapTimeStamp, idFile* fileOut ) { idToken token; src->ExpectTokenString( "{" ); // parse the name src->ExpectAnyToken( &token ); idRenderModel* model = renderModelManager->AllocModel(); model->InitEmpty( token ); if( fileOut != NULL ) { // write out the type so the binary reader knows what to instantiate fileOut->WriteString( "shadowmodel" ); fileOut->WriteString( token ); } int numSurfaces = src->ParseInt(); if( numSurfaces < 0 ) { src->Error( "R_ParseModel: bad numSurfaces" ); } for( int i = 0; i < numSurfaces; i++ ) { src->ExpectTokenString( "{" ); src->ExpectAnyToken( &token ); modelSurface_t surf; surf.shader = declManager->FindMaterial( token ); ( ( idMaterial* )surf.shader )->AddReference(); srfTriangles_t* tri = R_AllocStaticTriSurf(); surf.geometry = tri; tri->numVerts = src->ParseInt(); tri->numIndexes = src->ParseInt(); // parse the vertices idTempArray<float> verts( tri->numVerts * 8 ); for( int j = 0; j < tri->numVerts; j++ ) { src->Parse1DMatrix( 8, &verts[j * 8] ); } // parse the indices idTempArray<triIndex_t> indexes( tri->numIndexes ); for( int j = 0; j < tri->numIndexes; j++ ) { indexes[j] = src->ParseInt(); } #if 1 // find the island that each vertex belongs to idTempArray<int> vertIslands( tri->numVerts ); idTempArray<bool> trisVisited( tri->numIndexes ); vertIslands.Zero(); trisVisited.Zero(); int numIslands = 0; for( int j = 0; j < tri->numIndexes; j += 3 ) { if( trisVisited[j] ) { continue; } int islandNum = ++numIslands; vertIslands[indexes[j + 0]] = islandNum; vertIslands[indexes[j + 1]] = islandNum; vertIslands[indexes[j + 2]] = islandNum; trisVisited[j] = true; idList<int> queue; queue.Append( j ); for( int n = 0; n < queue.Num(); n++ ) { int t = queue[n]; for( int k = 0; k < tri->numIndexes; k += 3 ) { if( trisVisited[k] ) { continue; } bool connected = indexes[t + 0] == indexes[k + 0] || indexes[t + 0] == indexes[k + 1] || indexes[t + 0] == indexes[k + 2] || indexes[t + 1] == indexes[k + 0] || indexes[t + 1] == indexes[k + 1] || indexes[t + 1] == indexes[k + 2] || indexes[t + 2] == indexes[k + 0] || indexes[t + 2] == indexes[k + 1] || indexes[t + 2] == indexes[k + 2]; if( connected ) { vertIslands[indexes[k + 0]] = islandNum; vertIslands[indexes[k + 1]] = islandNum; vertIslands[indexes[k + 2]] = islandNum; trisVisited[k] = true; queue.Append( k ); } } } } // center the texture coordinates for each island for maximum 16-bit precision for( int j = 1; j <= numIslands; j++ ) { float minS = idMath::INFINITY; float minT = idMath::INFINITY; float maxS = -idMath::INFINITY; float maxT = -idMath::INFINITY; for( int k = 0; k < tri->numVerts; k++ ) { if( vertIslands[k] == j ) { minS = Min( minS, verts[k * 8 + 3] ); maxS = Max( maxS, verts[k * 8 + 3] ); minT = Min( minT, verts[k * 8 + 4] ); maxT = Max( maxT, verts[k * 8 + 4] ); } } const float averageS = idMath::Ftoi( ( minS + maxS ) * 0.5f ); const float averageT = idMath::Ftoi( ( minT + maxT ) * 0.5f ); for( int k = 0; k < tri->numVerts; k++ ) { if( vertIslands[k] == j ) { verts[k * 8 + 3] -= averageS; verts[k * 8 + 4] -= averageT; } } } #endif R_AllocStaticTriSurfVerts( tri, tri->numVerts ); for( int j = 0; j < tri->numVerts; j++ ) { tri->verts[j].xyz[0] = verts[j * 8 + 0]; tri->verts[j].xyz[1] = verts[j * 8 + 1]; tri->verts[j].xyz[2] = verts[j * 8 + 2]; tri->verts[j].SetTexCoord( verts[j * 8 + 3], verts[j * 8 + 4] ); tri->verts[j].SetNormal( verts[j * 8 + 5], verts[j * 8 + 6], verts[j * 8 + 7] ); } R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); for( int j = 0; j < tri->numIndexes; j++ ) { tri->indexes[j] = indexes[j]; } src->ExpectTokenString( "}" ); // add the completed surface to the model model->AddSurface( surf ); } src->ExpectTokenString( "}" ); model->FinishSurfaces(); if( fileOut != NULL && model->SupportsBinaryModel() && r_binaryLoadRenderModels.GetBool() ) { model->WriteBinaryModel( fileOut, &mapTimeStamp ); } return model; }
void FrustumCullingTask::FrustrumCull(CCamera* cam, BaseState* state) { Renderer* renderer = Renderer::getInstance(); // Points of the AABB in world space std::vector<Vector3> verts(8); Vector3 origin, scaledHalfVec, rotatedX, rotatedY, rotatedZ; Quaternion rot; std::vector<CRenderer*>* deferredQueue; std::vector<CRenderer*>* forwardQueue; std::vector<CRenderer*>* diffuseQueue; std::vector<CRenderer*>* fontQueue; std::vector<CLight*>* lightQueue; //the only thread sensitive area should be here { ThreadUtils::ThreadLockVisitor tlv(4); deferredQueue = &renderer->mMapDeferredQueues[cam]; forwardQueue = &renderer->mMapForwardQueues[cam]; diffuseQueue = &renderer->mMapDiffuseQueues[cam]; fontQueue = &renderer->mMapFontQueues[cam]; lightQueue = &renderer->mMapLightQueues[cam]; } const std::list<CRenderer*>* listRenderers = state->GetListOfComponentsOfType<CRenderer>(); if (listRenderers) { // Get vertices in world space for (auto& iter : *listRenderers) { if (!iter->isEnabled() || !iter->mMesh.Valid()) continue; origin = iter->GetMesh()->GetOrigin(); rot = iter->gameObject->transform->GetRotationQuaternion(); scaledHalfVec = iter->GetMesh()->GetAABB().maxPoint - origin; scaledHalfVec *= iter->gameObject->transform->scale; origin *= iter->gameObject->transform->scale; rotatedX = rot.RotatedVector(Vector3::cXAxis * scaledHalfVec.x); rotatedY = rot.RotatedVector(Vector3::cYAxis * scaledHalfVec.y); rotatedZ = rot.RotatedVector(Vector3::cZAxis * scaledHalfVec.z); rot.RotateVector(&origin); origin += iter->gameObject->transform->GetGlobalPosition(); // + + + verts[0] = origin + rotatedX + rotatedY + rotatedZ; // + + - verts[1] = origin + rotatedX + rotatedY - rotatedZ; // + - + verts[2] = origin + rotatedX - rotatedY + rotatedZ; // - + + verts[3] = origin - rotatedX + rotatedY + rotatedZ; // - - + verts[4] = origin - rotatedX - rotatedY + rotatedZ; // - + - verts[5] = origin - rotatedX + rotatedY - rotatedZ; // + - - verts[6] = origin + rotatedX - rotatedY - rotatedZ; // - - - verts[7] = origin - rotatedX - rotatedY - rotatedZ; // AABB cull check if (cam->CullAABB(verts)) { if (iter->mymeta() == CMeshRenderer::getmeta() || iter->mymeta() == CSkinMeshRenderer::getmeta()) deferredQueue->push_back(iter); else if (iter->mymeta() == CForwardRenderer::getmeta()) forwardQueue->push_back(iter); else if (iter->mymeta() == CDiffuseRenderer::getmeta()) diffuseQueue->push_back(iter); else if (iter->mymeta() == CFontRenderer::getmeta()) fontQueue->push_back(iter); } } } const std::list<CLight*>* listLight = state->GetListOfComponentsOfType<CLight>(); if (listLight) { // Iterate through all Lights for (auto& light : *listLight) { if (!light->isEnabled()) continue; if (light->mLightType == CLight::DIRECTIONAL) { lightQueue->push_back(light); continue; } Vector3 lightPos = light->gameObject->transform->GetGlobalPosition(); if (cam->CullSphere(lightPos, light->GetRange())) lightQueue->push_back(light); } } }