opengl漫游模型示例

opengl漫游模型示例:

#include <stdio.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <GLFW/glfw3.h>
#include "TrackballController.h"

#define CIGAMA 0.1

TrackballController* 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=%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<float>(coords.x*2.0f) / static_cast<float>(viewport.x) - 1.0f,
                              1.0f - static_cast<float>(coords.y*2.0f) / static_cast<float>(viewport.y) );*/

    return glm::vec2( static_cast<float>(coords.x) / static_cast<float>(viewport.x),
        1.0f - static_cast<float>(coords.y) / static_cast<float>(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;
}
时间: 2024-08-02 17:16:38

opengl漫游模型示例的相关文章

OpenGL入门和示例程序

大家好,今天雅乐网给大家介绍一下OpenGL的一些基本语法和一个简单的示例程序. OpenGL是什么呢?说简单一点,就是一个图形软件包,它提供了许多函数供我们调用.我们看看维基百科上的说法 开放图形库(英语:Open Graphics Library,缩写为OpenGL)是个定义了一个跨编程语言.跨平台的应用程序接口(API)的规范,它用于生成二维.三维图像.这个接口由近三百五十个不同的函数调用组成,用来从简单的图形比特绘制复杂的三维景象.而另一种程序接口系统是仅用于Microsoft Wind

WebGL或OpenGL关于模型视图投影变换的设置技巧

目录 1. 具体实例 2. 解决方案 1) Cube.html 2) Cube.js 3) 运行结果 3. 详细讲解 1) 模型变换 2) 视图变换 3) 投影变换 4) 模型视图投影矩阵 4. 存在问题 1. 具体实例 看了不少的关于WebGL/OpenGL的资料,笔者发现这些资料在讲解图形变换的时候都讲了很多的原理,然后举出一个特别简单的实例(坐标是1.0,0.5的那种)来讲解.确实一看就懂,但用到实际的场景之中就一脸懵逼了(比如地形的三维坐标都是很大的数字).所以笔者这里结合一个具体的实例

CI 搭建简单的MVC模型示例

1.下载CI框架源码 http://codeigniter.org.cn/download 2.我们主要的开发在application 文件夹进行,可以自己根据项目重命名文件夹.(例如公司名称_application,公司名称_system) 3.application->config 里面可以配置相关的内容(以后慢慢添加),数据库的连接配置在database.php 文件夹, $db['default']['hostname'] = 'localhost'; $db['default']['u

CSS制作华为mate8手机模型示例

CSS制作华为mate8手机模型效果图 1.HTML代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div class="phone"> <div class="body"></div> &

UML和模式应用4:初始阶段(4)--需求制品之用例模型示例

1. 前言 上章主要讨论UP初始阶段需求科目对应的制品之一---用例模型,阐述了用例模型的基本概念,使用用例的好处,用例的常用形式. 本章将用一个具体的实例进行详细分析和说明,采用用例的三种常用形式之一---详述风格来说明 处理销售   这个用例的编写. 2. 详述风格的特点 详述风格详细编写所有步骤及各种变化,同时具有补充部分. 一般在需求科目进行时用摘要形式编写了大量用例后,第一次需求讨论会上,用此风格将编写10%的关键用例,并对这10%具有架构意义的用例或场景进行设计和编程 3. 详述风格

LVS-DR模型示例讲解

实验拓扑图:因为DR模型是根据更改目标的MAC地址来实现任务调度的,所以这里我们需要修改两个内核参数.arp_announce:是否通告自己的网络arp_ignore:是否响应别人的arp广播请求配置之前在两台Real Server服务器上面配置httpd服务并创建两个测试页面根据上面的拓扑图我们可以看到调度器跟Real Server都只是用一块网卡,然后VIP地址配置在网卡的子接口上.首先配置调度器的VIP地址: ifconfig ens33:0 10.11.73.100/32 broadca

数仓模型示例

数仓模型案例一.范式建模1.零范式为便于分级说明三范式的特点,我们将不满足任何范式即无范式的数据称为零范式,假设它只满足一个最基本的条件--数据中不存在重复数据.假设根据零范式的定义数据库中有一张保险订单统计表,表中包含了用户id.保险id.用户名.注册省份.注册城市.注册区县.保险名称.购买信息(价格.数量).总保费.购买日期.具体情况如下图:2.一范式在零范式的基础上加上字段具有原子性即属性不可分这个条件后便形成了符合一范式的表.基于上面的保险订单统计表一范式和零范式的区别主要在于将表中的"

pytorch seq2seq模型示例

以下代码可以让你更加熟悉seq2seq模型机制 """ test """ import numpy as np import torch import torch.nn as nn import torch.optim as optim from torch.autograd import Variable # 创建字典 seq_data = [['man', 'women'], ['black', 'white'], ['king', 'que

Opengl使用模型视图变换移动光源

光源绕一个物体旋转,按下鼠标左键时,光源位置旋转. #include <GL/glut.h> static int spin = 0;static GLdouble x_1 = 0.0;static GLdouble y_1 = 0.0;static GLdouble z_1 = 0.0;void init(void){ glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); glEnable