0

我试图使用四元数旋转我的立方体,以基于轨迹球鼠标移动进行矩阵旋转。我的立方体正在渲染,它有运动/旋转,但它不仅仅是绕轴旋转,它也在向我的鼠标方向移动,所以我认为我从轨迹球获得的数据有点偏离,或者我将我的四元数转换为旋转矩阵的方式略有偏差。trackball_ptov 是我将鼠标位置转换为轨迹球的地方。mouseMotion() 是我从四元数创建旋转矩阵的地方。

我的主要内容:

#include "Angel.h"
#include <gl/glew.h>
#include <glut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
using namespace std;

#define bool int  /* if system does not support bool type */
#define false 0
#define true 1
#define M_PI 3.14159265358 /* if not in math.h */
int winWidth, winHeight;
float angle = 0.0, axis[3], trans[3];
bool trackingMouse = false;
float lastPos[3] = {0.0, 0.0, 0.0};
float aspect = 1.0;
int curx, cury;
int startX, startY;
int modelInit=1;
//the program object
GLuint program = 0;
 glm::mat4 model;

typedef Angel::vec4 color4;
typedef Angel::vec4 point4;
const int NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle)
point4 points[NumVertices];
color4 colors[NumVertices];

enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
int Axis = Xaxis;
GLuint mvpUniform;
GLuint shaderaxis;
int Index = 0;


// Vertices of a unit cube centered at origin, sides aligned with axes
point4 vertices[8]={
        point4(-0.5, -0.5, 0.5, 1.0),
        point4(-0.5, 0.5, 0.5, 1.0),
        point4(0.5, 0.5, 0.5, 1.0),
        point4(0.5, -0.5, 0.5, 1.0),
        point4(-0.5, -0.5, -0.5, 1.0),
        point4(-0.5, 0.5, -0.5, 1.0),
        point4(0.5, 0.5, -0.5, 1.0),
        point4(0.5, -0.5, -0.5, 1.0)
};

// RGBA colors
color4 vertex_colors[8] = {
        color4(0.0, 0.0, 0.0, 1.0), // black
        color4(1.0, 0.0, 0.0, 1.0), // red
        color4(1.0, 1.0, 0.0, 1.0), // yellow
        color4(0.0, 1.0, 0.0, 1.0), // green
        color4(0.0, 0.0, 1.0, 1.0), // blue
        color4(1.0, 0.0, 1.0, 1.0), // magenta
        color4(1.0, 1.0, 1.0, 1.0), // white
        color4(0.0, 1.0, 1.0, 1.0) // cyan
};

// quad generates two triangles for each face and assigns colors to the vertices
void quad(int a, int b, int c, int d) {
        colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
        colors[Index] = vertex_colors[b]; points[Index] = vertices[b]; Index++;
        colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
        colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
        colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
        colors[Index] = vertex_colors[d]; points[Index] = vertices[d]; Index++;
}

// generate 12 triangles: 36 vertices and 36 colors
void colorcube(void) {
        quad(1, 0, 3, 2);
        quad(2, 3, 7, 6);
        quad(3, 0, 4, 7);
        quad(6, 5, 1, 2);
        quad(4, 5, 6, 7);
        quad(5, 4, 0, 1);
}

// OpenGL initialization
void init(void) {
        colorcube();
        // Load shaders and use the resulting shader program
        GLuint program = InitShader("vshader36.glsl", "fshader36.glsl");
        glUseProgram(program);

        // Create a vertex array object
        GLuint vao;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);

        // Create and initialize a buffer object
        GLuint buffer;
        glGenBuffers(1, &buffer);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors), NULL, GL_STATIC_DRAW);

        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
        glBufferSubData(GL_ARRAY_BUFFER, sizeof(points),  sizeof(colors), colors);

        // set up vertex arrays
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

        model = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, -5.0));

        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)));

        mvpUniform = glGetUniformLocation(program, "mvp");
        glEnable(GL_DEPTH_TEST);
        glClearColor(1.0, 1.0, 1.0, 1.0);
}

void trackball_ptov(int x, int y, int width, int height, float v[3]) {
        float d, a;
        /* project x, y onto a hemisphere centered within width, height , note z is up here*/
        v[0] = (2.0*x - width) / width;
        v[1] = (height - 2.0F*y) / height;
        d = sqrt(v[0]*v[0] + v[1]*v[1]);
        v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0));
        a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
        v[0] *= a;
        v[1] *= a;
        v[2] *= a;
}

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

 glm::mat4 proj = glm::perspective(90.F, 1.F, 0.1F, 100.F);

 glm::mat4 view = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, 0.0)); //apply mouse translation
 //view = glm::rotate(view, 0.2*mousediff.x, glm::vec3(0.0, 1.0, 0.0)); //apply mouse rotation
 //view = glm::rotate(view, 0.2*mousediff.y, glm::vec3(1.0, 0.0, 0.0));

//model = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, -5.0));


 //glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(proj));
 glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(proj*view*model));
 //glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(model*view*proj));

 glDrawArrays(GL_TRIANGLES, 0, NumVertices);
 glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y) {
        switch(key) {
                case 033: // Escape Key
                case 'q': case 'Q':
                        exit(EXIT_SUCCESS);
                        break;
        }
}

void mouseButton(int button, int state, int x, int y) {
        if(button==GLUT_RIGHT_BUTTON) exit(0);
        /* holding down left button allows user to rotate cube */
        if(button==GLUT_LEFT_BUTTON)
                switch(state) {
                        case GLUT_DOWN:
                                        trackingMouse = true;
                                        startX = x;
                                        startY = y;
                                        curx = x;
                                        cury = y;
                                        trackball_ptov(x, y, 512, 512, lastPos);
                                        break;
                        case GLUT_UP:
                                        trackingMouse = false;
                                        angle = 0.0;
                                        break;
                }
}

void mouseMotion(int x, int y) {
        float curPos[3], dx, dy, dz;
        /* compute position on hemisphere */

        if(trackingMouse) {
                /* compute the change in position on the hemisphere */
                trackball_ptov(x, y, 512, 512, curPos);

                dx = curPos[0] - lastPos[0];                
                dy = curPos[1] - lastPos[1];
                dz = curPos[2] - lastPos[2];
                if (dx || dy || dz) {
                        /* compute theta and cross product */
                        angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz);
                        axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
                        axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
                        axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];
                        /* update position */
                        lastPos[0] = curPos[0];
                        lastPos[1] = curPos[1];
                        lastPos[2] = curPos[2];
                }
                float w = angle;
                float x = axis[0];
                float y = axis[1];
                float z = axis[2];
                glm::mat4 xform = glm::mat4((1.F - (2.F * ( y*y + z*z ))),(2.F * ( x*y - z*w )),( x*z + y*w ),0.F,
                (2.F * ( x*y + z*w )),(1.F - (2.F * ( x*x + z*z ))),(2.F * ( y*z - x*w )),0.F,
                (2.F * ( x*z - y*w )),(2.F * ( y*z + x*w )),(1.F - (2.F * ( x*x + y*y ))),0.F,
                0.F,0.F,0.F,1.F);

                model = xform*model;
        }
        glutPostRedisplay();
}


int main(int argc, char **argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
        glutInitWindowSize(512, 512);
        glutCreateWindow("Color Cube");
        glewInit();
        init();
        glutDisplayFunc(display);
        glutKeyboardFunc(keyboard);
        glutIdleFunc(display);
        glutMouseFunc(mouseButton);
        glutMotionFunc(mouseMotion);
        glutMainLoop();
        return 0;
}

这是fshader36

     #version 150
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}

这是 VSHADER

#version 330
uniform mat4 mvp;
layout(location=0) in vec4 vPosition;
layout(location=1) in vec4 vColor;
out vec4 color;

void main() {
    color = vColor;
    gl_Position = mvp * vPosition;
}
4

0 回答 0