Mat4f GLContext::xformMouseToUser(const Mat4f& userToClip) const { return userToClip.inverted() * Mat4f::scale(Vec3f(1.0f, -1.0f, 1.0f)) * Mat4f::translate(Vec3f(-1.0f, -1.0f, 0.0f)) * Mat4f::scale(Vec3f(m_viewScale, 1.0f)) * Mat4f::translate(Vec3f(0.5f, 0.5f, 0.0f)); }
void ForwardRenderer::renderWithZPrePass(IRenderContext* rc) { cullAll(); Mat4f VP = m_pCamera->getProjectionMatrix() * m_pCamera->getViewMatrix(); // Do Z Pre-Pass rc->enableColorBuffer(false, false, false, false); rc->enableDepthBuffer(true); rc->clear(IRenderContext::DEPTH); rc->setDepthTest(IRenderContext::DepthTestValue::Less); rc->setDrawMode(IRenderContext::DrawMode::Fill); m_pZPrePassShader->use(); for (auto& e : m_entitiesCulled) // TODO: front-to-back order { Mat4f MVP = VP * e->getModelMatrix(); Platform::get()->curShaderProgram()->setUniformFloatMatrix4Array(m_prePassMVPHandle, 1, false, MVP.getDataPointer()); rc->drawMesh(e->getMesh()); } // Do color pass rc->enableColorBuffer(true, true, true, true); rc->enableDepthBuffer(false); rc->clear(IRenderContext::COLOR); rc->setDepthTest(IRenderContext::DepthTestValue::LessEqual); rc->setDrawMode(IRenderContext::DrawMode::Fill); for (auto& e : m_entitiesCulled) // TODO: ordered by material { e->setupUnique(); e->setupMaterial(); rc->drawMesh(e->getMesh()); } // Render translucent objects in back-to-front order rc->enableDepthBuffer(true); for (auto& e : m_translucentEntitiesCulled) // TODO: order { e->setupUnique(); e->setupMaterial(); rc->drawMesh(e->getMesh()); } }
void cameraProto::setGl() { //// Set up a perspective view, with square aspect ratio glMatrixMode(GL_PROJECTION); glLoadIdentity(); // extern void gluPerspective (GLdouble fov_y, GLdouble aspect, GLdouble zNear, GLdouble zFar); gluPerspective((GLdouble)fov_, (GLdouble)1.0, (GLdouble)near_clip_, (GLdouble)far_clip_); // Rotate the image glMatrixMode( GL_MODELVIEW ); // Current matrix affects objects position_s glLoadIdentity(); // Initialize to the identity Mat4f modelView; current_quat_.get(modelView); gluLookAt(0, 0, current_dist_, 0, 0, 0, 0, 1, 0); glMultMatrixf(modelView.getPtr()); glTranslatef(this->look_at_.x, this->look_at_.y,this->look_at_.z); }
Cube::Cube(const Vec3f &pos, const Vec3f &scale, const Mat4f &rot, const std::string &name, std::shared_ptr<Bsdf> bsdf) : Primitive(name), _rot(rot), _invRot(rot.transpose()), _pos(pos), _scale(scale*0.5f), _bsdf(std::move(bsdf)) { _transform = Mat4f::translate(_pos)*rot*Mat4f::scale(Vec3f(scale)); }
void Options::update_euler() { Mat4f matrix = quaternion.to_matrix(); Vec3f euler = matrix.get_euler(order_YXZ); rotation_x.set_radians(euler.x); rotation_y.set_radians(euler.y); rotation_z.set_radians(euler.z); // Make 0 to 360 degrees rotation_x.normalize(); rotation_y.normalize(); rotation_z.normalize(); set_value(slider_rotation_x, rotation_x.to_degrees(), 0, max_angle_value); set_value(slider_rotation_y, rotation_y.to_degrees(), 0, max_angle_value); set_value(slider_rotation_z, rotation_z.to_degrees(), 0, max_angle_value); update_all_slider_text(); }
void Camera::applyViewingTransform() { if( mDirtyTransform ) calculateViewingTransformParameters(); ModelerDrawState *mds = ModelerDrawState::Instance(); if(mds->m_rayFile) { fprintf( mds->m_rayFile, "camera {\n\tposition = (%f, %f, %f);\n\tlook_at = (%f, %f, %f);\n\taspectratio = 1\n\tfov = 30; }\n\n", mPosition[0], mPosition[1], mPosition[2], mLookAt[0], mLookAt[1], mLookAt[2]); } // Place the camera at mPosition, aim the camera at // mLookAt, and twist the camera such that mUpVector is up /*gluLookAt( mPosition[0], mPosition[1], mPosition[2], mLookAt[0], mLookAt[1], mLookAt[2], mUpVector[0], mUpVector[1], mUpVector[2]);*/ // You Will Have to implement this (gluLookAt() ) yourself! // what fun that will be! Vec3f n = mPosition - mLookAt; Vec3f v = mUpVector - ((mUpVector * n) / (n * n)) * n; Vec3f u = v ^ n; u.normalize(); v.normalize(); n.normalize(); Mat4f mat; mat[0][0] = u[0]; mat[0][1] = v[0]; mat[0][2] = n[0]; mat[1][0] = u[1]; mat[1][1] = v[1]; mat[1][2] = n[1]; mat[2][0] = u[2]; mat[2][1] = v[2]; mat[2][2] = n[2]; mat = mat.transpose(); mat = mat * mat.createTranslation(-mPosition[0], -mPosition[1], -mPosition[2]); // Transpose the final matrix so that n is in column-major order to match OpenGL. mat = mat.transpose(); glMultMatrixf(mat.n); }
void m3dTest::eulerAnglesTest() { using namespace m3d; Vec3f axis(frand(), frand(), frand()); float angle = frand(0, 2.0f*PI); Mat4f input = Mat4f::rotAxis(axis, angle); Vec3f euler = input.eulerAngles(); Mat4f output = Mat4f::rotZ(euler.z) * Mat4f::rotX(euler.x) * Mat4f::rotY(euler.y); for (int x = 0; x < 4; ++x) { for (int y = 0; y < 4; ++y) { // check if equal CPPUNIT_ASSERT(fabs(input[x][y] - output[x][y]) < EPSILON); // check for NaN CPPUNIT_ASSERT(output[x][y] == output[x][y]); } } }
void m3dTest::orthonormalInverseTest() { using namespace m3d; Vec3f dir(frand(), frand(), frand()); Vec3f pos(frand(), frand(), frand()); Mat4f matrix = Mat4f::gramSchmidt(dir, pos); Mat4f inverse = matrix.inverse(); Mat4f orth_inverse = matrix.orthonormalInverse(); for (int x = 0; x < 4; ++x) { for (int y = 0; y < 4; ++y) { // check if equal CPPUNIT_ASSERT(fabs(inverse[x][y] - orth_inverse[x][y]) < EPSILON); // check for NaN CPPUNIT_ASSERT(inverse[x][y] == inverse[x][y]); CPPUNIT_ASSERT(orth_inverse[x][y] == orth_inverse[x][y]); } } }
Curve evalBspline( const vector< Vec3f >& P, unsigned steps ) { // Check if( P.size() < 4 ) { cerr << "evalBspline must be called with 4 or more control points." << endl; exit( 0 ); } cerr << "\t>>> evalBSpline has been called with the following input:" << endl; cerr << "\t>>> Control points (type vector< Vec3f >): "<< endl; for( unsigned i = 0; i < P.size(); ++i ) { cerr << "\t>>> "; printTranspose(P[i]); cerr << endl; } cerr << "\t>>> Steps (type steps): " << steps << endl; // Use your evalBezier function to evaluate the B-spline. // Convert the input control points to suitable coordinate system. // See lecture notes for further instructions. vector<Vec3f> Pbz; for (int i = 0; i < P.size()-3; i++) { // Create the G matrix for conversion Mat4f G; for (int j = 0; j < 4; j++) { G.setCol(j, Vec4f(P[i+j].x, P[i+j].y, P[i+j].z, 0.0)); } // Calculate the conversion matrix: G_2 = G_1 * B_1 * (B_2)^-1 G = G * Base::bsplineBase * Base::bezierBase.inverted(); // Detach the converted control points from the G matrix for (int j = 0; j < 3; j++) { Pbz.push_back(Vec3f(G.getCol(j)[0], G.getCol(j)[1], G.getCol(j)[2])); } // Only add the last column for the very last index if (i+3 == P.size()-1) { Pbz.push_back(Vec3f(G.getCol(3)[0], G.getCol(3)[1], G.getCol(3)[2])); } } return evalBezier(Pbz, steps); }
void m3dTest::saveLoadTest() { using namespace m3d; Vec4f vin(frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f)); Mat4f min(frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f), frand(-10000.0f, 10000.0f)); Vec4f vout; Mat4f mout; vout.assign(vin.str()); mout.assign(min.str()); for (int x = 0; x < 4; ++x) { // check if equal, allow a reasonable deviation CPPUNIT_ASSERT(fabs(vin[x] - vout[x]) < 0.005f); // check for NaN CPPUNIT_ASSERT(vout[x] == vout[x]); } for (int x = 0; x < 4; ++x) { for (int y = 0; y < 4; ++y) { // check if equal, allow a reasonable deviation CPPUNIT_ASSERT(fabs(min[x][y] - mout[x][y]) < 0.005f); // check for NaN CPPUNIT_ASSERT(mout[x][y] == mout[x][y]); } } }
void m3dTest::gramSchmidtTest() { using namespace m3d; Vec3f dir(frand(), frand(), frand()); Vec3f pos(frand(), frand(), frand()); Mat4f matrix = Mat4f::gramSchmidt(dir, pos); // check if all axes are perpendicular CPPUNIT_ASSERT(fabs(matrix.getX() * matrix.getY()) < EPSILON); CPPUNIT_ASSERT(fabs(matrix.getY() * matrix.getZ()) < EPSILON); CPPUNIT_ASSERT(fabs(matrix.getX() * matrix.getZ()) < EPSILON); for (int x = 0; x < 4; ++x) { for (int y = 0; y < 4; ++y) { // check for NaN CPPUNIT_ASSERT(matrix[x][y] == matrix[x][y]); } } // check if position is correct CPPUNIT_ASSERT(matrix.getW() == pos); }
void setUniform (int loc, const Mat4f& v) { if (loc >= 0) glUniformMatrix4fv(loc, 1, false, v.getPtr()); }
bool App::handleEvent(const Window::Event& ev) { if (ev.type == Window::EventType_Close) { m_window.showModalMessage("Exiting..."); delete this; return true; } Action action = m_action; m_action = Action_None; String name; Mat4f mat; switch (action) { case Action_None: break; case Action_LoadMesh: name = m_window.showFileLoadDialog("Load mesh", getMeshImportFilter()); if (name.getLength()) { Bvh::setBvhMode((Bvh::BvhMode)m_bvhMode); loadMesh(name); } break; case Action_ReloadMesh: if (m_meshFileName.getLength()) { Bvh::setBvhMode((Bvh::BvhMode)m_bvhMode); loadMesh(m_meshFileName); } break; case Action_SaveMesh: name = m_window.showFileSaveDialog("Save mesh", getMeshExportFilter()); if (name.getLength()) saveMesh(name); break; case Action_ResetCamera: if (m_mesh) { m_cameraCtrl.initForMesh(m_mesh); m_commonCtrl.message("Camera reset"); } break; case Action_EncodeCameraSignature: m_window.setVisible(false); printf("\nCamera signature:\n"); printf("%s\n", m_cameraCtrl.encodeSignature().getPtr()); waitKey(); break; case Action_DecodeCameraSignature: { m_window.setVisible(false); printf("\nEnter camera signature:\n"); char buf[1024]; if (scanf_s("%s", buf, FW_ARRAY_SIZE(buf))) m_cameraCtrl.decodeSignature(buf); else setError("Signature too long!"); if (!hasError()) printf("Done.\n\n"); else { printf("Error: %s\n", getError().getPtr()); clearError(); waitKey(); } } break; case Action_NormalizeScale: if (m_mesh) { Vec3f lo, hi; m_mesh->getBBox(lo, hi); m_mesh->xform(Mat4f::scale(Vec3f(2.0f / (hi - lo).max())) * Mat4f::translate((lo + hi) * -0.5f)); } break; case Action_FlipXY: nvswap(mat.col(0), mat.col(1)); if (m_mesh) { m_mesh->xform(mat); m_mesh->flipTriangles(); } break; case Action_FlipYZ: nvswap(mat.col(1), mat.col(2)); if (m_mesh) { m_mesh->xform(mat); m_mesh->flipTriangles(); } break; case Action_FlipZ: mat.col(2) = -mat.col(2); if (m_mesh) { m_mesh->xform(mat); m_mesh->flipTriangles(); } break; case Action_NormalizeNormals: if (m_mesh) m_mesh->xformNormals(mat.getXYZ(), true); break; case Action_FlipNormals: mat = -mat; if (m_mesh) m_mesh->xformNormals(mat.getXYZ(), false); break; case Action_RecomputeNormals: if (m_mesh) m_mesh->recomputeNormals(); break; case Action_FlipTriangles: if (m_mesh) m_mesh->flipTriangles(); break; case Action_CleanMesh: if (m_mesh) m_mesh->clean(); break; case Action_CollapseVertices: if (m_mesh) m_mesh->collapseVertices(); break; case Action_DupVertsPerSubmesh: if (m_mesh) m_mesh->dupVertsPerSubmesh(); break; case Action_FixMaterialColors: if (m_mesh) m_mesh->fixMaterialColors(); break; case Action_DownscaleTextures: if (m_mesh) downscaleTextures(m_mesh); break; case Action_ChopBehindNear: if (m_mesh) { Mat4f worldToClip = m_cameraCtrl.getCameraToClip() * m_cameraCtrl.getWorldToCamera(); Vec4f pleq = worldToClip.getRow(2) + worldToClip.getRow(3); chopBehindPlane(m_mesh, pleq); } break; // Assignment 2: actions case Action_PlaceLightSourceAtCamera: m_areaLight->setOrientation( m_cameraCtrl.getCameraToWorld().getXYZ() ); m_areaLight->setPosition( m_cameraCtrl.getPosition() ); m_commonCtrl.message("Placed light at camera"); break; case Action_ComputeRadiosity: Sampler::setSequenceMode((Sampler::SequenceMode)m_samplingMode); m_radiosity->startRadiosityProcess( m_mesh, m_areaLight, m_rt, m_numBounces, m_numDirectRays, m_numHemisphereRays ); m_updateClock.start(); break; case Action_LoadRadiosity: name = m_window.showFileLoadDialog("Load radiosity solution", "rad:Radiosity Solution" ); if (name.getLength()) loadRadiosity(name); break; case Action_SaveRadiosity: name = m_window.showFileSaveDialog("Save radiosity solution", "rad:Radiosity Solution" ); if (name.getLength()) saveRadiosity(name); break; // Assignment 1: actions /* case Action_TracePrimaryRays: { m_renderer->setAONumRays( m_numAORays ); m_renderer->setAORayLength( m_aoRayLength ); m_renderer->rayTracePicture( m_mesh, m_rt, m_rtImage, m_cameraCtrl, (Renderer::ShadingMode)m_shadingMode, (Renderer::SamplingMode)m_samplingMode, (Renderer::ColorMode)m_colorMode ); m_showRTImage = true; } break; */ default: FW_ASSERT(false); break; } m_window.setVisible(true); if (ev.type == Window::EventType_Paint) renderFrame(m_window.getGL()); m_window.repaint(); return false; }
//-------------------------------------------------------------------------------------------------- /// Create a (possibly oblique) cylinder oriented along the z-axis /// /// \param bottomRadius Bottom radius of cylinder /// \param topRadius Top radius of cylinder /// \param height Height of cylinder /// \param topOffsetX Offset top disc relative to bottom in X direction /// \param topOffsetY Offset top disc relative to bottom in Y direction /// \param numSlices Number of slices /// \param normalsOutwards true to generate polygons with outward facing normals. /// \param closedBot true to close the bottom of the cylinder with a disc /// \param closedTop true to close the top of the cylinder with a disc /// \param numPolysZDir Number of (subdivisions) polygons along the Z axis. /// \param builder Geometry builder to use when creating geometry /// /// An oblique cylinder is a cylinder with bases that are not aligned one directly above the other /// The base of the cylinder is placed at z = 0, and the top at z = height. /// Cylinder is subdivided around the z-axis into slices. /// Use the cone functions instead of setting one of the radius params to 0 //-------------------------------------------------------------------------------------------------- void GeometryUtils::createObliqueCylinder(float bottomRadius, float topRadius, float height, float topOffsetX, float topOffsetY, uint numSlices, bool normalsOutwards, bool closedBot, bool closedTop, uint numPolysZDir, GeometryBuilder* builder) { // Create cylinder... Vec3f centBot(0, 0, 0); Vec3f centTop(topOffsetX, topOffsetY, height); // Create vertices uint zPoly; for (zPoly = 0; zPoly <= numPolysZDir; zPoly++) { float fT = static_cast<float>((1.0/numPolysZDir)*(zPoly)); float radius = bottomRadius + fT*(topRadius - bottomRadius); Vec3f center(fT*topOffsetX, fT*topOffsetY, fT*height); Vec3fArray verts; verts.reserve(numSlices); Vec3f point = Vec3f::ZERO; double da = 2*PI_D/numSlices; uint i; for (i = 0; i < numSlices; i++) { // Precompute this one (A = i*da;) double sinA = Math::sin(i*da); double cosA = Math::cos(i*da); point.x() = static_cast<float>(-sinA*radius); point.y() = static_cast<float>( cosA*radius); point.z() = 0; point += center; verts.add(point); } uint baseNodeIdx = builder->addVertices(verts); // First time we only create the sourceNodes if (zPoly != 0) { uint offset = baseNodeIdx - numSlices; uint piConn[4] = { 0, 0, 0, 0 }; // Normals facing outwards if (normalsOutwards) { uint i; for (i = 0; i < numSlices; i++) { piConn[0] = offset + i; piConn[1] = offset + i + 1; piConn[2] = offset + i + numSlices + 1; piConn[3] = offset + i + numSlices; if (i == numSlices - 1) { piConn[1] = offset; piConn[2] = offset + numSlices; } builder->addQuad(piConn[0], piConn[1], piConn[2], piConn[3]); } } // Normals facing inwards else { uint i; for (i = 0; i < numSlices; i++) { piConn[0] = offset + i + 1; piConn[1] = offset + i; piConn[2] = offset + i + numSlices; piConn[3] = offset + i + numSlices + 1; if (i == numSlices - 1) { piConn[0] = offset; piConn[3] = offset + numSlices; } builder->addQuad(piConn[0], piConn[1], piConn[2], piConn[3]); } } } } if (closedBot) { createDisc(bottomRadius, numSlices, builder); } if (closedTop) { uint startIdx = builder->vertexCount(); createDisc(topRadius, numSlices, builder); uint endIdx = builder->vertexCount() - 1; // Translate the top disc sourceNodes, also flip it to get the normals the right way Mat4f mat = Mat4f::fromRotation(Vec3f(1.0f, 0.0f, 0.0f), Math::toRadians(180.0f)); mat.translatePreMultiply(Vec3f(topOffsetX, topOffsetY, height)); builder->transformVertexRange(startIdx, endIdx, mat); } }
void xform (const Mat4f& mat) { xformPositions(mat); xformNormals(mat.getXYZ().transposed().inverted()); }
void Rectangle::updateAttributes(Config cfg) { std::vector<TriangleFace> *faces; { TriangleVertex level0[4]; level0[0] = TriangleVertex(Vec3f(0.0,0.0,0.0),0); level0[1] = TriangleVertex(Vec3f(1.0,0.0,0.0),1); level0[2] = TriangleVertex(Vec3f(1.0,0.0,1.0),2); level0[3] = TriangleVertex(Vec3f(0.0,0.0,1.0),3); std::vector<TriangleFace> facesLevel0(2); facesLevel0[0] = TriangleFace( level0[0], level0[1], level0[3] ); facesLevel0[1] = TriangleFace( level0[1], level0[2], level0[3] ); faces = tessellate(cfg.levelOfDetail, facesLevel0); } Mat4f rotMat = Mat4f::rotationMatrix(cfg.rotation.x, cfg.rotation.y, cfg.rotation.z); GLboolean useIndexBuffer = (cfg.levelOfDetail>1); GLuint numVertices; std::map<GLuint,GLuint> indexMap; std::set<GLuint> processedIndices; ref_ptr<ShaderInput1ui> indices; if(useIndexBuffer) { // Allocate RAM for indices GLuint numIndices = faces->size()*3; indices = ref_ptr<ShaderInput1ui>::alloc("i"); indices->setVertexData(numIndices); GLuint *indicesPtr = (GLuint*)indices->clientDataPtr(); // Set index data and compute vertex count GLuint currIndex = 0; for(GLuint faceIndex=0; faceIndex<faces->size(); ++faceIndex) { TriangleFace &face = (*faces)[faceIndex]; TriangleVertex *vertices = (TriangleVertex*)&face; for(GLuint i=0; i<3; ++i) { TriangleVertex &vertex = vertices[i]; // Find vertex index if(indexMap.count(vertex.i)==0) { indexMap[vertex.i] = currIndex; currIndex += 1; } // Add to indices attribute *indicesPtr = indexMap[vertex.i]; indicesPtr += 1; } } numVertices = indexMap.size(); } else { numVertices = faces->size()*3; } if(cfg.isTangentRequired) { cfg.isNormalRequired = GL_TRUE; cfg.isTexcoRequired = GL_TRUE; } Vec3f startPos; if(cfg.centerAtOrigin) { startPos = Vec3f(-cfg.posScale.x*0.5f, 0.0f, -cfg.posScale.z*0.5f); } else { startPos = Vec3f(0.0f, 0.0f, 0.0f); } // allocate attributes pos_->setVertexData(numVertices); if(cfg.isNormalRequired) { nor_->setVertexData(numVertices); } if(cfg.isTexcoRequired) { texco_->setVertexData(numVertices); } if(cfg.isTangentRequired) { tan_->setVertexData(numVertices); } GLuint triIndices[3]; Vec3f triVertices[3]; Vec2f triTexco[3]; Vec3f normal = rotMat.transformVector(Vec3f(0.0,-1.0,0.0)); for(GLuint faceIndex=0; faceIndex<faces->size(); ++faceIndex) { TriangleFace &face = (*faces)[faceIndex]; TriangleVertex *vertices = (TriangleVertex*)&face; for(GLuint i=0; i<3; ++i) { GLuint vertexIndex; if(useIndexBuffer) { vertexIndex = indexMap[vertices[i].i]; } else { vertexIndex = faceIndex*3+i; } triIndices[i] = vertexIndex; if(processedIndices.count(vertexIndex)>0) { if(cfg.isTangentRequired) { triVertices[i] = pos_->getVertex(vertexIndex); triTexco[i] = texco_->getVertex(vertexIndex); } continue; } processedIndices.insert(vertexIndex); pos_->setVertex(vertexIndex, rotMat.transformVector( cfg.posScale*vertices[i].p + startPos) + cfg.translation); if(cfg.isNormalRequired) { nor_->setVertex(vertexIndex, normal); } if(cfg.isTexcoRequired) { texco_->setVertex(vertexIndex, cfg.texcoScale - (cfg.texcoScale*Vec2f(vertices[i].p.x,vertices[i].p.z))); } if(cfg.isTangentRequired) { triVertices[i] = pos_->getVertex(vertexIndex); triTexco[i] = texco_->getVertex(vertexIndex); } } if(cfg.isTangentRequired) { Vec4f tangent = calculateTangent(triVertices, triTexco, normal); for(GLuint i=0; i<3; ++i) { tan_->setVertex(triIndices[i], tangent); } } } delete faces; begin(ShaderInputContainer::INTERLEAVED); if(useIndexBuffer) setIndices(indices, numVertices); setInput(pos_); if(cfg.isNormalRequired) setInput(nor_); if(cfg.isTexcoRequired) setInput(texco_); if(cfg.isTangentRequired) setInput(tan_); end(); minPosition_ = -cfg.posScale; maxPosition_ = cfg.posScale; }
void Renderer::ApplyTransformation( const Mat4f& view ) { glLoadMatrixf( view.GetArray() ); }
void Shader::uniformMat(const std::string &name, const Mat4f &m, bool transpose) { glf->glUniformMatrix4fv(uniform(name), 1, transpose, m.data()); }
String CudaRenderer::renderObject( Image& frame, OctreeRuntime* runtime, int objectID, const Mat4f& octreeToWorld, const Mat4f& worldToCamera, const Mat4f& projection) { FW_ASSERT(runtime); // Check frame buffer validity. if (frame.getSize().min() <= 0) return ""; if (frame.getFormat() != ImageFormat::ABGR_8888 || frame.getStride() != frame.getSize().x * frame.getBPP()) { return "CudaRenderer: Incompatible framebuffer!"; } // Determine preprocessor defines. const Array<AttachIO::AttachType>& attach = runtime->getAttachTypes(objectID); FW_ASSERT(attach.getSize() == AttachSlot_Max); m_compiler.clearDefines(); bool enableContours = (attach[AttachSlot_Contour] == AttachIO::ContourAttach && m_params.enableContours); if (enableContours) m_compiler.define("ENABLE_CONTOURS"); switch (attach[AttachSlot_Attribute]) { case AttachIO::ColorNormalPaletteAttach: m_compiler.define("VOXELATTRIB_PALETTE"); m_compiler.define("DISABLE_PUSH_OPTIMIZATION"); break; case AttachIO::ColorNormalCornerAttach: m_compiler.define("VOXELATTRIB_CORNER"); m_compiler.define("DISABLE_PUSH_OPTIMIZATION"); break; case AttachIO::ColorNormalDXTAttach: m_compiler.define("VOXELATTRIB_DXT"); break; default: return "Unsupported attribute attachment!"; } if (attach[AttachSlot_AO] == AttachIO::AOAttach) m_compiler.define("VOXELATTRIB_AO"); if (m_params.measureRaycastPerf) m_compiler.define("KERNEL_RAYCAST_PERF"); else m_compiler.define("KERNEL_RENDER"); if (m_params.enablePerfCounters) m_compiler.define("ENABLE_PERF_COUNTERS"); if (m_params.enableLargeReconstruction) m_compiler.define("LARGE_RECONSTRUCTION_KERNEL"); if (m_params.enableJitterLOD) m_compiler.define("JITTER_LOD"); if (m_params.visualization == Visualization_PrimaryAndShadow) m_compiler.define("ENABLE_SHADOWS"); if (!m_blurLUT.getSize()) constructBlurLUT(); m_compiler.define("BLUR_LUT_SIZE", String(m_blurLUT.getSize())); // Determine flags. U32 flags = 0; if (m_params.visualization == Visualization_IterationCount) flags |= RenderFlags_VisualizeIterations; else if (m_params.visualization == Visualization_RaycastLevel) flags |= RenderFlags_VisualizeRaycastLevel; // Set input. m_input.frameSize = frame.getSize(); m_input.flags = flags; m_input.batchSize = m_params.batchSize; m_input.aaRays = (m_params.enableAntialias) ? 4 : 1; m_input.maxVoxelSize = m_params.maxVoxelSize; m_input.brightness = m_params.brightness; m_input.coarseSize = m_params.coarseSize; m_input.coarseFrameSize = (m_input.frameSize + (m_params.coarseSize - 1)) / m_params.coarseSize + 1; m_input.frame = frame.getBuffer().getMutableCudaPtr(); m_input.rootNode = runtime->getRootNodeCuda(objectID); OctreeMatrices& om = m_input.octreeMatrices; Vec3f scale = Vec3f(Vec2f(2.0f) / Vec2f(m_input.frameSize), 1.0f); om.viewportToCamera = projection.inverted() * Mat4f::translate(Vec3f(-1.0f, -1.0f, 0.0f)) * Mat4f::scale(scale); om.cameraToOctree = Mat4f::translate(Vec3f(1.0f)) * (worldToCamera * octreeToWorld).inverted(); Mat4f vto = om.cameraToOctree * om.viewportToCamera; om.pixelInOctree = sqrt(Vec4f(vto.col(0)).getXYZ().cross(Vec4f(vto.col(1)).getXYZ()).length()); om.octreeToWorld = octreeToWorld * Mat4f::translate(Vec3f(-1.0f)); om.worldToOctree = invert(om.octreeToWorld); om.octreeToWorldN = octreeToWorld.getXYZ().inverted().transposed(); om.cameraPosition = invert(worldToCamera) * Vec3f(0.f, 0.f, 0.f); om.octreeToViewport = invert(om.viewportToCamera) * invert(om.cameraToOctree); om.viewportToOctreeN = (om.octreeToViewport).transposed(); // Setup frame-related buffers. int numPixels = m_input.frameSize.x * m_input.frameSize.y; if (m_pixelTable.getSize() != m_input.frameSize) { m_indexToPixel.resizeDiscard(numPixels * sizeof(S32)); m_pixelTable.setSize(m_input.frameSize); memcpy(m_indexToPixel.getMutablePtr(), m_pixelTable.getIndexToPixel(), numPixels * sizeof(S32)); } // Coarse frame and pixel buffers. int coarseNumPixels = m_input.coarseFrameSize.x * m_input.coarseFrameSize.y; m_coarseFrameBuffer.resizeDiscard(coarseNumPixels * sizeof(S32)); m_input.frameCoarse = m_coarseFrameBuffer.getMutableCudaPtr(); if (m_coarsePixelTable.getSize() != m_input.coarseFrameSize) { m_coarseIndexToPixel.resizeDiscard(coarseNumPixels * sizeof(S32)); m_coarsePixelTable.setSize(m_input.coarseFrameSize); memcpy(m_coarseIndexToPixel.getMutablePtr(), m_coarsePixelTable.getIndexToPixel(), coarseNumPixels * sizeof(S32)); m_coarseIndexToPixel.free(Buffer::CPU); } // Temp frame buffer for blurring. if (m_params.enableBlur) { // override frame buffer address! m_tempFrameBuffer.resizeDiscard(numPixels * sizeof(U32)); m_input.frame = m_tempFrameBuffer.getMutableCudaPtr(); } // AA sample buffer if (m_input.aaRays > 1) { m_aaSampleBuffer.resizeDiscard(numPixels * m_input.aaRays * sizeof(U32)); m_input.aaSampleBuffer = m_aaSampleBuffer.getMutableCudaPtr(); } // Setup performance counter buffer. if (m_params.enablePerfCounters) { m_perfCounters.resizeDiscard(m_numWarps * PerfCounter_Max * 33 * sizeof(S64)); memset(m_perfCounters.getMutablePtr(), 0, (size_t)m_perfCounters.getSize()); m_input.perfCounters = m_perfCounters.getMutableCudaPtr(); } // Render. LaunchResult coarseResult; if (m_params.enableBeamOptimization) { RenderInput old = m_input; m_input.numPrimaryRays = coarseNumPixels; m_input.aaRays = 1; m_input.flags |= RenderFlags_CoarsePass; m_input.batchSize = 1; m_compiler.undef("ENABLE_CONTOURS"); coarseResult = launch(coarseNumPixels * m_params.numFrameRepeats, false); m_input = old; m_input.flags |= RenderFlags_UseCoarseData; if (enableContours) m_compiler.define("ENABLE_CONTOURS"); } m_input.numPrimaryRays = numPixels * m_input.aaRays; LaunchResult renderResult = launch(m_input.numPrimaryRays * m_params.numFrameRepeats, true); // Post-process blur. F32 blurTime = 0.f; if (m_params.enableBlur) { // restore true frame buffer pointer m_input.frame = frame.getBuffer().getMutableCudaPtr(); // get module CudaModule* module = m_compiler.compile(); // update blur LUT Vec4i* pLUT = (Vec4i*)module->getGlobal("c_blurLUT").getMutablePtr(); for (int i=0; i < m_blurLUT.getSize(); i++) { float d = sqrtf((float)sqr(m_blurLUT[i].x) + (float)sqr(m_blurLUT[i].y)); Vec4i& v = pLUT[i]; v.x = m_blurLUT[i].x; v.y = m_blurLUT[i].y; v.z = floatToBits((float)m_blurLUT[i].z); v.w = floatToBits(d); } // update globals *(RenderInput*)module->getGlobal("c_input").getMutablePtr() = m_input; module->setTexRef("texTempFrameIn", m_tempFrameBuffer, CU_AD_FORMAT_UNSIGNED_INT8, 4); module->setTexRef("texAASamplesIn", m_aaSampleBuffer, CU_AD_FORMAT_UNSIGNED_INT8, 4); // launch blurTime = module->getKernel("blurKernel").launchTimed(frame.getSize(), Vec2i(8)); } // Update statistics. F32 totalTime = renderResult.time + coarseResult.time + blurTime; m_results.launchTime += totalTime; m_results.coarseTime += coarseResult.time; m_results.renderWarps += renderResult.numWarps; m_results.coarseWarps += coarseResult.numWarps; if (m_params.enablePerfCounters) { const S64* ptr = (const S64*)m_perfCounters.getPtr(); for (int warpIdx = 0; warpIdx < m_numWarps; warpIdx++) { for (int counterIdx = 0; counterIdx < PerfCounter_Max; counterIdx++) { for (int threadIdx = 0; threadIdx < 32; threadIdx++) m_results.threadCounters[counterIdx] += *ptr++; m_results.warpCounters[counterIdx] += *ptr++; } } } m_stats = sprintf("CudaRenderer: launch %.2f ms (%.2f FPS), %.2f MPix/s", totalTime * 1.0e3f, 1.0f / totalTime, numPixels * 1.0e-6f / totalTime); if (m_params.enableBlur) m_stats += sprintf(", blur %.2f MPix/s", numPixels * 1.0e-6f / blurTime); // Adjust the number of warps for the next run. int maxWarps = max(renderResult.numWarps, coarseResult.numWarps); if (maxWarps * 2 > m_numWarps) { if (maxWarps == m_numWarps) printf("CudaRenderer: warp count auto-detect overflow, increasing warp count to %d\n", maxWarps * 2); else printf("CudaRenderer: warp count auto-detected: %d warps, launching %d\n", maxWarps, maxWarps * 2); m_numWarps = maxWarps * 2; } return ""; }
void ModelTransformation::scale(const Vec3f &scaling, GLdouble dt) { Mat4f* val = (Mat4f*)modelMat_->clientDataPtr(); val->scale(scaling); modelMat_->nextStamp(); }
void TestApp::test_matrix_mat4() { Console::write_line(" Class: Mat4"); Console::write_line(" Function: inverse()"); { Mat4f test_src = Mat4f::rotate((Angle(30, angle_degrees)), 1.0, 0.0, 0.0, true); Mat4f test_inv; Mat4f test_dest; Mat4f test_ident = Mat4f::identity(); test_dest = test_src; test_dest.inverse(); test_dest = test_dest * test_src; if (test_ident != test_dest) fail(); } static int test_a_values[] = {3, 1, 2, 4, 5 ,6, 4, 2, 1, 4, 6, 7, 6, 3, 7, 2}; static int test_b_values[] = {4, 7, 2, 5, 3, 5, 2, 9, 3, 3, 6, 9, 2, 4, 6, 2}; Mat4i test_a(test_a_values); Mat4i test_b(test_b_values); Mat4f test_c(test_a); Mat4f test_c_scaled(test_c); { float x = 2.0f; float y = 3.0f; float z = 4.0f; test_c_scaled[0 + 4 * 0] *= x; test_c_scaled[0 + 4 * 1] *= y; test_c_scaled[0 + 4 * 2] *= z; test_c_scaled[1 + 4 * 0] *= x; test_c_scaled[1 + 4 * 1] *= y; test_c_scaled[1 + 4 * 2] *= z; test_c_scaled[2 + 4 * 0] *= x; test_c_scaled[2 + 4 * 1] *= y; test_c_scaled[2 + 4 * 2] *= z; test_c_scaled[3 + 4 * 0] *= x; test_c_scaled[3 + 4 * 1] *= y; test_c_scaled[3 + 4 * 2] *= z; } Console::write_line(" Function: add() and operator"); { int answer_values[] = {7, 8, 4, 9, 8, 11, 6, 11, 4, 7, 12, 16, 8, 7, 13, 4}; Mat4i answer(answer_values); Mat4i result = test_a + test_b; if (result != answer) fail(); result = Mat4i::add(test_a, test_b); if (result != answer) fail(); } Console::write_line(" Function: subtract() and operator"); { int answer_values[] = {-1, -6, 0, -1, 2, 1, 2, -7, -2, 1, 0, -2, 4, -1, 1, 0}; Mat4i answer(answer_values); Mat4i result = test_a - test_b; if (result != answer) fail(); result = Mat4i::subtract(test_a, test_b); if (result != answer) fail(); } Console::write_line(" Function: translate()"); { int answer_values[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 3, 4, 1}; Mat4i answer(answer_values); Mat4i result = Mat4i::translate(2, 3, 4); if (result != answer) fail(); } Console::write_line(" Function: translate_self() (int)"); { Mat4i answer(test_a); Mat4i result = test_a; result = result * Mat4i::translate(2, 3, 4); Mat4i result2 = test_a; result2.translate_self(2,3,4); if (result != result2) fail(); } Console::write_line(" Function: translate_self() (float)"); { Mat4f answer(test_a); Mat4f result(test_a); result = result * Mat4f::translate(2, 3, 4); Mat4f result2(test_a); result2.translate_self(2, 3, 4); if (!result.is_equal(result2, 0.00001f)) fail(); } Console::write_line(" Function: scale_self()"); { Mat4i answer(test_a); Mat4i result = test_a; result = result * Mat4i::scale(2, 3, 4); Mat4i result2 = test_a; result2.scale_self(2,3,4); if (result != result2) fail(); Mat4f test = test_c; test.scale_self(2.0f, 3.0f, 4.0f); if (!test.is_equal(test_c_scaled, 0.00001f)) fail(); } Console::write_line(" Function: rotate (using euler angles)"); { Mat4f mv = Mat4f::identity(); mv = mv * Mat4f::rotate(Angle(30.0f, angle_degrees), 0.0f, 0.0f, 1.0f, false); mv = mv * Mat4f::rotate(Angle(10.0f, angle_degrees), 1.0f, 0.0f, 0.0f, false); mv = mv * Mat4f::rotate(Angle(20.0f, angle_degrees), 0.0f, 1.0f, 0.0f, false); Mat4f test_matrix; test_matrix = Mat4f::rotate(Angle(10.0f, angle_degrees), Angle(20.0f, angle_degrees), Angle(30.0f, angle_degrees), order_YXZ); if (!test_matrix.is_equal(mv, 0.00001f)) fail(); } Console::write_line(" Function: rotate (using euler angles) and get_euler"); { test_rotate_and_get_euler(order_XYZ); test_rotate_and_get_euler(order_XZY); test_rotate_and_get_euler(order_YZX); test_rotate_and_get_euler(order_YXZ); test_rotate_and_get_euler(order_ZXY); test_rotate_and_get_euler(order_ZYX); } Console::write_line(" Function: transpose() (float)"); { Mat4f original(test_a); Mat4f transposed_matrix; transposed_matrix[0] = original[0]; transposed_matrix[1] = original[4]; transposed_matrix[2] = original[8]; transposed_matrix[3] = original[12]; transposed_matrix[4] = original[1]; transposed_matrix[5] = original[5]; transposed_matrix[6] = original[9]; transposed_matrix[7] = original[13]; transposed_matrix[8] = original[2]; transposed_matrix[9] = original[6]; transposed_matrix[10] = original[10]; transposed_matrix[11] = original[14]; transposed_matrix[12] = original[3]; transposed_matrix[13] = original[7]; transposed_matrix[14] = original[11]; transposed_matrix[15] = original[15]; Mat4f test = original; test.transpose(); if (!test.is_equal(transposed_matrix, 0.00001f)) fail(); } }
void Render(double time) { // // the camera matrix Mat4f camera = CamMatrixf::Orbiting( Vec3f(), 6.5 + SineWave(time / 16.0) * 1.5, FullCircles(time / 12.0), Degrees(SineWave(time / 30.0) * 90) ); // // the model matrix Mat4f model = ModelMatrixf::RotationA( Vec3f(1.0f, 1.0f, 1.0f), FullCircles(time / 10.0) ); // the light position Vec3f lightPos(0.0f, SineWave(time / 7.0) * 0.5, 0.0f); // SetProgramUniform(shape_prog, "LightPos", lightPos); SetProgramUniform(depth_prog, "LightPos", lightPos); SetProgramUniform(light_prog, "LightPos", lightPos); // SetProgramUniform(shape_prog, "CameraMatrix", camera); SetProgramUniform(light_prog, "CameraMatrix", camera); SetProgramUniform(shape_prog, "ModelMatrix", model); SetProgramUniform(depth_prog, "ModelMatrix", model); // render the shadow map depth_fbo.Bind(Framebuffer::Target::Draw); gl.DrawBuffer(ColorBuffer::None); gl.Viewport(tex_side, tex_side); gl.Clear().DepthBuffer(); depth_prog.Use(); shape.Bind(); shape_instr.Draw(shape_indices); // render the output frame Framebuffer::BindDefault(Framebuffer::Target::Draw); gl.DrawBuffer(ColorBuffer::Back); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); shape_prog.Use(); shape.Bind(); shape_instr.Draw(shape_indices); gl.Enable(Capability::Blend); light_prog.Use(); SetUniform(light_prog, "ViewX", camera.Row(0).xyz()); SetUniform(light_prog, "ViewY", camera.Row(1).xyz()); SetUniform(light_prog, "ViewZ", camera.Row(2).xyz()); light.Bind(); gl.DrawArraysInstanced( PrimitiveType::Points, 0, 1, sample_count ); gl.Disable(Capability::Blend); }
void Scene::RenderQuaxolChunk(Camera* pCamera, Shader* pShader) { if(!m_pQuaxolChunk) return; WasGLErrorPlusPrint(); pShader->StartUsing(); pShader->SetCameraParams(pCamera); Mat4f worldMatrix; worldMatrix.storeIdentity(); pShader->SetOrientation(&worldMatrix); WasGLErrorPlusPrint(); if (m_pQuaxolAtlas) { GLint hTex0 = pShader->getUniform("texDiffuse0"); if (hTex0 != -1) { glActiveTexture(GL_TEXTURE0); WasGLErrorPlusPrint(); glBindTexture(GL_TEXTURE_2D, m_pQuaxolAtlas->GetTextureID()); //WasGLErrorPlusPrint(); // glUniform1i(hTex0, 0); } } GLint hTexCoord = glGetAttribLocation(pShader->getProgramId(), "vertCoord"); //GLint hTexCoord = pShader->getAttrib("vertCoord"); static Vec4f zero(0,0,0,0); pShader->SetPosition(&zero); GLuint colorHandle = pShader->GetColorHandle(); glBegin(GL_TRIANGLES); // TODO: use vbo, as we have already done the work to put things into // a nice format. IndexList& indices = m_pQuaxolChunk->m_indices; VecList& verts = m_pQuaxolChunk->m_verts; QVertList& packVerts = m_pQuaxolChunk->m_packVerts; int numTris = (int)indices.size() / 3; int currentIndex = 0; for (int tri = 0; tri < numTris; ++tri) { const QuaxolVert& vA = packVerts[indices[currentIndex]]; const Vec4f& a = verts[indices[currentIndex++]]; const QuaxolVert& vB = packVerts[indices[currentIndex]]; const Vec4f& b = verts[indices[currentIndex++]]; const QuaxolVert& vC = packVerts[indices[currentIndex]]; const Vec4f& c = verts[indices[currentIndex++]]; if (colorHandle != -1) { float minW = (std::min)(a.w, (std::min)(b.w, c.w)); int colorIndex = ((int)abs(minW)) % m_colorArray.size(); glVertexAttrib4fv(colorHandle, m_colorArray[colorIndex].raw()); } if (hTexCoord != -1) { const float invTexSteps = 1.0f / 16.0f; int firstTriOffset = tri % 2; glVertexAttrib2f(hTexCoord, (float)((vA._uvInd % 8) + 0) * invTexSteps, (float)((vA._uvInd / 8) + firstTriOffset) * invTexSteps); glVertex4fv(a.raw()); glVertexAttrib2f(hTexCoord, (float)((vB._uvInd % 8) + 1) * invTexSteps, (float)((vB._uvInd / 8) + 0) * invTexSteps); glVertex4fv(b.raw()); glVertexAttrib2f(hTexCoord, (float)((vC._uvInd % 8) + firstTriOffset) * invTexSteps, (float)((vC._uvInd / 8) + 1) * invTexSteps); glVertex4fv(c.raw()); } else { glVertex4fv(a.raw()); glVertex4fv(b.raw()); glVertex4fv(c.raw()); } } glEnd(); pShader->StopUsing(); }
// We are going to override (is that the right word?) the draw() // method of ModelerView to draw out RobotArm void RobotArm::draw() { /* pick up the slider values */ float theta = VAL( BASE_ROTATION ); float phi = VAL( LOWER_TILT ); float psi = VAL( UPPER_TILT ); float cr = VAL( CLAW_ROTATION ); float h1 = VAL( BASE_LENGTH ); float h2 = VAL( LOWER_LENGTH ); float h3 = VAL( UPPER_LENGTH ); float pc = VAL( PARTICLE_COUNT ); // This call takes care of a lot of the nasty projection // matrix stuff ModelerView::draw(); // Save the camera transform that was applied by // ModelerView::draw() above. // While we're at it, save an inverted copy of this matrix. We'll // need it later. Mat4f matCam = glGetMatrix( GL_MODELVIEW_MATRIX ); matCamInverse = matCam.inverse(); static GLfloat lmodel_ambient[] = {0.4,0.4,0.4,1.0}; // define the model ground(-0.2); base(0.8); glTranslatef( 0.0, 0.8, 0.0 ); // move to the top of the base glRotatef( theta, 0.0, 1.0, 0.0 ); // turn the whole assembly around the y-axis. rotation_base(h1); // draw the rotation base glTranslatef( 0.0, h1, 0.0 ); // move to the top of the base glPushMatrix(); glTranslatef( 0.5, h1, 0.6 ); glPopMatrix(); glRotatef( phi, 0.0, 0.0, 1.0 ); // rotate around the z-axis for the lower arm glTranslatef( -0.1, 0.0, 0.4 ); lower_arm(h2); // draw the lower arm glTranslatef( 0.0, h2, 0.0 ); // move to the top of the lower arm glRotatef( psi, 0.0, 0.0, 1.0 ); // rotate around z-axis for the upper arm upper_arm(h3); // draw the upper arm glTranslatef( 0.0, h3, 0.0 ); glRotatef( cr, 0.0, 0.0, 1.0 ); Mat4f mvMatrix = glGetMatrix(GL_MODELVIEW_MATRIX); Vec4f clawEmitPos = matCamInverse * mvMatrix * Vec4f(0.0, 0.0, 0.0, 1.0); if (ps != NULL) { Vec3f clawPos = Vec3f(clawEmitPos[0], clawEmitPos[1], clawEmitPos[2]); ps->setEmitterPosition(clawPos, 1); } claw(1.0); //*** DON'T FORGET TO PUT THIS IN YOUR OWN CODE **/ endDraw(); }
void m3dTest::quaternionTest() { using namespace m3d; // generate first matrix and quaternion Vec3f axis(frand(), frand(), frand()); float angle = frand(0, 2.0f*PI); Mat4f input1 = Mat4f::rotAxis(axis, angle); Quatf quat1(axis, angle); // generate second matrix and quaternion Vec3f axis2(frand(), frand(), frand()); float angle2 = frand(0, 2.0f*PI); Mat4f input2 = Mat4f::rotAxis(axis2, angle2); Quatf quat2(axis2, angle2); // multiply them Mat4f input = input1 * input2; Quatf quat = quat1 * quat2; Mat4f output = quat.mat4(); // normalize all axes input.setX(input.getX().normalized()); input.setY(input.getY().normalized()); input.setZ(input.getZ().normalized()); output.setX(input.getX().normalized()); output.setY(input.getY().normalized()); output.setZ(input.getZ().normalized()); // compare for (int x = 0; x < 4; ++x) { for (int y = 0; y < 4; ++y) { // check if equal, allow a reasonable deviation CPPUNIT_ASSERT(fabs(input[x][y] - output[x][y]) < EPSILON); // check for NaN CPPUNIT_ASSERT(output[x][y] == output[x][y]); } } }
void Scene::RenderQuaxolsIndividually(Camera* pCamera, Shader* pShader) { if(!m_pQuaxolMesh) return; WasGLErrorPlusPrint(); pShader->StartUsing(); pShader->SetCameraParams(pCamera); WasGLErrorPlusPrint(); Mat4f worldMatrix; worldMatrix.storeIdentity(); pShader->SetOrientation(&worldMatrix); WasGLErrorPlusPrint(); GLint hTex0 = pShader->getUniform("texDiffuse0"); WasGLErrorPlusPrint(); if (hTex0 != -1) { SetTexture(0, hTex0); } for (auto quaxol : m_quaxols) { const QuaxolSpec& q = quaxol; float shift_amount = 10.0f; Vec4f shift; shift.x = shift_amount * q.x; shift.y = shift_amount * q.y; shift.z = shift_amount * q.z; shift.w = shift_amount * q.w; pShader->SetPosition(&shift); WasGLErrorPlusPrint(); if (m_texList.size() > 0) { int layerTexIndex = abs(q.w) % m_texList.size(); SetTexture(layerTexIndex, hTex0); } int tesseractTris = m_pQuaxolMesh->getNumberTriangles(); int startTriangle = 0; int endTriangle = tesseractTris; WasGLErrorPlusPrint(); GLuint colorHandle = pShader->GetColorHandle(); glBegin(GL_TRIANGLES); //WasGLErrorPlusPrint(); Vec4f a, b, c; int colorIndex = abs(q.w) % m_colorArray.size(); for (int t = startTriangle; t < endTriangle && t < tesseractTris; t++) { if(colorHandle != -1) { glVertexAttrib4fv(colorHandle, m_colorArray[colorIndex].raw()); } //WasGLErrorPlusPrint(); m_pQuaxolMesh->getTriangle(t, a, b, c); glVertex4fv(a.raw()); glVertex4fv(b.raw()); glVertex4fv(c.raw()); //WasGLErrorPlusPrint(); //if ((t+1) % 2 == 0) { // colorIndex = (colorIndex + 1) % m_colorArray.size(); //} } //WasGLErrorPlusPrint(); glEnd(); WasGLErrorPlusPrint(); } pShader->StopUsing(); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UniformMatrixf::set(const Mat4f& value) { m_type = FLOAT_MAT4; m_data.resize(16); m_data.copyData(value.ptr(), 16, 0); }
void MyModel::SpawnParticles(Mat4f CameraTransforms) { Mat4f WorldMatrix = CameraTransforms.inverse() * getModelViewMatrix(); Vec3f WorldPoint = WorldMatrix * Vec4f(0, 0, 0, 1); particleSystem.addParticleAt(WorldPoint); }