位置: 编程技术 - 正文

OpenGL轨迹球代码(轨迹球怎么调出来)

编辑:rootadmin

推荐整理分享OpenGL轨迹球代码(轨迹球怎么调出来),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:轨迹球鼠标绘图快吗,轨迹球鼠标绘图,轨迹球 建模,轨迹球怎么调出来,轨迹球怎么调出来,轨迹球 fps,轨迹球 建模,轨迹球模块,内容如对您有帮助,希望把文章链接给更多的朋友!

OpenGL轨迹球代码(轨迹球怎么调出来)

转自: ArcBall.cpp ArcBall.h///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////sample.cpp////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#pragma comment( lib, "opengl.lib" ) #pragma comment( lib, "glut.lib")#pragma comment( lib, "glew.lib") #include <GL/glew.h>#include <GL/glut.h>#include <GL/glu.h>#include <math.h> #include "ArcBall.h" //初始化,必须用全局变量的方式,不能用newArcBallT arcBall(.0f,.0f);ArcBallT* ArcBall =&arcBall;// new ArcBallT(.0f,.0f);//&arcBall;void reshape(int w, int h){ glViewport(0,0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1, 1, -1, 1, 1.5, ); glMatrixMode(GL_MODELVIEW); ////ball ArcBall->setBounds((GLfloat)w, (GLfloat)h);//1. 设置窗口边界}void init(){ glClearColor(0,0,0,0); glShadeModel(GL_FLAT);}void display (void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glScalef(1.0, 2.0, 1.0); //glPushMatrix(); glTranslatef(0,0,-3); glScalef(ArcBall->zoomRate, ArcBall->zoomRate, ArcBall->zoomRate);//2. 缩放 glMultMatrixf(ArcBall->Transform.M); //3. 旋转 glutWireCube(1.0); //glPopMatrix(); glFlush (); }//移动void move(int x, int y) { ArcBall->MousePt.s.X = x; ArcBall->MousePt.s.Y = y; ArcBall->upstate(); glutPostRedisplay();}//点击void mouse(int button, int state, int x, int y) { if(button == GLUT_LEFT_BUTTON && state==GLUT_DOWN){ ArcBall->isClicked = true; move(x,y); } else if(button == GLUT_LEFT_BUTTON && state==GLUT_UP) ArcBall->isClicked = false; else if(button == GLUT_RIGHT_BUTTON && state==GLUT_DOWN){ ArcBall->isRClicked = true; move(x,y); } else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) ArcBall->isRClicked = false; ArcBall->upstate(); glutPostRedisplay();}int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(,); glutCreateWindow("HI"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); //registered the mouse event. glutMotionFunc(move); //registered the move event glutMainLoop(); return 0;}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ArcBall.cpp//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include <windows.h> #include <GL/glew.h> #include <math.h> #include "ArcBall.h" //轨迹球参数://直径 2.0f//半径 1.0f//半径平方 1.0fvoid ArcBall_t::_mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const{ Point2fT TempPt; GLfloat length; //复制到临时变量 TempPt = *NewPt; //把长宽调整到[-1 ... 1]区间 TempPt.s.X = (TempPt.s.X * this->AdjustWidth) - 1.0f; TempPt.s.Y = 1.0f - (TempPt.s.Y * this->AdjustHeight); //计算长度的平方 length = (TempPt.s.X * TempPt.s.X) &#; (TempPt.s.Y * TempPt.s.Y); //如果点映射到球的外面 if (length > 1.0f) { GLfloat norm; //缩放到球上 norm = 1.0f / FuncSqrt(length); //设置z坐标为0 NewVec->s.X = TempPt.s.X * norm; NewVec->s.Y = TempPt.s.Y * norm; NewVec->s.Z = 0.0f; } //如果在球内 else { //利用半径的平方为1,求出z坐标 NewVec->s.X = TempPt.s.X; NewVec->s.Y = TempPt.s.Y; NewVec->s.Z = FuncSqrt(1.0f - length); }}ArcBall_t::ArcBall_t(GLfloat NewWidth, GLfloat NewHeight){ this->StVec.s.X =0.0f; this->StVec.s.Y = 0.0f; this->StVec.s.Z = 0.0f; this->EnVec.s.X =0.0f; this->EnVec.s.Y = 0.0f; this->EnVec.s.Z = 0.0f; Matrix4fSetIdentity(&Transform); Matrix3fSetIdentity(&LastRot); Matrix3fSetIdentity(&ThisRot); this->isDragging=false; this->isClicked= false; this->isRClicked = false; this->isZooming = false; this->zoomRate = 1; this->setBounds(NewWidth, NewHeight);}void ArcBall_t::upstate(){ if(!this->isZooming && this->isRClicked){ // 开始拖动 this->isZooming = true; // 设置拖动为变量为true this->LastPt = this->MousePt; this->lastZoomRate = this->zoomRate; } else if(this->isZooming){//正在拖动 if(this->isRClicked){ //拖动 Point2fSub(&this->MousePt, &this->LastPt); this->zoomRate = this->lastZoomRate &#; this->MousePt.s.X * this->AdjustWidth * 2; } else{ //停止拖动 this->isZooming = false; } } else if (!this->isDragging && this->isClicked){ // 如果没有拖动 this->isDragging = true; // 设置拖动为变量为true this->LastRot = this->ThisRot; this->click(&this->MousePt); } else if(this->isDragging){ if (this->isClicked){ //如果按住拖动 Quat4fT ThisQuat; this->drag(&this->MousePt, &ThisQuat); // 更新轨迹球的变量 Matrix3fSetRotationFromQuat4f(&this->ThisRot, &ThisQuat); // 计算旋转量 Matrix3fMulMatrix3f(&this->ThisRot, &this->LastRot); Matrix4fSetRotationFromMatrix3f(&this->Transform, &this->ThisRot); } else // 如果放开鼠标,设置拖动为false this->isDragging = false; }}//按下鼠标,记录当前对应的轨迹球的位置void ArcBall_t::click(const Point2fT* NewPt){ this->_mapToSphere(NewPt, &this->StVec);}//鼠标拖动,计算旋转四元数void ArcBall_t::drag(const Point2fT* NewPt, Quat4fT* NewRot){ //新的位置 this->_mapToSphere(NewPt, &this->EnVec); //计算旋转 if (NewRot) { Vector3fT Perp; //计算旋转轴 Vector3fCross(&Perp, &this->StVec, &this->EnVec); //如果不为0 if (Vector3fLength(&Perp) > Epsilon) { //记录旋转轴 NewRot->s.X = Perp.s.X; NewRot->s.Y = Perp.s.Y; NewRot->s.Z = Perp.s.Z; //在四元数中,w=cos(a/2),a为旋转的角度 NewRot->s.W= Vector3fDot(&this->StVec, &this->EnVec); } //是0,说明没有旋转 else { NewRot->s.X = NewRot->s.Y = NewRot->s.Z = NewRot->s.W = 0.0f; } }}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ArcBall.h///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifndef _ArcBall_h#define _ArcBall_h#include <stdlib.h>// 仅在Debug模式下,启用断言#ifdef _DEBUG# include "assert.h"#else# define assert(x) { }#endif//2维点typedef union Tuple2f_t{ struct { GLfloat X, Y; } s; GLfloat T[2];} Tuple2fT; //3维点typedef union Tuple3f_t{ struct { GLfloat X, Y, Z; } s; GLfloat T[3];} Tuple3fT; //4维点typedef union Tuple4f_t{ struct { GLfloat X, Y, Z, W; } s; GLfloat T[4];} Tuple4fT; //3x3矩阵typedef union Matrix3f_t{ struct { //column major union { GLfloat M; GLfloat XX; GLfloat SX; }; union { GLfloat M; GLfloat XY; }; union { GLfloat M; GLfloat XZ; }; union { GLfloat M; GLfloat YX; }; union { GLfloat M; GLfloat YY; GLfloat SY; }; union { GLfloat M; GLfloat YZ; }; union { GLfloat M; GLfloat ZX; }; union { GLfloat M; GLfloat ZY; }; union { GLfloat M; GLfloat ZZ; GLfloat SZ; }; } s; GLfloat M[9];} Matrix3fT; //4x4矩阵typedef union Matrix4f_t{ struct { //column major union { GLfloat M; GLfloat XX; GLfloat SX; }; union { GLfloat M; GLfloat XY; }; union { GLfloat M; GLfloat XZ; }; union { GLfloat M; GLfloat XW; }; union { GLfloat M; GLfloat YX; }; union { GLfloat M; GLfloat YY; GLfloat SY; }; union { GLfloat M; GLfloat YZ; }; union { GLfloat M; GLfloat YW; }; union { GLfloat M; GLfloat ZX; }; union { GLfloat M; GLfloat ZY; }; union { GLfloat M; GLfloat ZZ; GLfloat SZ; }; union { GLfloat M; GLfloat ZW; }; union { GLfloat M; GLfloat TX; }; union { GLfloat M; GLfloat TY; }; union { GLfloat M; GLfloat TZ; }; union { GLfloat M; GLfloat TW; GLfloat SW; }; } s; GLfloat M[];} Matrix4fT; //定义类型的别名#define Point2fT Tuple2fT #define Quat4fT Tuple4fT #define Vector2fT Tuple2fT #define Vector3fT Tuple3fT #define FuncSqrt sqrtf# define Epsilon 1.0e-5//2维点相加inlinestatic void Point2fAdd(Point2fT* NewObj, const Tuple2fT* t1){ assert(NewObj && t1); NewObj->s.X &#;= t1->s.X; NewObj->s.Y &#;= t1->s.Y;}//2维点相减inlinestatic void Point2fSub(Point2fT* NewObj, const Tuple2fT* t1){ assert(NewObj && t1); NewObj->s.X -= t1->s.X; NewObj->s.Y -= t1->s.Y;}//3维点矢积inlinestatic void Vector3fCross(Vector3fT* NewObj, const Vector3fT* v1, const Vector3fT* v2){ Vector3fT Result; assert(NewObj && v1 && v2); Result.s.X = (v1->s.Y * v2->s.Z) - (v1->s.Z * v2->s.Y); Result.s.Y = (v1->s.Z * v2->s.X) - (v1->s.X * v2->s.Z); Result.s.Z = (v1->s.X * v2->s.Y) - (v1->s.Y * v2->s.X); *NewObj = Result;}//3维点点积inlinestatic GLfloat Vector3fDot(const Vector3fT* NewObj, const Vector3fT* v1){ assert(NewObj && v1); return (NewObj->s.X * v1->s.X) &#; (NewObj->s.Y * v1->s.Y) &#; (NewObj->s.Z * v1->s.Z);}//3维点的长度的平方inlinestatic GLfloat Vector3fLengthSquared(const Vector3fT* NewObj){ assert(NewObj); return (NewObj->s.X * NewObj->s.X) &#; (NewObj->s.Y * NewObj->s.Y) &#; (NewObj->s.Z * NewObj->s.Z);}//3维点的长度inlinestatic GLfloat Vector3fLength(const Vector3fT* NewObj){ assert(NewObj); return FuncSqrt(Vector3fLengthSquared(NewObj));}//设置3x3矩阵为0矩阵inlinestatic void Matrix3fSetZero(Matrix3fT* NewObj){ NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = 0.0f;}//设置4x4矩阵为0矩阵inlinestatic void Matrix4fSetZero(Matrix4fT* NewObj){ NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = 0.0f;}//设置3x3矩阵为单位矩阵inlinestatic void Matrix3fSetIdentity(Matrix3fT* NewObj){ Matrix3fSetZero(NewObj); NewObj->s.M = NewObj->s.M = NewObj->s.M = 1.0f;}//设置4x4矩阵为单位矩阵inlinestatic void Matrix4fSetIdentity(Matrix4fT* NewObj){ Matrix4fSetZero(NewObj); NewObj->s.M = 1.0f; NewObj->s.M = 1.0f; NewObj->s.M = 1.0f; NewObj->s.M=1.0f;}//从四元数设置旋转矩阵inlinestatic void Matrix3fSetRotationFromQuat4f(Matrix3fT* NewObj, const Quat4fT* q1){ GLfloat n, s; GLfloat xs, ys, zs; GLfloat wx, wy, wz; GLfloat xx, xy, xz; GLfloat yy, yz, zz; assert(NewObj && q1); n = (q1->s.X * q1->s.X) &#; (q1->s.Y * q1->s.Y) &#; (q1->s.Z * q1->s.Z) &#; (q1->s.W * q1->s.W); s = (n > 0.0f) ? (2.0f / n) : 0.0f; xs = q1->s.X * s; ys = q1->s.Y * s; zs = q1->s.Z * s; wx = q1->s.W * xs; wy = q1->s.W * ys; wz = q1->s.W * zs; xx = q1->s.X * xs; xy = q1->s.X * ys; xz = q1->s.X * zs; yy = q1->s.Y * ys; yz = q1->s.Y * zs; zz = q1->s.Z * zs; NewObj->s.XX = 1.0f - (yy &#; zz); NewObj->s.YX = xy - wz; NewObj->s.ZX = xz &#; wy; NewObj->s.XY = xy &#; wz; NewObj->s.YY = 1.0f - (xx &#; zz); NewObj->s.ZY = yz - wx; NewObj->s.XZ = xz - wy; NewObj->s.YZ = yz &#; wx; NewObj->s.ZZ = 1.0f - (xx &#; yy);}//3x3矩阵相乘inlinestatic void Matrix3fMulMatrix3f(Matrix3fT* NewObj, const Matrix3fT* m1){ Matrix3fT Result; assert(NewObj && m1); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); *NewObj = Result;}//4x4矩阵相乘inlinestatic void Matrix4fSetRotationScaleFromMatrix4f(Matrix4fT* NewObj, const Matrix4fT* m1){ assert(NewObj && m1); NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX; NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY; NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;}//进行矩阵的奇异&#;分解,旋转矩阵被保存到rot3和rot4中,返回矩阵的缩放因子inlinestatic GLfloat Matrix4fSVD(const Matrix4fT* NewObj, Matrix3fT* rot3, Matrix4fT* rot4){ GLfloat s, n; assert(NewObj); s = FuncSqrt( ( (NewObj->s.XX * NewObj->s.XX) &#; (NewObj->s.XY * NewObj->s.XY) &#; (NewObj->s.XZ * NewObj->s.XZ) &#; (NewObj->s.YX * NewObj->s.YX) &#; (NewObj->s.YY * NewObj->s.YY) &#; (NewObj->s.YZ * NewObj->s.YZ) &#; (NewObj->s.ZX * NewObj->s.ZX) &#; (NewObj->s.ZY * NewObj->s.ZY) &#; (NewObj->s.ZZ * NewObj->s.ZZ) ) / 3.0f ); if (rot3) { rot3->s.XX = NewObj->s.XX; rot3->s.XY = NewObj->s.XY; rot3->s.XZ = NewObj->s.XZ; rot3->s.YX = NewObj->s.YX; rot3->s.YY = NewObj->s.YY; rot3->s.YZ = NewObj->s.YZ; rot3->s.ZX = NewObj->s.ZX; rot3->s.ZY = NewObj->s.ZY; rot3->s.ZZ = NewObj->s.ZZ; n = 1.0f / FuncSqrt( (NewObj->s.XX * NewObj->s.XX) &#; (NewObj->s.XY * NewObj->s.XY) &#; (NewObj->s.XZ * NewObj->s.XZ) ); rot3->s.XX *= n; rot3->s.XY *= n; rot3->s.XZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.YX * NewObj->s.YX) &#; (NewObj->s.YY * NewObj->s.YY) &#; (NewObj->s.YZ * NewObj->s.YZ) ); rot3->s.YX *= n; rot3->s.YY *= n; rot3->s.YZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.ZX * NewObj->s.ZX) &#; (NewObj->s.ZY * NewObj->s.ZY) &#; (NewObj->s.ZZ * NewObj->s.ZZ) ); rot3->s.ZX *= n; rot3->s.ZY *= n; rot3->s.ZZ *= n; } if (rot4) { if (rot4 != NewObj) { Matrix4fSetRotationScaleFromMatrix4f(rot4, NewObj); } n = 1.0f / FuncSqrt( (NewObj->s.XX * NewObj->s.XX) &#; (NewObj->s.XY * NewObj->s.XY) &#; (NewObj->s.XZ * NewObj->s.XZ) ); rot4->s.XX *= n; rot4->s.XY *= n; rot4->s.XZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.YX * NewObj->s.YX) &#; (NewObj->s.YY * NewObj->s.YY) &#; (NewObj->s.YZ * NewObj->s.YZ) ); rot4->s.YX *= n; rot4->s.YY *= n; rot4->s.YZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.ZX * NewObj->s.ZX) &#; (NewObj->s.ZY * NewObj->s.ZY) &#; (NewObj->s.ZZ * NewObj->s.ZZ) ); rot4->s.ZX *= n; rot4->s.ZY *= n; rot4->s.ZZ *= n; } return s;}//从3x3矩阵变为4x4的旋转矩阵inlinestatic void Matrix4fSetRotationScaleFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1){ assert(NewObj && m1); NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX; NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY; NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;}//4x4矩阵的与标量的乘积inlinestatic void Matrix4fMulRotationScale(Matrix4fT* NewObj, GLfloat scale){ assert(NewObj); NewObj->s.XX *= scale; NewObj->s.YX *= scale; NewObj->s.ZX *= scale; NewObj->s.XY *= scale; NewObj->s.YY *= scale; NewObj->s.ZY *= scale; NewObj->s.XZ *= scale; NewObj->s.YZ *= scale; NewObj->s.ZZ *= scale;}//设置旋转矩阵inlinestatic void Matrix4fSetRotationFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1){ GLfloat scale; assert(NewObj && m1); scale = Matrix4fSVD(NewObj, NULL, NULL); Matrix4fSetRotationScaleFromMatrix3f(NewObj, m1); Matrix4fMulRotationScale(NewObj, scale);}typedef class ArcBall_t{protected: //把二维点映射到三维点 inline void _mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const;public: //构造/析构函数 ArcBall_t(GLfloat NewWidth, GLfloat NewHeight); ~ArcBall_t() { }; //设置边界 inline void setBounds(GLfloat NewWidth, GLfloat NewHeight) { assert((NewWidth > 1.0f) && (NewHeight > 1.0f)); //设置长宽的调整因子 this->AdjustWidth = 1.0f / ((NewWidth - 1.0f) * 0.5f); this->AdjustHeight = 1.0f / ((NewHeight - 1.0f) * 0.5f); } //鼠标点击 void click(const Point2fT* NewPt); //鼠标拖动计算旋转 void drag(const Point2fT* NewPt, Quat4fT* NewRot); //更新鼠标状态 void upstate(); //void mousemove(WPARAM wParam,LPARAM lParam);protected: Vector3fT StVec; //保存鼠标点击的坐标 Vector3fT EnVec; //保存鼠标拖动的坐标 GLfloat AdjustWidth; //宽度的调整因子 GLfloat AdjustHeight; //长度的调整因子public: Matrix4fT Transform; //计算变换 Matrix3fT LastRot; //上一次的旋转 Matrix3fT ThisRot; //这次的旋转 float zoomRate; float lastZoomRate; bool isDragging; // 是否拖动 bool isRClicked; // 是否右击鼠标 bool isClicked; // 是否点击鼠标 bool isZooming; //是否正在缩放 Point2fT LastPt; Matrix4fT origTransform; Point2fT MousePt; // 当前的鼠标位置} ArcBallT;#endifple.cpp ArcBall.cpp ArcBall.h///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////sample.cpp////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#pragma comment( lib, "opengl.lib" ) #pragma comment( lib, "glut.lib")#pragma comment( lib, "glew.lib") #include <GL/glew.h>#include <GL/glut.h>#include <GL/glu.h>#include <math.h> #include "ArcBall.h" //初始化,必须用全局变量的方式,不能用newArcBallT arcBall(.0f,.0f);ArcBallT* ArcBall =&arcBall;// new ArcBallT(.0f,.0f);//&arcBall;void reshape(int w, int h){ glViewport(0,0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1, 1, -1, 1, 1.5, ); glMatrixMode(GL_MODELVIEW); ////ball ArcBall->setBounds((GLfloat)w, (GLfloat)h);//1. 设置窗口边界}void init(){ glClearColor(0,0,0,0); glShadeModel(GL_FLAT);}void display (void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glScalef(1.0, 2.0, 1.0); //glPushMatrix(); glTranslatef(0,0,-3); glScalef(ArcBall->zoomRate, ArcBall->zoomRate, ArcBall->zoomRate);//2. 缩放 glMultMatrixf(ArcBall->Transform.M); //3. 旋转 glutWireCube(1.0); //glPopMatrix(); glFlush (); }//移动void move(int x, int y) { ArcBall->MousePt.s.X = x; ArcBall->MousePt.s.Y = y; ArcBall->upstate(); glutPostRedisplay();}//点击void mouse(int button, int state, int x, int y) { if(button == GLUT_LEFT_BUTTON && state==GLUT_DOWN){ ArcBall->isClicked = true; move(x,y); } else if(button == GLUT_LEFT_BUTTON && state==GLUT_UP) ArcBall->isClicked = false; else if(button == GLUT_RIGHT_BUTTON && state==GLUT_DOWN){ ArcBall->isRClicked = true; move(x,y); } else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) ArcBall->isRClicked = false; ArcBall->upstate(); glutPostRedisplay();}int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(,); glutCreateWindow("HI"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); //registered the mouse event. glutMotionFunc(move); //registered the move event glutMainLoop(); return 0;}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ArcBall.cpp//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include <windows.h> #include <GL/glew.h> #include <math.h> #include "ArcBall.h" //轨迹球参数://直径 2.0f//半径 1.0f//半径平方 1.0fvoid ArcBall_t::_mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const{ Point2fT TempPt; GLfloat length; //复制到临时变量 TempPt = *NewPt; //把长宽调整到[-1 ... 1]区间 TempPt.s.X = (TempPt.s.X * this->AdjustWidth) - 1.0f; TempPt.s.Y = 1.0f - (TempPt.s.Y * this->AdjustHeight); //计算长度的平方 length = (TempPt.s.X * TempPt.s.X) &#; (TempPt.s.Y * TempPt.s.Y); //如果点映射到球的外面 if (length > 1.0f) { GLfloat norm; //缩放到球上 norm = 1.0f / FuncSqrt(length); //设置z坐标为0 NewVec->s.X = TempPt.s.X * norm; NewVec->s.Y = TempPt.s.Y * norm; NewVec->s.Z = 0.0f; } //如果在球内 else { //利用半径的平方为1,求出z坐标 NewVec->s.X = TempPt.s.X; NewVec->s.Y = TempPt.s.Y; NewVec->s.Z = FuncSqrt(1.0f - length); }}ArcBall_t::ArcBall_t(GLfloat NewWidth, GLfloat NewHeight){ this->StVec.s.X =0.0f; this->StVec.s.Y = 0.0f; this->StVec.s.Z = 0.0f; this->EnVec.s.X =0.0f; this->EnVec.s.Y = 0.0f; this->EnVec.s.Z = 0.0f; Matrix4fSetIdentity(&Transform); Matrix3fSetIdentity(&LastRot); Matrix3fSetIdentity(&ThisRot); this->isDragging=false; this->isClicked= false; this->isRClicked = false; this->isZooming = false; this->zoomRate = 1; this->setBounds(NewWidth, NewHeight);}void ArcBall_t::upstate(){ if(!this->isZooming && this->isRClicked){ // 开始拖动 this->isZooming = true; // 设置拖动为变量为true this->LastPt = this->MousePt; this->lastZoomRate = this->zoomRate; } else if(this->isZooming){//正在拖动 if(this->isRClicked){ //拖动 Point2fSub(&this->MousePt, &this->LastPt); this->zoomRate = this->lastZoomRate &#; this->MousePt.s.X * this->AdjustWidth * 2; } else{ //停止拖动 this->isZooming = false; } } else if (!this->isDragging && this->isClicked){ // 如果没有拖动 this->isDragging = true; // 设置拖动为变量为true this->LastRot = this->ThisRot; this->click(&this->MousePt); } else if(this->isDragging){ if (this->isClicked){ //如果按住拖动 Quat4fT ThisQuat; this->drag(&this->MousePt, &ThisQuat); // 更新轨迹球的变量 Matrix3fSetRotationFromQuat4f(&this->ThisRot, &ThisQuat); // 计算旋转量 Matrix3fMulMatrix3f(&this->ThisRot, &this->LastRot); Matrix4fSetRotationFromMatrix3f(&this->Transform, &this->ThisRot); } else // 如果放开鼠标,设置拖动为false this->isDragging = false; }}//按下鼠标,记录当前对应的轨迹球的位置void ArcBall_t::click(const Point2fT* NewPt){ this->_mapToSphere(NewPt, &this->StVec);}//鼠标拖动,计算旋转四元数void ArcBall_t::drag(const Point2fT* NewPt, Quat4fT* NewRot){ //新的位置 this->_mapToSphere(NewPt, &this->EnVec); //计算旋转 if (NewRot) { Vector3fT Perp; //计算旋转轴 Vector3fCross(&Perp, &this->StVec, &this->EnVec); //如果不为0 if (Vector3fLength(&Perp) > Epsilon) { //记录旋转轴 NewRot->s.X = Perp.s.X; NewRot->s.Y = Perp.s.Y; NewRot->s.Z = Perp.s.Z; //在四元数中,w=cos(a/2),a为旋转的角度 NewRot->s.W= Vector3fDot(&this->StVec, &this->EnVec); } //是0,说明没有旋转 else { NewRot->s.X = NewRot->s.Y = NewRot->s.Z = NewRot->s.W = 0.0f; } }}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ArcBall.h///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifndef _ArcBall_h#define _ArcBall_h#include <stdlib.h>// 仅在Debug模式下,启用断言#ifdef _DEBUG# include "assert.h"#else# define assert(x) { }#endif//2维点typedef union Tuple2f_t{ struct { GLfloat X, Y; } s; GLfloat T[2];} Tuple2fT; //3维点typedef union Tuple3f_t{ struct { GLfloat X, Y, Z; } s; GLfloat T[3];} Tuple3fT; //4维点typedef union Tuple4f_t{ struct { GLfloat X, Y, Z, W; } s; GLfloat T[4];} Tuple4fT; //3x3矩阵typedef union Matrix3f_t{ struct { //column major union { GLfloat M; GLfloat XX; GLfloat SX; }; union { GLfloat M; GLfloat XY; }; union { GLfloat M; GLfloat XZ; }; union { GLfloat M; GLfloat YX; }; union { GLfloat M; GLfloat YY; GLfloat SY; }; union { GLfloat M; GLfloat YZ; }; union { GLfloat M; GLfloat ZX; }; union { GLfloat M; GLfloat ZY; }; union { GLfloat M; GLfloat ZZ; GLfloat SZ; }; } s; GLfloat M[9];} Matrix3fT; //4x4矩阵typedef union Matrix4f_t{ struct { //column major union { GLfloat M; GLfloat XX; GLfloat SX; }; union { GLfloat M; GLfloat XY; }; union { GLfloat M; GLfloat XZ; }; union { GLfloat M; GLfloat XW; }; union { GLfloat M; GLfloat YX; }; union { GLfloat M; GLfloat YY; GLfloat SY; }; union { GLfloat M; GLfloat YZ; }; union { GLfloat M; GLfloat YW; }; union { GLfloat M; GLfloat ZX; }; union { GLfloat M; GLfloat ZY; }; union { GLfloat M; GLfloat ZZ; GLfloat SZ; }; union { GLfloat M; GLfloat ZW; }; union { GLfloat M; GLfloat TX; }; union { GLfloat M; GLfloat TY; }; union { GLfloat M; GLfloat TZ; }; union { GLfloat M; GLfloat TW; GLfloat SW; }; } s; GLfloat M[];} Matrix4fT; //定义类型的别名#define Point2fT Tuple2fT #define Quat4fT Tuple4fT #define Vector2fT Tuple2fT #define Vector3fT Tuple3fT #define FuncSqrt sqrtf# define Epsilon 1.0e-5//2维点相加inlinestatic void Point2fAdd(Point2fT* NewObj, const Tuple2fT* t1){ assert(NewObj && t1); NewObj->s.X &#;= t1->s.X; NewObj->s.Y &#;= t1->s.Y;}//2维点相减inlinestatic void Point2fSub(Point2fT* NewObj, const Tuple2fT* t1){ assert(NewObj && t1); NewObj->s.X -= t1->s.X; NewObj->s.Y -= t1->s.Y;}//3维点矢积inlinestatic void Vector3fCross(Vector3fT* NewObj, const Vector3fT* v1, const Vector3fT* v2){ Vector3fT Result; assert(NewObj && v1 && v2); Result.s.X = (v1->s.Y * v2->s.Z) - (v1->s.Z * v2->s.Y); Result.s.Y = (v1->s.Z * v2->s.X) - (v1->s.X * v2->s.Z); Result.s.Z = (v1->s.X * v2->s.Y) - (v1->s.Y * v2->s.X); *NewObj = Result;}//3维点点积inlinestatic GLfloat Vector3fDot(const Vector3fT* NewObj, const Vector3fT* v1){ assert(NewObj && v1); return (NewObj->s.X * v1->s.X) &#; (NewObj->s.Y * v1->s.Y) &#; (NewObj->s.Z * v1->s.Z);}//3维点的长度的平方inlinestatic GLfloat Vector3fLengthSquared(const Vector3fT* NewObj){ assert(NewObj); return (NewObj->s.X * NewObj->s.X) &#; (NewObj->s.Y * NewObj->s.Y) &#; (NewObj->s.Z * NewObj->s.Z);}//3维点的长度inlinestatic GLfloat Vector3fLength(const Vector3fT* NewObj){ assert(NewObj); return FuncSqrt(Vector3fLengthSquared(NewObj));}//设置3x3矩阵为0矩阵inlinestatic void Matrix3fSetZero(Matrix3fT* NewObj){ NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = 0.0f;}//设置4x4矩阵为0矩阵inlinestatic void Matrix4fSetZero(Matrix4fT* NewObj){ NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = NewObj->s.M = 0.0f;}//设置3x3矩阵为单位矩阵inlinestatic void Matrix3fSetIdentity(Matrix3fT* NewObj){ Matrix3fSetZero(NewObj); NewObj->s.M = NewObj->s.M = NewObj->s.M = 1.0f;}//设置4x4矩阵为单位矩阵inlinestatic void Matrix4fSetIdentity(Matrix4fT* NewObj){ Matrix4fSetZero(NewObj); NewObj->s.M = 1.0f; NewObj->s.M = 1.0f; NewObj->s.M = 1.0f; NewObj->s.M=1.0f;}//从四元数设置旋转矩阵inlinestatic void Matrix3fSetRotationFromQuat4f(Matrix3fT* NewObj, const Quat4fT* q1){ GLfloat n, s; GLfloat xs, ys, zs; GLfloat wx, wy, wz; GLfloat xx, xy, xz; GLfloat yy, yz, zz; assert(NewObj && q1); n = (q1->s.X * q1->s.X) &#; (q1->s.Y * q1->s.Y) &#; (q1->s.Z * q1->s.Z) &#; (q1->s.W * q1->s.W); s = (n > 0.0f) ? (2.0f / n) : 0.0f; xs = q1->s.X * s; ys = q1->s.Y * s; zs = q1->s.Z * s; wx = q1->s.W * xs; wy = q1->s.W * ys; wz = q1->s.W * zs; xx = q1->s.X * xs; xy = q1->s.X * ys; xz = q1->s.X * zs; yy = q1->s.Y * ys; yz = q1->s.Y * zs; zz = q1->s.Z * zs; NewObj->s.XX = 1.0f - (yy &#; zz); NewObj->s.YX = xy - wz; NewObj->s.ZX = xz &#; wy; NewObj->s.XY = xy &#; wz; NewObj->s.YY = 1.0f - (xx &#; zz); NewObj->s.ZY = yz - wx; NewObj->s.XZ = xz - wy; NewObj->s.YZ = yz &#; wx; NewObj->s.ZZ = 1.0f - (xx &#; yy);}//3x3矩阵相乘inlinestatic void Matrix3fMulMatrix3f(Matrix3fT* NewObj, const Matrix3fT* m1){ Matrix3fT Result; assert(NewObj && m1); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); Result.s.M = (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M) &#; (NewObj->s.M * m1->s.M); *NewObj = Result;}//4x4矩阵相乘inlinestatic void Matrix4fSetRotationScaleFromMatrix4f(Matrix4fT* NewObj, const Matrix4fT* m1){ assert(NewObj && m1); NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX; NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY; NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;}//进行矩阵的奇异&#;分解,旋转矩阵被保存到rot3和rot4中,返回矩阵的缩放因子inlinestatic GLfloat Matrix4fSVD(const Matrix4fT* NewObj, Matrix3fT* rot3, Matrix4fT* rot4){ GLfloat s, n; assert(NewObj); s = FuncSqrt( ( (NewObj->s.XX * NewObj->s.XX) &#; (NewObj->s.XY * NewObj->s.XY) &#; (NewObj->s.XZ * NewObj->s.XZ) &#; (NewObj->s.YX * NewObj->s.YX) &#; (NewObj->s.YY * NewObj->s.YY) &#; (NewObj->s.YZ * NewObj->s.YZ) &#; (NewObj->s.ZX * NewObj->s.ZX) &#; (NewObj->s.ZY * NewObj->s.ZY) &#; (NewObj->s.ZZ * NewObj->s.ZZ) ) / 3.0f ); if (rot3) { rot3->s.XX = NewObj->s.XX; rot3->s.XY = NewObj->s.XY; rot3->s.XZ = NewObj->s.XZ; rot3->s.YX = NewObj->s.YX; rot3->s.YY = NewObj->s.YY; rot3->s.YZ = NewObj->s.YZ; rot3->s.ZX = NewObj->s.ZX; rot3->s.ZY = NewObj->s.ZY; rot3->s.ZZ = NewObj->s.ZZ; n = 1.0f / FuncSqrt( (NewObj->s.XX * NewObj->s.XX) &#; (NewObj->s.XY * NewObj->s.XY) &#; (NewObj->s.XZ * NewObj->s.XZ) ); rot3->s.XX *= n; rot3->s.XY *= n; rot3->s.XZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.YX * NewObj->s.YX) &#; (NewObj->s.YY * NewObj->s.YY) &#; (NewObj->s.YZ * NewObj->s.YZ) ); rot3->s.YX *= n; rot3->s.YY *= n; rot3->s.YZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.ZX * NewObj->s.ZX) &#; (NewObj->s.ZY * NewObj->s.ZY) &#; (NewObj->s.ZZ * NewObj->s.ZZ) ); rot3->s.ZX *= n; rot3->s.ZY *= n; rot3->s.ZZ *= n; } if (rot4) { if (rot4 != NewObj) { Matrix4fSetRotationScaleFromMatrix4f(rot4, NewObj); } n = 1.0f / FuncSqrt( (NewObj->s.XX * NewObj->s.XX) &#; (NewObj->s.XY * NewObj->s.XY) &#; (NewObj->s.XZ * NewObj->s.XZ) ); rot4->s.XX *= n; rot4->s.XY *= n; rot4->s.XZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.YX * NewObj->s.YX) &#; (NewObj->s.YY * NewObj->s.YY) &#; (NewObj->s.YZ * NewObj->s.YZ) ); rot4->s.YX *= n; rot4->s.YY *= n; rot4->s.YZ *= n; n = 1.0f / FuncSqrt( (NewObj->s.ZX * NewObj->s.ZX) &#; (NewObj->s.ZY * NewObj->s.ZY) &#; (NewObj->s.ZZ * NewObj->s.ZZ) ); rot4->s.ZX *= n; rot4->s.ZY *= n; rot4->s.ZZ *= n; } return s;}//从3x3矩阵变为4x4的旋转矩阵inlinestatic void Matrix4fSetRotationScaleFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1){ assert(NewObj && m1); NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX; NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY; NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;}//4x4矩阵的与标量的乘积inlinestatic void Matrix4fMulRotationScale(Matrix4fT* NewObj, GLfloat scale){ assert(NewObj); NewObj->s.XX *= scale; NewObj->s.YX *= scale; NewObj->s.ZX *= scale; NewObj->s.XY *= scale; NewObj->s.YY *= scale; NewObj->s.ZY *= scale; NewObj->s.XZ *= scale; NewObj->s.YZ *= scale; NewObj->s.ZZ *= scale;}//设置旋转矩阵inlinestatic void Matrix4fSetRotationFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1){ GLfloat scale; assert(NewObj && m1); scale = Matrix4fSVD(NewObj, NULL, NULL); Matrix4fSetRotationScaleFromMatrix3f(NewObj, m1); Matrix4fMulRotationScale(NewObj, scale);}typedef class ArcBall_t{protected: //把二维点映射到三维点 inline void _mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const;public: //构造/析构函数 ArcBall_t(GLfloat NewWidth, GLfloat NewHeight); ~ArcBall_t() { }; //设置边界 inline void setBounds(GLfloat NewWidth, GLfloat NewHeight) { assert((NewWidth > 1.0f) && (NewHeight > 1.0f)); //设置长宽的调整因子 this->AdjustWidth = 1.0f / ((NewWidth - 1.0f) * 0.5f); this->AdjustHeight = 1.0f / ((NewHeight - 1.0f) * 0.5f); } //鼠标点击 void click(const Point2fT* NewPt); //鼠标拖动计算旋转 void drag(const Point2fT* NewPt, Quat4fT* NewRot); //更新鼠标状态 void upstate(); //void mousemove(WPARAM wParam,LPARAM lParam);protected: Vector3fT StVec; //保存鼠标点击的坐标 Vector3fT EnVec; //保存鼠标拖动的坐标 GLfloat AdjustWidth; //宽度的调整因子 GLfloat AdjustHeight; //长度的调整因子public: Matrix4fT Transform; //计算变换 Matrix3fT LastRot; //上一次的旋转 Matrix3fT ThisRot; //这次的旋转 float zoomRate; float lastZoomRate; bool isDragging; // 是否拖动 bool isRClicked; // 是否右击鼠标 bool isClicked; // 是否点击鼠标 bool isZooming; //是否正在缩放 Point2fT LastPt; Matrix4fT origTransform; Point2fT MousePt; // 当前的鼠标位置} ArcBallT;#endif

Cocos openGL编写自己的Shaders cocos2d-x3.5,lua环境下实现按钮变灰;代码调用:localprogram=cc.GLProgram:create(Shaders/Gray.vsh,Shaders/Gray.fsh)program:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION,cc.VERTEX_ATTRIB

OpenGL--选择和反馈 理论基础选择和反馈:整的来说就是鼠标点击,然后算出到底点击的是哪个物体。在选择和反馈模式下,绘制信息返回给应用程序而不是像在渲染模式

opengl penGl基本框架.1Opengl简介.2openGl的工作方式.2.1Opengl体系结构.2.2openGl流水线.2.3OpenGl状态机.3OpenGl操作步骤.4OpenGl组成.5OpenGl数据类型.6OpenGl函数

标签: 轨迹球怎么调出来

本文链接地址:https://www.jiuchutong.com/biancheng/369596.html 转载请保留说明!

上一篇:OpenGL编程逐步深入(十)索引绘制(简述opengl的编程步骤)

下一篇:Cocos openGL编写自己的Shaders(cocos lua教程)

  • 个税汇算清缴系统找不到扣缴义务人
  • 企业的税务风险研究怎么写
  • 房产税的计税基础包括契税吗
  • 土地增值税清算管理规程
  • 怎么做税种
  • 建筑公司租赁费会计分录
  • 小规模企业收入怎么做账
  • 实验用品包括实验仪器吗
  • 软件无形资产摊销年限是多久
  • 培训费发票开具的要求
  • 社保免征还需要申报吗
  • 分公司报增值税吗
  • 附加税是当月计算吗
  • 已付款收不到发票怎么办
  • 个人购买商业保险怎么抵扣个税
  • 购买的旧机械设备怎么办
  • 百度推广服务费一年多少钱
  • 劳务报酬申报个税后还需要开发票吗
  • 股东收取了公司的货款
  • 应交税费减免税额结转
  • 养老金余额退休能取吗
  • 行政会计账务处理
  • 合并报表汇兑损益怎么填
  • 租房提取的话可以全部提取吗
  • 金税盘问题
  • 税务局代增值税普通发票流程
  • 餐饮装修费用计入什么科目
  • 公户转账备注写错会查吗
  • 公司院内打井怎么处罚
  • 水电费发票可以开吗
  • 电梯维修公司发展前景
  • 客户退回货物会计分录
  • win10下载软件被阻止安装怎么办
  • 职工福利费扣除率是多少
  • 个人所得税租房和房贷只能二选一吗
  • 礼品应该计入会计分录
  • uefi系统安装win7gho
  • linux怎么创建主页文件
  • PHP:mcrypt_module_get_algo_block_size()的用法_Mcrypt函数
  • anaconda更改虚拟环境路径
  • 表单校验html5
  • 电子税务局已申报信息查询
  • php函数的定义和调用
  • 微信小程序的视频怎么下载
  • vue如何使用axios
  • 出口货物离岸价差异原因说明表在电子税务局的位置
  • 可供出售金融资产现在叫什么
  • 应收应付款会计分录
  • 普通发票开具红字发票后发票联怎么处理?
  • 农副食品发票
  • 退回上年度企业所得税
  • 员工工资占公司收入
  • 进项跟销项金额一样是否可行
  • 税收会计记账方法
  • mysql 表分区
  • mysql实现分页查询
  • mysql8.0免安装
  • u盘怎么装win7系统步骤
  • xp系统玩英雄联盟出现win32
  • 生产环境如何对linux进行合理分区
  • os x10.8.5
  • win10右键菜单不显示
  • Win10预览版更新弹窗如何关闭
  • win7系统打印机服务开启
  • js中attribute
  • 备份mbr引导
  • easyui表格
  • android动画种类
  • java script和java区别
  • javascript 作用
  • python gensim
  • 安卓模拟器测试
  • javascript概述
  • 如何打印高速公路电子发票
  • 建筑服务纳税人有哪些
  • 预征率是2%怎么计算
  • 运城取暖费网上怎么交
  • 国家税务总局关于新型墙体材料增值税政策的通知
  • 学校经费审批流程
  • 国税三所电话
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设