#include "Renderer.h" #include #include #include #include #include #include void TrackBall::mouseDownEvent(EMouseButton btn, int x, int y) { if (camera() == NULL) return; // if already busy ignore the event if (mode() != NoMode) return; // set x/y relative to the viewport x -= camera()->viewport()->x(); y -= openglContext()->framebuffer()->height() - 1 - (camera()->viewport()->y() + camera()->viewport()->height() - 1); unsigned char selected; // enter new mode if (btn == rotationButton()) { glReadPixels(x, y, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &selected); GLenum err = glGetError(); err = glGetError(); } else if (btn == translationButton()) mMode = TranslationMode; else if (btn == zoomButton()) mMode = ZoomMode; VL_CHECK(openglContext()->framebuffer()) // check that the click is in the viewport int w = camera()->viewport()->width(); int h = camera()->viewport()->height(); if (x<0 || y<0 || x >= w || y >= h) return; mMouseStart.x() = x; mMouseStart.y() = y; if (mTransform) { mStartMatrix = mTransform->localMatrix(); mPivot = mStartMatrix.getT(); } else mStartMatrix = camera()->modelingMatrix(); mStartCameraPos = camera()->modelingMatrix().getT(); mStartPivot = mPivot; } void TrackBall::mouseMoveEvent(int x, int y) { if (camera() == NULL) return; mCurrentX = x - camera()->viewport()->x(); mCurrentY = y - (openglContext()->framebuffer()->height() - 1 - (camera()->viewport()->y() + camera()->viewport()->height() - 1)); // ignore the event if the trackball is not in any mode if (mode() == NoMode) return; VL_CHECK(openglContext()->framebuffer()) // set x/y relative to the top/left cornder of the viewport x -= camera()->viewport()->x(); y -= openglContext()->framebuffer()->height() - 1 - (camera()->viewport()->y() + camera()->viewport()->height() - 1); //if (mode() == RotationMode)TrackBall:: //{ // if (mTransform) // { // mTransform->setLocalMatrix(mat4::getTranslation(mPivot) * trackballRotation(x, y) * mat4::getTranslation(-mPivot) * mStartMatrix); // mTransform->computeWorldMatrix(); // mStartMatrix = mTransform->localMatrix(); // } // else // { // camera()->setModelingMatrix(mat4::getTranslation(mPivot) * trackballRotation(x, y) * mat4::getTranslation(-mPivot) * mStartMatrix); // mStartMatrix = camera()->modelingMatrix(); // } // mMouseStart.x() = x; // mMouseStart.y() = y; //} //else //{ if (mode() == ZoomMode) { float t = (y - mMouseStart.y()) / 200.0f; t *= zoomSpeed(); real distance = (mStartCameraPos - mPivot).length(); vec3 camera_pos = mStartCameraPos - camera()->modelingMatrix().getZ()*t*distance; mat4 m = camera()->modelingMatrix(); m.setT(camera_pos); camera()->setModelingMatrix(m); } else if (mode() == TranslationMode) { vl::vec3 eye, at, up, right; camera()->getViewMatrixAsLookAt(eye, at, up, right); vl::vec4 focus_point_w, focus_point; focus_point_w.x() = at.x(); focus_point_w.y() = at.y(); focus_point_w.z() = at.z(); focus_point_w.w() = 1.0; camera()->project(focus_point_w, focus_point); vl::vec3 vp0, vp1; vp0.x() = mMouseStart.x(); vp0.y() = mMouseStart.y(); vp0.z() = focus_point.z(); vp1.x() = x; vp1.y() = y; vp1.z() = focus_point.z(); vl::vec4 v4p0, v4p1; camera()->unproject(vp0, v4p0); camera()->unproject(vp1, v4p1); vec3 mv = v4p1.xyz() - v4p0.xyz(); mv.x() = -mv.x(); mat4 m = camera()->modelingMatrix(); m.setT(mStartCameraPos + mv); camera()->setModelingMatrix(m); mPivot = mStartPivot + mv; } //} // update the view openglContext()->update(); } void TrackBall::mouseWheelEvent(int delta) { vl::vec3 eye, at, up, right; camera()->getViewMatrixAsLookAt(eye, at, up, right); vl::vec4 focus_point_w, focus_point; focus_point_w.x() = at.x(); focus_point_w.y() = at.y(); //focus_point_w.z() = at.z(); focus_point_w.z() = at.z(); focus_point_w.w() = 1.0; camera()->project(focus_point_w, focus_point); vl::vec3 vp0; vp0.x() = mCurrentX; vp0.y() = mCurrentY; vp0.z() = focus_point.z(); vl::vec4 v4p0; camera()->unproject(vp0, v4p0); mMode = ZoomMode; float t = delta / 20.0f; t *= zoomSpeed(); vec3 camera_pos = camera()->modelingMatrix().getT(); if (delta > 0) { camera_pos.x() += (v4p0.x() - camera_pos.x()) / 5; camera_pos.y() -= (v4p0.y() - camera_pos.y()) / 5; mPivot.x() += (v4p0.x() - mPivot.x()) / 5; mPivot.y() -= (v4p0.y() - mPivot.y()) / 5; } else { camera_pos.x() -= (v4p0.x() - camera_pos.x()) / 5; camera_pos.y() += (v4p0.y() - camera_pos.y()) / 5; mPivot.x() -= (v4p0.x() - mPivot.x()) / 5; mPivot.y() += (v4p0.y() - mPivot.y()) / 5; } real distance = (camera_pos - mPivot).length(); camera_pos = camera_pos - camera()->modelingMatrix().getZ()*t*distance; mat4 m = camera()->modelingMatrix(); m.setT(camera_pos); camera()->setModelingMatrix(m); openglContext()->update(); mMode = NoMode; } bool VLRenderer::m_IsInit = false; VLRenderer::VLRenderer() :m_Width(800) , m_Height(600) { if (!m_IsInit) { m_IsInit = true; vl::VisualizationLibrary::init(true); vl::globalSettings()->setCheckOpenGLStates(false); } mCubeTransform = new vl::Transform; trackball = new TrackBall; } VLRenderer::~VLRenderer() { dispatchDestroyEvent(); vl::VisualizationLibrary::shutdown(); } void VLRenderer::Init(void) { initGLContext(true); mRendering = new vl::Rendering; mSceneManager = new vl::SceneManagerActorTree; mRendering->sceneManagers()->push_back(mSceneManager.get()); rendering()->camera()->viewport()->setClearColor(vl::darkgray); rendering()->camera()->viewport()->setClearFlags(vl::CF_CLEAR_COLOR_DEPTH_STENCIL); rendering()->camera()->viewport()->set(0, 0, m_Width, m_Height); ResetCamera(); /* use a framebuffer object as render target */ mFBO = openglContext()->createFramebufferObject(m_Width, m_Height); rendering()->renderer()->setFramebuffer(mFBO.get()); /* bind a depth buffer */ mFBODB = new vl::FBODepthBufferAttachment(vl::DBF_DEPTH_COMPONENT16); mFBO->addDepthAttachment(mFBODB.get()); /* use texture as color buffer */ mTexture = new vl::Texture(m_Width, m_Height, vl::TF_RGBA); vl::ref fbo_tex_attachm = new vl::FBOTexture2DAttachment(mTexture.get(), 0, vl::T2DT_TEXTURE_2D); mFBO->addTextureAttachment(vl::AP_COLOR_ATTACHMENT0, fbo_tex_attachm.get()); mFBO->setDrawBuffer(vl::RDB_COLOR_ATTACHMENT0); //vl::ref trackball = new vl::TrackballManipulator; trackball->setCamera(rendering()->camera()); trackball->setTransform(NULL); trackball->setPivot(vl::vec3(0, 0, 0)); //trackball->setRotationButton(100000); trackball->setTranslationSpeed(0.5); trackball->mVLRenderer = this; openglContext()->addEventListener(trackball.get()); /*mvg = new vl::VectorGraphics; vl::ref vgscene = new vl::SceneManagerVectorGraphics; vgscene->vectorGraphicObjects()->push_back(mvg.get()); mRendering->sceneManagers()->push_back(vgscene.get());*/ } void VLRenderer::Render(void) { // --- scene update --- rendering()->setFrameClock(vl::Time::currentTime()); rendering()->render(); if (openglContext()->hasDoubleBuffer()) openglContext()->swapBuffers(); } bool VLRenderer::UpdateSize(unsigned int w, unsigned int h) { if (w == m_Width && h == m_Height) return false; if (w <= 0 || h <= 0) return false; m_Width = w; m_Height = h; if (mTexture)mTexture->destroyTexture(); mTexture = nullptr; if (mFBODB)mFBODB->deleteRenderBuffer(); mFBODB = nullptr; if (mFBO)mFBO->deleteFBO(); mFBO = nullptr; rendering()->camera()->viewport()->setWidth(m_Width); rendering()->camera()->viewport()->setHeight(m_Height); rendering()->camera()->setProjectionPerspective(); mFBO = openglContext()->createFramebufferObject(m_Width, m_Height); rendering()->renderer()->setFramebuffer(mFBO.get()); mFBODB = new vl::FBODepthBufferAttachment(vl::DBF_DEPTH_COMPONENT16); mFBO->addDepthAttachment(mFBODB.get()); mTexture = new vl::Texture(m_Width, m_Height, vl::TF_RGBA); vl::ref fbo_tex_attachm = new vl::FBOTexture2DAttachment(mTexture.get(), 0, vl::T2DT_TEXTURE_2D); mFBO->addTextureAttachment(vl::AP_COLOR_ATTACHMENT0, fbo_tex_attachm.get()); mFBO->setDrawBuffer(vl::RDB_COLOR_ATTACHMENT0); dispatchResizeEvent(m_Width, m_Height); UpdateScene(); return true; } double VLRenderer::GetWorldDis(double *p0, double *p1) { vl::vec3 eye, at, up, right; mRendering->camera()->getViewMatrixAsLookAt(eye, at, up, right); vl::vec4 focus_point_w, focus_point; focus_point_w.x() = at.x(); focus_point_w.y() = at.y(); focus_point_w.z() = 0.0; focus_point_w.w() = 1.0; mRendering->camera()->project(focus_point_w, focus_point); vl::vec3 vp0, vp1; vp0.x() = p0[0]; vp0.y() = p0[1]; vp0.z() = focus_point.z(); vp1.x() = p1[0]; vp1.y() = p1[1]; vp1.z() = focus_point.z(); vl::vec4 v4p0, v4p1; mRendering->camera()->unproject(vp0, v4p0); mRendering->camera()->unproject(vp1, v4p1); return sqrt((v4p0.x() - v4p1.x()) * (v4p0.x() - v4p1.x()) + (v4p0.y() - v4p1.y()) * (v4p0.y() - v4p1.y())/* + (v4p0.z() - v4p1.z()) * (v4p0.z() - v4p1.z())*/); } /*void VLRenderer::UpdateCurrentLayer() { if (m_RenderMode != RenderMode2D) return; if (m_DataType == DATATYPE_BP) { if (m_BPData == nullptr) return; m_PartSelected = -1; ClearScene(); m_BPData->UpdateCurrentLayerParts(); std::vector parts = m_BPData->GetParts(); for (unsigned int i = 0; i < parts.size(); i++) { if (parts[i]->GetActor().get() == nullptr) continue; m_actors.push_back(parts[i]->GetActor()); } UpdateScene(); } }*/ void VLRenderer::UpdateScene(void) { vl::ActorCollection actors; mSceneManager->tree()->extractActors(actors); for (unsigned int i = 0; i < actors.size(); i++) mSceneManager->tree()->eraseActor(actors.at(i)); rendering()->transform()->eraseAllChildrenRecursive(); #if 0 if (m_RenderMode == RenderMode3D) m_vtkRenderWindowInteractor->SetInteractorStyle(style3d); else m_vtkRenderWindowInteractor->SetInteractorStyle(style2d); #endif for (unsigned int i = 0; i < m_actors.size(); i++) { if (m_actors[i].get() != nullptr) { mSceneManager->tree()->addActor(m_actors[i].get()); rendering()->transform()->addChild(m_actors[i]->transform()); } } InitScene(); } void VLRenderer::ClearScene(bool ClearJobs) { vl::ActorCollection actors; mSceneManager->tree()->extractActors(actors); for (unsigned int i = 0; i < actors.size(); i++) mSceneManager->tree()->eraseActor(actors.at(i)); rendering()->transform()->eraseAllChildrenRecursive(); m_actors.clear(); if (ClearJobs && m_BPData) { delete m_BPData; m_BPData = nullptr; } InitScene(); } vl::ref VLRenderer::MakePlatform(const vec3& origin, real xside, real yside, int x, int y, bool gen_texcoords, fvec2 uv0, fvec2 uv1, bool center) { vl::ref geom = new Geometry; geom->setObjectName("Platform"); vl::ref vert3 = new ArrayFloat3; vl::ref text2 = new ArrayFloat2; geom->setVertexArray(vert3.get()); VL_CHECK(x >= 2) VL_CHECK(y >= 2) real dx = xside / (x - 1); real dz = yside / (y - 1); if (center) { xside /= 2.0f; yside /= 2.0f; } vert3->resize(x * y); if (gen_texcoords) { geom->setTexCoordArray(0, text2.get()); text2->resize(x * y); } // create vertices int vert_idx = 0; for (int i = 0; iat(vert_idx) = (fvec3)(vec3(-xside + j*dx, -yside + i*dz, 0) + vec3(0, 0, 0)); if (gen_texcoords) { float tu = (float)j / (x - 1); // 0 .. 1 float tv = (float)i / (y - 1); // 0 .. 1 text2->at(vert_idx).s() = (1.0f - tu) * uv0.s() + tu * uv1.s(); text2->at(vert_idx).t() = (1.0f - tv) * uv0.t() + tv * uv1.t(); } } // create indices vl::ref polys = new DrawElementsUInt(PT_QUADS); geom->drawCalls().push_back(polys.get()); int idx = 0; polys->indexBuffer()->resize((y - 1)*(x - 1) * 4); for (int i = 0; iindexBuffer()->at(idx++) = j + 0 + x*(i + 1); polys->indexBuffer()->at(idx++) = j + 1 + x*(i + 1); polys->indexBuffer()->at(idx++) = j + 1 + x*(i + 0); polys->indexBuffer()->at(idx++) = j + 0 + x*(i + 0); } } #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2) geom->makeGLESFriendly(); #endif return geom; } vl::ref VLRenderer::MakePlatform(const vec3& origin, real diameter, unsigned int phi) { vl::ref geom = new Geometry; geom->setObjectName("Platform"); vl::ref vert3 = new ArrayFloat3; vert3->resize(phi + 1); geom->setVertexArray(vert3.get()); vl::ref tris = new DrawElementsUInt(PT_TRIANGLE_FAN); tris->indexBuffer()->resize(phi + 2); geom->drawCalls().push_back(tris.get()); int idx = 0; diameter /= 2; vert3->at(0) = origin; for (int j = 0; j < phi; ++j) { vec3 v(diameter, 0, 0); v = mat4::getRotation(360.0f / phi * j, 0, 0, 1) * v; vert3->at(j + 1) = (fvec3)(v + origin); } // top fan tris->indexBuffer()->at(idx++) = 0; for (int j = 0; j < phi + 1; ++j) tris->indexBuffer()->at(idx++) = 1 + j % phi; #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2) geom->makeGLESFriendly(); #endif return geom; } void VLRenderer::InitScene() { vl::ref platform; if (m_PlatformShape == PS_ROUND) platform = MakePlatform(vl::vec3(0, 0, 0), m_PlatformWidth, 100); else platform = MakePlatform(vl::vec3(0, 0, 0), m_PlatformWidth, m_PlatformDepth, 2, 2); vl::ref effect = new vl::Effect; effect->shader()->enable(vl::EN_DEPTH_TEST); effect->shader()->enable(vl::EN_BLEND); effect->shader()->gocColor()->setValue(vl::lightgray); /* wireframe shader */ //effect->lod(0)->push_back(new Shader); //effect->shader(0, 1)->enable(EN_BLEND); //effect->shader(0, 1)->enable(EN_DEPTH_TEST); //effect->shader(0, 1)->enable(EN_POLYGON_OFFSET_LINE); //effect->shader(0, 1)->gocPolygonOffset()->set(-0.5f, -0.5f); //effect->shader(0, 1)->gocPolygonMode()->set(PM_LINE, PM_LINE); //effect->shader(0, 1)->gocColor()->setValue(vl::fvec4(0, 0.05, 0.05, 0.02)); //effect->shader(0, 1)->gocBlendFunc()->set(vl::BF_SRC_ALPHA, vl::BF_ONE_MINUS_SRC_ALPHA); mSceneManager->tree()->addActor(platform.get(), effect.get()); } void VLRenderer::SetCurrentLayer(unsigned int layer) { if (m_RenderMode != RenderMode2D) return; if (m_DataType == DATATYPE_BP) { if (m_BPData == nullptr) return; if (m_BPData->GetCurrentLayer() == layer) return; m_PartSelected = -1; ClearScene(); //m_BPData->GetLayerData(layer); std::map* partMap = m_BPData->GetPartMap(); for (map::iterator it = partMap->begin(); it != partMap->end(); it++) { Part* part = it->second; if (part->GetActor().get() == nullptr) continue; m_actors.push_back(part->GetActor()); } UpdateScene(); } } void VLRenderer::SetPreviewLayer(unsigned int layer) { if (m_RenderMode != RenderMode2D) return; if (m_DataType == DATATYPE_BP) { if (m_BPData == nullptr) return; if (m_BPData->GetCurrentLayer() == layer) return; m_PartSelected = -1; ClearScene(); //m_BPData->GetPrevLayerData(layer); std::map* partMap = m_BPData->GetPartMap(); for (map::iterator it = partMap->begin(); it != partMap->end(); it++) { Part* part = it->second; if (part->GetActor().get() == nullptr) continue; m_actors.push_back(part->GetActor()); } UpdateScene(); } } //void VLRenderer::SetJob(FileProcessor * jfp) //{ // if (jfp == nullptr) // return; // // if (m_BPData == nullptr) // m_BPData = new BPData; // // if (m_BPData->GetJobFileProcessor() != nullptr && // jfp->GetJobUid() == m_BPData->GetJobID()) // return; // // ClearScene(); // // m_DataType = DATATYPE_BP; // m_BPData->SetJob(jfp); // if (m_RenderMode == RenderMode2D) // { // m_BPData->GetPrevLayerData(0); // m_BPData->GetJobFileProcessor()->m_IsOpen = true; // } // else // m_BPData->GetJobData(); // // std::map* partMap = m_BPData->GetPartMap(); // for (map::iterator it = partMap->begin(); it != partMap->end(); it++) { // AddActor(it->second->GetActor()); // } // UpdateScene(); //} //void VLRenderer::AddPart(MetaData::Part* part) //{ // Part* tmep = m_BPData->AddPart(part); // AddActor(tmep->GetActor()); // UpdateScene(); // //UpdateScene(); //} //void VLRenderer::DelPart(MetaData::Part* part) //{ // Part* temp = m_BPData->GetPart(part->id); // for (vector>::iterator it = m_actors.begin(); it != m_actors.end();) { // vl::ref act = (*it); // if (act == temp->GetActor()) { // it = m_actors.erase(it); // } // else { // it++; // } // } // m_BPData->DelPart(part); // UpdateScene(); //} void VLRenderer::SetRenderMode(RenderMode mode) { if (m_RenderMode == mode) return; m_RenderMode = mode; if (mode == RenderMode2D) SetCurrentLayer(0); else if (mode == RenderMode3D) { if (m_DataType == DATATYPE_BP) { m_BPData->GetJobData(); ClearScene(); std::map* partMap = m_BPData->GetPartMap(); for (map::iterator it = partMap->begin(); it != partMap->end(); it++) { AddActor(it->second->GetActor()); } UpdateScene(); } } } /*std::vector* VLRenderer::GetParts(void) { if (m_DataType == DATATYPE_BP && m_BPData) return &m_BPData->GetParts(); else return nullptr; }*/ std::map* VLRenderer::GetPartMap() { if (m_DataType == DATATYPE_BP && m_BPData) return m_BPData->GetPartMap(); else return nullptr; } void VLRenderer::UpdateGlobalOffset(double offset_x, double offset_y) { if (offset_x == m_GlobalOffsetX && offset_y == m_GlobalOffsetY) return; m_GlobalOffsetX = offset_x; m_GlobalOffsetY = offset_y; if (m_BPData == NULL)return; std::map* partMap = m_BPData->GetPartMap(); for (map::iterator it = partMap->begin(); it != partMap->end(); it++) { it->second->UpdateGlobalOffset(offset_x, offset_y); } } void VLRenderer::ResetCamera(void) { double high = (m_PlatformWidth / 2 + 20) / tan(0.55); rendering()->camera()->setProjectionPerspective(); vl::mat4 m = vl::mat4::getLookAt(vl::vec3(0, 0, high), vl::vec3(0, 0, 0), vl::vec3(0, 1, 0)); rendering()->camera()->setViewMatrix(m); trackball->setPivot(vl::vec3(0, 0, 0)); } void VLRenderer::SetPlatfromSize(double width, double depth, double height) { if (width < 10.0 || depth < 10.0 || height < 10.0) return; m_PlatformWidth = width; m_PlatformDepth = depth; m_PlatformHeight = height; UpdateScene(); ResetCamera(); } void VLRenderer::SetPlatformShape(PlatformShape shape) { m_PlatformShape = shape; } void VLRenderer::AddActor(vl::ref actor) { if (!actor) return; m_actors.push_back(actor); } Part* VLRenderer::GetPart(unsigned int index) { if (m_BPData) return m_BPData->GetPart(index); else return nullptr; }