OpenGL鼠标旋转物体

测试发现,还是NEHE的鼠标旋转物体效果好啊,但NEHE是在基于Windows 的程序框架下编写的,不少代码融入到了windows编程中,感觉比较混乱,所以就想提取出来,在基于控制台的框架下实现出来,在此框架下代码结构比较简单,便于以后再使用这些代码,也就是便于代码复用。主程序代码如下

#include <stdlib.h>
#include <GL/glut.h>
#include <stdio.h>
#include "math.h"
#include "ArcBall.h"

// object
GLfloat vertices[] = {-1.0,-1.0,-1.0,1.0,-1.0,-1.0,
1.0,1.0,-1.0, -1.0,1.0,-1.0, -1.0,-1.0,1.0,
1.0,-1.0,1.0, 1.0,1.0,1.0, -1.0,1.0,1.0};

GLfloat colors[] = {0.0,0.0,0.0,1.0,0.0,0.0,
1.0,1.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0,
1.0,0.0,1.0, 1.0,1.0,1.0, 0.0,1.0,1.0};

GLubyte cubeIndices[]={0,3,2,1,2,3,7,6,0,4,7,3,1,2,6,5,4,5,6,7,0,1,5,4};

// mouse control
Matrix4fT   Transform   = {  1.0f,  0.0f,  0.0f,  0.0f,                // NEW: Final Transform
0.0f,  1.0f,  0.0f,  0.0f,
0.0f,  0.0f,  1.0f,  0.0f,
0.0f,  0.0f,  0.0f,  1.0f };

Matrix3fT   LastRot     = {  1.0f,  0.0f,  0.0f,                    // NEW: Last Rotation
0.0f,  1.0f,  0.0f,
0.0f,  0.0f,  1.0f };

Matrix3fT   ThisRot     = {  1.0f,  0.0f,  0.0f,                    // NEW: This Rotation
0.0f,  1.0f,  0.0f,
0.0f,  0.0f,  1.0f };

ArcBallT    ArcBall(640.0f, 480.0f);                                // NEW: ArcBall Instance
Point2fT    MousePt;                                                // NEW: Current Mouse Point
bool        isClicked  = false;                                        // NEW: Clicking The Mouse?
bool        isDragging = false;                                        // NEW: Dragging The Mouse?


void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    glPushMatrix();                                                    // NEW: Prepare Dynamic Transform
    glMultMatrixf(Transform.M);                                        // NEW: Apply Dynamic Transform
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices);
    glPopMatrix();   

    glutSwapBuffers();
}

void mouse(int btn, int state, int x, int y)
{
    if(btn==GLUT_LEFT_BUTTON)
    {
        switch(state)
        {
        case GLUT_DOWN:           
            isClicked = true;
            printf_s("startmotion: x = %d, y = %d\n",x,y);
            break;
        case GLUT_UP:
            isClicked = false;
            isDragging = false;
            printf_s("stopmotion: x = %d, y = %d\n",x,y);
            break;
        }
    }

    if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
    {
        Matrix3fSetIdentity(&LastRot);                                // Reset Rotation
        Matrix3fSetIdentity(&ThisRot);                                // Reset Rotation
        Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot);        // Reset Rotation

        glutPostRedisplay();
    }
}

void mouseMotion(int x, int y)
{
    MousePt.s.X = x;
    MousePt.s.Y = y;   

    if (!isDragging)                                                // Not Dragging
    {
        if (isClicked)                                                // First Click
        {
            isDragging = true;                                        // Prepare For Dragging
            LastRot = ThisRot;                                        // Set Last Static Rotation To Last Dynamic One           
            ArcBall.click(&MousePt);                                // Update Start Vector And Prepare For Dragging
        }
    }
    else
    {
        if (isClicked)                                                // Still Clicked, So Still Dragging
        {
            Quat4fT     ThisQuat;

            ArcBall.drag(&MousePt, &ThisQuat);                        // Update End Vector And Get Rotation As Quaternion
            Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat);        // Convert Quaternion Into Matrix3fT
            Matrix3fMulMatrix3f(&ThisRot, &LastRot);                // Accumulate Last Rotation Into This One
            Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot);    // Set Our Final Transform's Rotation From This One
        }
    }

    glutPostRedisplay();
}

void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 27: // VK_ESCAPE
        exit(0);
        break;
    }
}

void myReshape(int w, int h)
{
    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
        glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
    else
        glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
}

void main(int argc, char **argv)
{
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutCreateWindow("colorcube");

    glutReshapeFunc(myReshape);
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(mouseMotion);
    glutKeyboardFunc(keyboard);

    glEnable(GL_DEPTH_TEST);

    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glColorPointer(3,GL_FLOAT, 0, colors);

    glClearColor(0.0,0.0,0.0,1.0);
    glColor3f(1.0,1.0,1.0);

    glutMainLoop();
}

,另外再包含NEHE教程中的ArcBall.h和ArcBall.cpp程序。

ArcBall.cpp中包含的头文件还要做如下修改                                

//#include <gl\gl.h>        // 注释掉                                       

//#include <gl\glu.h>      // 注释掉                          

#include <gl\glut.h>       // 做修改                                

 

 

 

 

 

 

 

可以尝试一下,与之前的鼠标跟踪球程序对比,哪个效果好,感觉还是NEHE这个功能完善。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值