PostFX::PostFX(Engine *engine, ContextWindow *cw): m_engine(engine), m_cw(cw) { std::vector<glm::vec3> vertices= {glm::vec3(-1, -1, 0),glm::vec3(1, -1, 0),glm::vec3(1, 1, 0), glm::vec3(-1, 1, 0)}; auto bMgr=engine->getBufferManager(); auto aMgr=engine->getVertexArrayManager(); auto vbo=bMgr->registerVertexBuffer("POSTFX_QUAD", &vertices[0], vertices.size()*3*sizeof(float), r3d::BU_STATIC_DRAW); auto ibo=bMgr->registerIndexBuffer("POSTFX_QUAD", {0, 1, 2, 0, 2, 3}, r3d::BU_STATIC_DRAW); m_vao=aMgr->registerVertexArray("POSTFX_QUAD"); m_vao->bindVertexBuffer(vbo); m_vao->bindIndexBuffer(ibo); AttribPointer vertAtt(RT_FLOAT, 3, 0, 0); m_vao->enableAttribArray(0, vertAtt); m_fbosource=engine->newRenderTarget2D(); auto colorText=cw->getTextureManager()->registerColorTexture2D("LightedMap", cw->getWidth(), cw->getHeight(), PF_BGR); colorText->setFilter(F_LINEAR, F_LINEAR); ColorTexture2D *texts[]={colorText}; m_fbosource->attachColorTextures(1, texts); }
MeshSceneNode::MeshSceneNode(SceneNodePtr parent, ContextWindow *cw, Shape &shape, bool useTangent, const char *name_, const Transformation &relative): SceneNode(parent, cw, (name_? name_: shape.name.c_str()), relative) { std::string name=(name_? name_: shape.name.c_str()); // construct vertex struct for(uint32_t v=0; v<shape.mesh.positions.size()/3; v++) { m_vertices.push_back({glm::vec3(shape.mesh.positions[v*3], shape.mesh.positions[v*3+1], shape.mesh.positions[v*3+2]), shape.mesh.texcoords.size()>0?glm::vec2(shape.mesh.texcoords.at(v*2), 1.0f-shape.mesh.texcoords.at(v*2+1)): glm::vec2(), glm::vec3(shape.mesh.normals.at(v*3), shape.mesh.normals.at(v*3+1), shape.mesh.normals.at(v*3+2))}); } if(useTangent) { // construct tangent and bitangent vector if useTangent is true m_vertexTangents.resize(m_vertices.size()); for(uint32_t i=0; i<shape.mesh.indices.size(); i+=3) { const glm::vec3 &o = m_vertices[shape.mesh.indices[i]].pos; const glm::vec3 &a = m_vertices[shape.mesh.indices[i+1]].pos; const glm::vec3 &b = m_vertices[shape.mesh.indices[i+2]].pos; const glm::vec2 &uvo = m_vertices[shape.mesh.indices[i]].texCoord; const glm::vec2 &uva = m_vertices[shape.mesh.indices[i+1]].texCoord; const glm::vec2 &uvb = m_vertices[shape.mesh.indices[i+2]].texCoord; // Edges of the triangle : position delta const glm::vec3 &o_a = a-o; const glm::vec3 &o_b = b-o; // UV delta const glm::vec2 &uv_o_a = uva-uvo; const glm::vec2 &uv_o_b = uvb-uvo; float r = 1.0f / (uv_o_a.x*uv_o_b.y - uv_o_a.y*uv_o_b.x); const glm::vec3 &tangent = (o_a*uv_o_b.y - o_b*uv_o_a.y)*r; const glm::vec3 &bitangent = (o_b*uv_o_a.x - o_a*uv_o_b.x)*r; m_vertexTangents[shape.mesh.indices[i]].tangent+=tangent; m_vertexTangents[shape.mesh.indices[i]].bitangent+=bitangent; m_vertexTangents[shape.mesh.indices[i+1]].tangent+=tangent; m_vertexTangents[shape.mesh.indices[i+1]].bitangent+=bitangent; m_vertexTangents[shape.mesh.indices[i+2]].tangent+=tangent; m_vertexTangents[shape.mesh.indices[i+2]].bitangent+=bitangent; } } for(uint32_t i=0; i<m_vertexTangents.size(); i++) { m_vertexTangents[i].tangent=glm::normalize(m_vertexTangents[i].tangent); m_vertexTangents[i].bitangent=glm::normalize(m_vertexTangents[i].bitangent); } // We must move object to the middle findAABB(); const glm::vec3 &middle=(m_aabb.m_max+m_aabb.m_min)/2.0f; for(auto &v: m_vertices) v.pos-=middle; // We change the vertex data, must find aabb again findAABB(); m_relative.setTranslation(middle); auto vaoMgr=cw->getVertexArrayManager(); auto bMgr=cw->getBufferManager(); uint32_t stride = sizeof(Vertex)+(useTangent? sizeof(VertexTangent): 0); auto vbo=bMgr->registerVertexBuffer(name, nullptr, stride*m_vertices.size(), BU_STATIC_DRAW); auto ibo=bMgr->registerIndexBuffer(name, shape.mesh.indices, BU_STATIC_DRAW); // upload our data manually void *mappedBuffer=vbo->lock(BA_WRITE_ONLY); for(uint32_t i=0; i<m_vertices.size(); i++) { *(Vertex *)mappedBuffer=m_vertices[i]; if(useTangent) { void *mappedBufferTangent=(int8_t *)mappedBuffer+sizeof(Vertex); *(VertexTangent *)mappedBufferTangent=m_vertexTangents[i]; } mappedBuffer=(uint8_t *)mappedBuffer+stride; } vbo->unlock(); m_vao=vaoMgr->registerVertexArray(name); m_vao->bindVertexBuffer(vbo); m_vao->bindIndexBuffer(ibo); AttribPointer vertAtt(RT_FLOAT, 3, stride, 0); AttribPointer texCoordAtt(RT_FLOAT, 2, stride, 3*sizeof(float)); AttribPointer normAtt(RT_FLOAT, 3, stride, 5*sizeof(float)); AttribPointer tangentAtt(RT_FLOAT, 3, stride, 8*sizeof(float)); AttribPointer bitangentAtt(RT_FLOAT, 3, stride, 11*sizeof(float)); m_vao->enableAttribArray(0, vertAtt); m_vao->enableAttribArray(1, texCoordAtt); m_vao->enableAttribArray(2, normAtt); if(useTangent) { m_vao->enableAttribArray(3, tangentAtt); //m_vao->enableAttribArray(4, bitangentAtt); } m_indicesCount=shape.mesh.indices.size(); m_nodeType="Mesh"; }