基于弧球四元数旋转矩阵旋转我的立方体稍微偏离
我试图旋转我的立方体使用四元数矩阵旋转基于arcball鼠标移动。 我的魔方正在渲染,它有移动/旋转,但它不仅仅是围绕一个轴旋转,它也在朝我的鼠标方向移动,所以我认为从我的轨迹球获得的数据有点偏离,或者将我的四元数转换为旋转矩阵的方式稍微偏离。 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;
}
链接地址: http://www.djcxy.com/p/81851.html
上一篇: Rotation of my cube based on arcball quaternion rotation matrix slightly off