void Chunk::addCube(Batch& batch, uint8_t x, uint8_t y, uint8_t z) { std::vector<glm::vec3> vertices(6 * 6); std::vector<glm::vec2> texCoords(6 * 6); glm::vec3 v0(x, y, z); glm::vec3 v1(x, y + 1.0f, z); glm::vec3 v2(x + 1.0f, y, z); glm::vec3 v3(x + 1.0f, y + 1.0f, z); glm::vec3 v4(x, y + 1.0f, z + 1.0f); glm::vec3 v5(x, y, z + 1.0f); glm::vec3 v6(x + 1.0f, y, z + 1.0f); glm::vec3 v7(x + 1.0f, y + 1.0f, z + 1.0f); glm::vec2 t0(0.0f, 0.0f); glm::vec2 t1(0.0f, 1.0f); glm::vec2 t2(1.0f, 0.0f); glm::vec2 t3(1.0f, 1.0f); // Front Face vertices.push_back(v1); vertices.push_back(v0); vertices.push_back(v2); texCoords.push_back(t1); texCoords.push_back(t0); texCoords.push_back(t2); vertices.push_back(v2); vertices.push_back(v3); vertices.push_back(v1); texCoords.push_back(t2); texCoords.push_back(t3); texCoords.push_back(t1); // Right Face vertices.push_back(v3); vertices.push_back(v2); vertices.push_back(v6); texCoords.push_back(t1); texCoords.push_back(t0); texCoords.push_back(t2); vertices.push_back(v6); vertices.push_back(v7); vertices.push_back(v3); texCoords.push_back(t2); texCoords.push_back(t3); texCoords.push_back(t1); // Back Face vertices.push_back(v7); vertices.push_back(v6); vertices.push_back(v5); texCoords.push_back(t1); texCoords.push_back(t0); texCoords.push_back(t2); vertices.push_back(v5); vertices.push_back(v4); vertices.push_back(v7); texCoords.push_back(t2); texCoords.push_back(t3); texCoords.push_back(t1); // Left Face vertices.push_back(v4); vertices.push_back(v5); vertices.push_back(v0); texCoords.push_back(t1); texCoords.push_back(t0); texCoords.push_back(t2); vertices.push_back(v0); vertices.push_back(v1); vertices.push_back(v4); texCoords.push_back(t2); texCoords.push_back(t3); texCoords.push_back(t1); // Top Face vertices.push_back(v4); vertices.push_back(v1); vertices.push_back(v3); texCoords.push_back(t1); texCoords.push_back(t0); texCoords.push_back(t2); vertices.push_back(v3); vertices.push_back(v7); vertices.push_back(v4); texCoords.push_back(t2); texCoords.push_back(t3); texCoords.push_back(t1); // Bottom Face vertices.push_back(v0); vertices.push_back(v5); vertices.push_back(v6); texCoords.push_back(t1); texCoords.push_back(t0); texCoords.push_back(t2); vertices.push_back(v6); vertices.push_back(v2); vertices.push_back(v0); texCoords.push_back(t2); texCoords.push_back(t3); texCoords.push_back(t1); batch.vertices(vertices); batch.textures(texCoords); }
void Tesselator::addContour(const std::vector<TVec3d>& pts, std::vector<std::vector<TVec2f> > textureCoordinatesLists ) { unsigned int len = pts.size(); if ( len < 3 ) return; for (size_t i = 0; i < textureCoordinatesLists.size(); i++) { std::vector<TVec2f>& texCoords = textureCoordinatesLists.at(i); if (texCoords.size() != pts.size()) { if (!texCoords.empty()) { CITYGML_LOG_ERROR(_logger, "Invalid call to 'addContour'. The number of texture coordinates in list " << i << " (" << texCoords.size() << ") " "does not match the number of vertices (" << pts.size() << "). The texture coordinates list will be resized which may cause invalid texture coordinates."); } texCoords.resize(pts.size(), TVec2f(0.f, 0.f)); } } for (size_t i = 0; i < std::max(_texCoordsLists.size(), textureCoordinatesLists.size()); i++) { if (i >= _texCoordsLists.size()) { std::vector<TVec2f> texCoords(_vertices.size(), TVec2f(0.f, 0.f)); texCoords.insert(texCoords.end(), textureCoordinatesLists.at(i).begin(), textureCoordinatesLists.at(i).end()); _texCoordsLists.push_back(texCoords); } else if (i >= textureCoordinatesLists.size()) { _texCoordsLists.at(i).resize(_texCoordsLists.at(i).size() + pts.size(), TVec2f(0.f, 0.f)); } else { _texCoordsLists.at(i).insert(_texCoordsLists.at(i).end(), textureCoordinatesLists.at(i).begin(), textureCoordinatesLists.at(i).end()); } } unsigned int pos = _vertices.size(); gluTessBeginContour( _tobj ); for ( unsigned int i = 0; i < len; i++ ) { _vertices.push_back( pts[i] ); _indices.push_back(pos + i); gluTessVertex( _tobj, &(_vertices.back()[0]), &_indices.back() ); } gluTessEndContour( _tobj ); #ifndef NDEBUG for (size_t i = 0; i < _texCoordsLists.size(); i++) { assert(_texCoordsLists.at(i).size() == _vertices.size()); } #endif }
//-------------------------------------------------------------------------------- rectangle::rectangle(vec2 size, vec3 position) : m_coords(vec2(), vec2()) { m_size = size; m_position = position; m_color = vec4(.9f,.9f,.9f,1); m_buffer.reset(new bufferObject(GL_ARRAY_BUFFER)); m_coords = texCoords(vec2(0,1), vec2(1,0)); m_vertices.reset(new vertex[4]); setup(); buffer(); }
osg::ref_ptr<osg::Drawable> myQuad () { osg::ref_ptr<osg::Geode> geode (new osg::Geode()); osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry()); osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array()); vertices->push_back (osg::Vec3 ( 1.0, 0.0, 0.0)); vertices->push_back (osg::Vec3 ( 1.0, 0.0, 1.0)); vertices->push_back (osg::Vec3 ( 0.0, 0.0, 1.0)); vertices->push_back (osg::Vec3 (0.0, 0.0, 0.0)); geometry->setVertexArray (vertices.get()); // All vertices are white this time (it's hard to see that we have two // textures with all the colors...) osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array()); colors->push_back (osg::Vec4 (1.0f, 1.0f, 1.0f, 1.0f)); geometry->setColorArray (colors.get()); geometry->setColorBinding (osg::Geometry::BIND_OVERALL); osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array()); normals->push_back (osg::Vec3 (0.0f, -1.0f, 0.0f)); geometry->setNormalArray (normals.get()); geometry->setNormalBinding (osg::Geometry::BIND_OVERALL); osg::ref_ptr<osg::Vec2Array> texCoords (new osg::Vec2Array()); texCoords->push_back (osg::Vec2 (0.0, 0.0)); texCoords->push_back (osg::Vec2 (0.0, 1.0)); texCoords->push_back (osg::Vec2 (1.0, 1.0)); texCoords->push_back (osg::Vec2 (1.0, 0.0)); // Here, the two texture units (0 and 1) share the same texture coordinates. geometry->setTexCoordArray (0, texCoords.get()); geometry->setTexCoordArray (1, texCoords.get()); // Back to the usual: setup a primitive set and add the geometry to the geode. geometry->addPrimitiveSet( new osg::DrawArrays (osg::PrimitiveSet::QUADS, // how to render? 0, // index of first vertex vertices->size())); // how many vertices? // geode->addDrawable (geometry.get()); return geometry.get(); }
TriMesh<FloatType> Shapes<FloatType>::quad(const vec3<FloatType> &p0, const vec3<FloatType> &p1, const vec3<FloatType> &p2, const vec3<FloatType> &p3, const vec4<FloatType>& color) { std::vector<vec3<FloatType>> vertices = { p0, p1, p2, p3 }; std::vector<UINT> indices = { 0, 1, 2, 0, 2, 3 }; std::vector<vec3<FloatType>> normals = { ((p1 - p0) ^ (p3 - p0)).getNormalized(), ((p0 - p1) ^ (p2 - p1)).getNormalized(), ((p1 - p2) ^ (p3 - p2)).getNormalized(), ((p0 - p3) ^ (p2 - p3)).getNormalized() }; std::vector<vec2<FloatType>> texCoords(4); std::vector<vec4<FloatType>> colors = { color, color, color, color }; texCoords[0] = vec2<FloatType>(1.0f, 1.0f); texCoords[1] = vec2<FloatType>(0.0f, 1.0f); texCoords[2] = vec2<FloatType>(0.0f, 0.0f); texCoords[3] = vec2<FloatType>(1.0f, 0.0f); return TriMesh<FloatType>(vertices.size(), indices.size(), vertices.data(), indices.data(), colors.data(), normals.data(), texCoords.data()); }
void Layer::drawWithOpenGL( const sp<const DisplayDevice>& hw, const Region& clip) const { const uint32_t fbHeight = hw->getHeight(); const State& s(getDrawingState()); computeGeometry(hw, mMesh); /* * NOTE: the way we compute the texture coordinates here produces * different results than when we take the HWC path -- in the later case * the "source crop" is rounded to texel boundaries. * This can produce significantly different results when the texture * is scaled by a large amount. * * The GL code below is more logical (imho), and the difference with * HWC is due to a limitation of the HWC API to integers -- a question * is suspend is whether we should ignore this problem or revert to * GL composition when a buffer scaling is applied (maybe with some * minimal value)? Or, we could make GL behave like HWC -- but this feel * like more of a hack. */ const Rect win(computeBounds()); float left = float(win.left) / float(s.active.w); float top = float(win.top) / float(s.active.h); float right = float(win.right) / float(s.active.w); float bottom = float(win.bottom) / float(s.active.h); // TODO: we probably want to generate the texture coords with the mesh // here we assume that we only have 4 vertices Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>()); texCoords[0] = vec2(left, 1.0f - top); texCoords[1] = vec2(left, 1.0f - bottom); texCoords[2] = vec2(right, 1.0f - bottom); texCoords[3] = vec2(right, 1.0f - top); RenderEngine& engine(mFlinger->getRenderEngine()); engine.setDither(needsDithering()); engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha); engine.drawMesh(mMesh); engine.disableBlending(); }
TriMesh<FloatType> Shapes<FloatType>::rectangleZ(const vec2<FloatType> &start, const vec2<FloatType> &end, FloatType zValue, const vec4<FloatType>& color) { std::vector<vec3<FloatType>> vertices(4); std::vector<UINT> indices = { 0, 1, 2, 0, 2, 3 }; std::vector<vec3<FloatType>> normals(4, vec3f::eZ); std::vector<vec2<FloatType>> texCoords(4); std::vector<vec4<FloatType>> colors = { color, color, color, color }; vertices[0] = vec3<FloatType>(start.x, start.y, zValue); vertices[1] = vec3<FloatType>(end.x, start.y, zValue); vertices[2] = vec3<FloatType>(end.x, end.y, zValue); vertices[3] = vec3<FloatType>(start.x, end.y, zValue); texCoords[0] = vec2<FloatType>(0.0f, 0.0f); texCoords[1] = vec2<FloatType>(1.0f, 0.0f); texCoords[2] = vec2<FloatType>(1.0f, 1.0f); texCoords[3] = vec2<FloatType>(0.0f, 1.0f); return TriMesh<FloatType>(vertices.size(), indices.size(), vertices.data(), indices.data(), colors.data(), normals.data(), texCoords.data()); }
void Layer::drawProtectedImage(const sp<const DisplayDevice>& hw, const Region& clip) const { const State& s(getDrawingState()); const Transform tr(hw->getTransform() * s.transform); const uint32_t hw_h = hw->getHeight(); Rect win(s.active.w, s.active.h); if (!s.active.crop.isEmpty()) { win.intersect(s.active.crop, &win); } int w = win.getWidth(); int h = win.getHeight(); if (w > h) { win.left += ((w - h) / 2); win.right = win.left + h; } else { win.top += ((h - w) / 2); win.bottom = win.top + w; } Mesh::VertexArray<vec2> position(mMesh.getPositionArray<vec2>()); position[0] = tr.transform(win.left, win.top); position[1] = tr.transform(win.left, win.bottom); position[2] = tr.transform(win.right, win.bottom); position[3] = tr.transform(win.right, win.top); for (size_t i=0 ; i<4 ; i++) { position[i].y = hw_h - position[i].y; } Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>()); texCoords[0] = vec2(0, 0); texCoords[1] = vec2(0, 1); texCoords[2] = vec2(1, 1); texCoords[3] = vec2(1, 0); RenderEngine& engine(mFlinger->getRenderEngine()); engine.setupLayerProtectedImage(); engine.drawMesh(mMesh); engine.disableBlending(); }
void initScene() { // generate texture texture = std::unique_ptr<Texture>(new Texture()); texture->genImageMask(16, 16, false); // setup scene viewTransform.SetPosition({ 0, 0, -3 }); //addModelPlane(); // reference model to check that UV-coords are correct addModelCuboid(); addModelEllipsoid(); addModelCone(); addModelCylinder(); addModelPipe(); addModelTorus(); addModelSpiral(); addModelTorusKnot(); //addModelCurve(); //addModelBezierPatch(); //addModelTeapot(); //... for (auto it = models.begin(); it != models.end();) { #ifdef ENABLE_PRESENTATION // setup model for presentation it->turn(0, Gs::Deg2Rad(20.0f)); it->turn(Gs::Deg2Rad(40.0f), 0); #endif // check for unused vertices in all models auto n = countUnusedVertices(it->mesh); if (n > 0) std::cout << it->name << " has " << n << " unused vertices" << std::endl; else if (n < 0) { std::cout << it->name << " has " << (-n) << " invalid vertices -> model removed from list" << std::endl; it = models.erase(it); continue; } // compute tangent vectors const auto& verts = it->mesh.vertices; auto numVerts = verts.size(); it->tangents[0].resize(numVerts); it->tangents[1].resize(numVerts); Gs::Vector3 tangent, bitangent, normal; for (const auto& indices : it->mesh.triangles) { Gm::Triangle3 coords( verts[indices.a].position, verts[indices.b].position, verts[indices.c].position ); Gm::Triangle2 texCoords( verts[indices.a].texCoord, verts[indices.b].texCoord, verts[indices.c].texCoord ); Gm::ComputeTangentSpace(coords, texCoords, tangent, bitangent, normal); (it->tangents[0])[indices.a] = tangent; (it->tangents[1])[indices.a] = bitangent; (it->tangents[0])[indices.b] = tangent; (it->tangents[1])[indices.b] = bitangent; (it->tangents[0])[indices.c] = tangent; (it->tangents[1])[indices.c] = bitangent; } #ifdef WRITE_MODELS_TO_FILE // write model to file it->writeObjFile("mesh/" + it->name + ".obj"); #endif ++it; } // show first model std::cout << std::endl; showModel(models.size() - 1); }
// Called by Rocket when it wants to compile geometry it believes will be // static for the forseeable future. Rocket::Core::CompiledGeometryHandle RocketRenderInterface::CompileGeometry( Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture) { //For now don't compile anything //return (Rocket::Core::CompiledGeometryHandle) NULL; unsigned int handle = (unsigned int)_vao.size()+1; unsigned int new_vao, new_ibo, new_vbo; std::vector<unsigned int> ind(num_indices); std::vector<float> verts(num_vertices*2); std::vector<float> colors(num_vertices*4); std::vector<float> texCoords(num_vertices*2); for(int i = 0; i < num_indices; i++) { ind[i] = static_cast<unsigned int>(indices[i]); } for(int i = 0; i < num_vertices; i++) { int vidx = 2*i; verts[vidx] = vertices[i].position.x; verts[vidx + 1] = vertices[i].position.y; int cidx = 4*i; colors[cidx + 0] = vertices[i].colour.red/255.0f; colors[cidx + 1] = vertices[i].colour.green/255.0f; colors[cidx + 2] = vertices[i].colour.blue/255.0f; colors[cidx + 3] = vertices[i].colour.alpha/255.0f; texCoords[vidx] = vertices[i].tex_coord.x; texCoords[vidx + 1] = vertices[i].tex_coord.y; } glGenVertexArrays(1, &new_vao); glBindVertexArray(new_vao); GetGLError(); glGenBuffers(1, &new_ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, new_ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*ind.size(),&ind[0], GL_STATIC_DRAW); GetGLError(); glGenBuffers(1, &new_vbo); glBindBuffer(GL_ARRAY_BUFFER, new_vbo); glBufferData(GL_ARRAY_BUFFER, (verts.size()+colors.size()+texCoords.size())*sizeof(float), NULL, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*verts.size(), &verts[0]); glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*verts.size(), sizeof(float)*colors.size(), &colors[0]); GetGLError(); if(texture > 0) { // Load in the textured gui shader glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*(verts.size()+colors.size()), sizeof(float)*texCoords.size(), &texCoords[0]); GetGLError(); setVertexAttribPointerF(Vertex::LocationSlot::POSITION, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); setVertexAttribPointerF(Vertex::LocationSlot::COLOR, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*verts.size())); setVertexAttribPointerF(Vertex::LocationSlot::UV, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*(verts.size()+colors.size()))); _shader_types.push_back(RS_T_WITH_TEXTURE); } else { _shader_types.push_back(RS_T_NO_TEXTURE); setVertexAttribPointerF(Vertex::LocationSlot::POSITION, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); setVertexAttribPointerF(Vertex::LocationSlot::COLOR, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*verts.size())); } // Now store away the indices to the geometry objects _vao.push_back(new_vao); _ibo.push_back(new_ibo); _vbo.push_back(new_vbo); _index_size.push_back((unsigned int)ind.size()); _tex_id.push_back(static_cast<unsigned int>(texture)); // Unbind the VAO just in case anyone makes changes to it. glBindVertexArray(0); // std::cout << "Compiled libRocket geometry " << new_ibo << " " // << new_vbo << " " << new_vao << std::endl; return handle; }
osg::ref_ptr<osg::Node> get(const ImageVec_t& images) { osg::ref_ptr<osg::Group> rv( new osg::Group() ); for ( const auto& image : images ) { // here we create a quad that will be texture mapped with the image osg::ref_ptr<osg::Vec3Array> quad( new osg::Vec3Array() ); quad->push_back( image.corners[0] ); quad->push_back( image.corners[1] ); quad->push_back( image.corners[2] ); quad->push_back( image.corners[3] ); osg::ref_ptr<osg::Geometry> geo( new osg::Geometry() ); geo->setVertexArray( quad ); // here we create a drawing elelment to draw on osg::ref_ptr<osg::DrawElementsUInt> primitiveSet( new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0) ); primitiveSet->push_back( 0 ); primitiveSet->push_back( 1 ); primitiveSet->push_back( 2 ); primitiveSet->push_back( 3 ); geo->addPrimitiveSet( primitiveSet ); // the texture mappings osg::ref_ptr<osg::Vec2Array> texCoords( new osg::Vec2Array(4) ); (*texCoords)[3].set( 0.0f, 0.0f ); (*texCoords)[2].set( 1.0f, 0.0f ); (*texCoords)[1].set( 1.0f, 1.0f ); (*texCoords)[0].set( 0.0f, 1.0f ); geo->setTexCoordArray( 0, texCoords ); // now create the goede to hold our created geometry osg::ref_ptr<osg::Geode> geode( new osg::Geode() ); geode->addDrawable( geo ); // create the texture for the image osg::ref_ptr<osg::Texture2D> texture( new osg::Texture2D() ); texture->setResizeNonPowerOfTwoHint(false); texture->setDataVariance(osg::Object::STATIC); texture->setImage( image.image ); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); // put this in decal mode osg::ref_ptr<osg::TexEnv> decalTexEnv( new osg::TexEnv() ); decalTexEnv->setMode(osg::TexEnv::DECAL); // set the state set, lighting and such, so we actually display the image osg::ref_ptr<osg::StateSet> stateSet( geode->getOrCreateStateSet() ); stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateSet->setTextureAttribute(0, decalTexEnv); stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); geo->setStateSet(stateSet); // turn off any color binding - we want to use the texture geo->setColorBinding(osg::Geometry::BIND_OFF); // add this image and continue rv->addChild(geode); } return rv; };