OpenGL漫游模型示例

【OpenGL漫游模型示例】OpenGL漫游模型示例:

#include #include #include #include #include "TrackballController.h"#define CIGAMA 0.1TrackballController* TrackballController::m_inst(0); TrackballController* TrackballController::Inst() { if(!m_inst) { m_inst = new TrackballController(); }return m_inst; }TrackballController::TrackballController(void) { mOldMouseX=0; mOldMouseY=0; m_vPtTrans = glm::vec2(0.0f, 0.0f); //鼠标平移距离mRotationAangle=0; //旋转角度 mDistanceToModelCenter = -2.0; mRotationAaxis_Local=glm::vec3(1.0f, 0.0f, 0.0f); //初始化视图、平移、旋转、缩放矩阵 mViewMatrix = mTranslationMatrix = mRotationMatrix = mScaleMatrix = glm::mat4(1.0); mScrollSpeed = 0.0f; m_fScale = 1.0f; //缩放比例mMouseButton = -1; //标记鼠标按下的键 spin_y_old = 0.0f; //模型旋转角度初始化 }TrackballController::~TrackballController(void) { }void TrackballController::OnMouseMove(int x, int y) { // /*if ( abs(x - mOldMouseX) < CIGAMA && abs(y - mOldMouseY) < CIGAMA ) { return; }*/if ( GLFW_MOUSE_BUTTON_LEFT == mMouseButton ) { GLint viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); //获取视口大小 //转换屏幕坐标为opengl坐标 glm::vec2 newMouse = scaleMouse( glm::vec2(x, y), glm::vec2(viewport[2],viewport[3])); glm::vec2 oldMouse = scaleMouse( glm::vec2(mOldMouseX, mOldMouseY), glm::vec2(viewport[2],viewport[3])); //计算平移距离 glm::vec2 d = (newMouse - oldMouse); //y轴方向上移动的距离大于x轴方向上的距离时,平移 if (abs(mOldMouseX - x) < abs(mOldMouseY - y)) { m_vPtTrans = d; } else//反之,旋转 { float RotationAangle = 360*(x-mOldMouseX)/m_fWinWidth; mRotationMatrix=glm::rotate(mRotationMatrix, RotationAangle,glm::vec3(0.0f,1.0f,0.0f) ); //spin_y_old = mRotationAangle; //SetRotateParameter(newMouse,oldMouse); }mOldMouseX = x; mOldMouseY = y; //更新模型矩阵 UpdateMatrix(); } }void TrackballController::OnMouseScroll( int value ) { if ( value > 0 ) { // 推远模型 //mDistanceToModelCenter += mScrollSpeed; m_fScale *= (1.0f+mScrollSpeed); } else if ( value < 0 && m_fScale >= mScrollSpeed) { // 拉近模型 //mDistanceToModelCenter -= mScrollSpeed; m_fScale *= (1.0f-mScrollSpeed); }//printf("value=https://www.it610.com/article/%d, mDistanceToModelCenter=%f/n",value, mDistanceToModelCenter); UpdateMatrix(); }void TrackballController::onMouseButton( int action,int button ,int x,int y) { if (action != GLFW_PRESS) { mMouseButton = -1; return; }mMouseButton = button; mOldMouseX = x; mOldMouseY = y; }void TrackballController::UpdateMatrix() { //mTranslationMatrix = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f, 0.0f, mDistanceToModelCenter)); mScaleMatrix = glm::scale(glm::mat4(1.0f),glm::vec3(m_fScale, m_fScale, m_fScale)); mTranslationMatrix = glm::translate(mTranslationMatrix,glm::vec3(0.0f, m_vPtTrans.y, mDistanceToModelCenter)); mViewMatrix = mTranslationMatrix * mRotationMatrix * mScaleMatrix; m_vPtTrans = glm::vec2(0.0f,0.0f); mDistanceToModelCenter = 0.0f; }glm::vec2 TrackballController::scaleMouse(glm::vec2 coords, glm::vec2 viewport) { /*return glm::vec2( static_cast(coords.x*2.0f) / static_cast(viewport.x) - 1.0f, 1.0f - static_cast(coords.y*2.0f) / static_cast(viewport.y) ); */return glm::vec2( static_cast(coords.x) / static_cast(viewport.x), 1.0f - static_cast(coords.y) / static_cast(viewport.y) ); }glm::vec3 TrackballController::projectToSphere(glm::vec2 xy) { static const float sqrt2 = sqrtf(2.f); glm::vec3 result; float d = glm::length(xy); float size_=2; if (d < size_ * sqrt2 / 2.f) { result.z = sqrtf(size_ * size_ - d*d); } else { float t = size_ / sqrt2; result.z = t*t / d; }result.x = xy.x; result.y = xy.y; return glm::normalize(result); }void TrackballController::SetRotateParameter(glm::vec2 newMouse,glm::vec2 oldMouse) { if (newMouse == oldMouse) { return; }glm::vec3 p1 = projectToSphere(oldMouse); glm::vec3 p2 = projectToSphere(newMouse); glm::vec3 r_axis_world = glm::cross(p1, p2); glm::vec3 d = 0.5f*(p1 - p2); mRotationAangle= 180*glm::length(d); glm::vec3 r_axis_local_end=glm::vec3(glm::inverse(mViewMatrix)*glm::vec4(r_axis_world,1)); glm::vec3 r_axis_local_start=glm::vec3(glm::inverse(mViewMatrix)*glm::vec4(0.0,0.0,0.0,1)); mRotationAaxis_Local=r_axis_local_end-r_axis_local_start; mRotationMatrix=glm::rotate(mRotationMatrix, mRotationAangle,mRotationAaxis_Local ); //glm::vec3(0,1,0) }//初始化场景初始参数 void TrackballController::SetInitialState( glm::vec3 CameraPos, glm::vec3 modelCenter, glm::vec3 modelSize) { m_fScale = 1.0f; mTranslationMatrix = mRotationMatrix = mScaleMatrix = glm::mat4(1.0); spin_y_old = 0; mDistanceToModelCenter = -1.0 * glm::length( CameraPos - modelCenter ); mViewMatrix = glm::lookAt(CameraPos, modelCenter, glm::vec3(0.0f,1.0f,0.0f)); // 根据模型的尺寸,计算出鼠标滚轮对模型的推远与拉近的速度 float length = glm::length( modelSize ); mScrollSpeed = length * 0.1f; UpdateMatrix(); }//自动旋转参数设置 void TrackballController::AutoRotateAngle( GLfloat fAngle ) { mRotationMatrix=glm::rotate(mRotationMatrix, fAngle-spin_y_old,glm::vec3(0.0f,1.0f,0.0f) ); spin_y_old = fAngle; UpdateMatrix(); }//设置视口大小 void TrackballController::ReSize( GLfloat fWidth,GLfloat fHeight ) { m_fWinWidth = fWidth; m_fWinHeight = fHeight; }

    推荐阅读