OpenGL关于二维变换的例子

#include<GL/glut.h>
#include<cstdlib>
#include<cmath>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
/*初始化窗口大小*/
GLsizei winWidth = 600, winHeight = 600; /*int*/


/*设置世界坐标系*/
GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0;


class wcPt2D
{
public:
GLfloat x, y;


};


typedef GLfloat Matrix3x3[3][3];


Matrix3x3 matComposite; /*float 3*3 matrix*/
const GLdouble pi = 3.14159l;


void init(void)
{
/*设置显示窗口颜色为白色*/
glClearColor(1.0, 1.0, 1.0, 0.0);
}


/*构造3*3矩阵*/
void matrix3x3SetIdentity(Matrix3x3 matIdent3x3)
{
GLint row, col;
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
matIdent3x3[row][col] = (row == col);/*置为单位矩阵*/
}
/*m1矩阵左乘m2,结果放在m2中*/
void matrix3x3PreMultiply(Matrix3x3 m1, Matrix3x3 m2)
{
GLint row, col;
Matrix3x3 matTemp;
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
matTemp[row][col] = m1[row][0] * m2[0][col] + m1[row][1] * m2[1][col] + m1[row][2] * m2[2][col];/*matTemp[row][col] = m1[row][col] * m2[col][row];*/
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
m2[row][col] = matTemp[row][col];
}


void translate2D(GLfloat tx, GLfloat ty)
{
Matrix3x3 matTransl;
/*初始化平移矩阵*/
matrix3x3SetIdentity(matTransl);//matTransl置为单位矩阵


matTransl[0][2] = tx;
matTransl[1][2] = ty;/*1 0 0
 0 1 100
 0 0 1 */


/*连接matTransl复合矩阵*/
matrix3x3PreMultiply(matTransl, matComposite);/*
0 -0.550
0.5 0225
0 01*/
}


void rotate2D(wcPt2D pivotPt, GLfloat theta) /*旋转矩阵*/
{
Matrix3x3 matRot;
/*初始化旋转矩阵*/
matrix3x3SetIdentity(matRot);
matRot[0][0] = cos(theta);/*theta=pi/2*/
matRot[0][1] = -sin(theta);
matRot[0][2] = pivotPt.x*(1 - cos(theta)) + pivotPt.y*sin(theta);

matRot[1][0] = sin(theta);
matRot[1][1] = cos(theta);
matRot[1][2] = pivotPt.y*(1 - cos(theta)) + pivotPt.x*sin(theta);
/*
0 -175
1 075
0 01*/


/*连接matRot复合矩阵*/
matrix3x3PreMultiply(matRot, matComposite);/*
0 -0.550
0.5  0125
0  01*/
}


void scale2D(GLfloat sx, GLfloat sy, wcPt2D fixedPt)
{
Matrix3x3 matScale;
/*初始化扩展矩阵*/
matrix3x3SetIdentity(matScale);/*
1 00
0 10
0 01*/


matScale[0][0] = sx;
matScale[0][2] = (1 - sx)*fixedPt.x;
matScale[1][1] = sy;
matScale[1][2] = (1 - sy)*fixedPt.y;/*
0.5 00.5*100
0  0.5  0.5*50
0   0     1*/
/*连接matScale复合矩阵*/
matrix3x3PreMultiply(matScale, matComposite);/*
0.5 050
0 0.525
0 01
*/
}


/*使用复合矩阵,计算坐标转换*/
void transformVerts2D(GLint nVerts, wcPt2D *verts)
{
/*wcPt2D verts[3] = { { 50.0, 25.0 }, { 150.0, 25.0 }, { 100.0, 100.0 } };*/
GLint k;
GLfloat temp;
for (k = 0; k < nVerts; k++)
{
temp = matComposite[0][0] * verts[k].x + matComposite[0][1] * verts[k].y + matComposite[0][2];
verts[k].y = matComposite[1][0] * verts[k].x + matComposite[1][1] * verts[k].y + matComposite[1][2];
verts[k].x = temp;


}
}
void triangle(wcPt2D *verts)
{
GLint k;
glBegin(GL_TRIANGLES);
for (k = 0; k < 3; k++)
glVertex2f(verts[k].x, verts[k].y);
glEnd();
}


void displayFcn(void)
{
/*初始化三角形位置*/
GLint nVerts = 3;/*三角形*/
wcPt2D verts[3] = { { 50.0, 25.0 }, { 150.0, 25.0 }, { 100.0, 100.0 } };/*每个角的坐标*/
/*计算三角形质心位置*/
wcPt2D centroidPt;


GLint k, xSum = 0, ySum = 0;
/*把每个点对应的坐标相加求和除以顶点个数求质心的坐标*/
for (k = 0; k < nVerts; k++)
{
xSum += verts[k].x;/*300*/
ySum += verts[k].y;/*150*/
}
centroidPt.x = GLfloat(xSum) / GLfloat(nVerts);/*100*/
centroidPt.y = GLfloat(ySum) / GLfloat(nVerts);/*50*/


/*设置几何转换参数*/
wcPt2D pivPt, fixedPt;
pivPt = centroidPt;/*100,50*/
fixedPt = centroidPt;/*100,50*/


GLfloat tx = 0.0, ty = 100.0; /*x方向不动,向y正方向平移100个单位*/
GLfloat sx = 0.5, sy = 0.5; /*缩放比例*/
GLdouble theta = pi / 2.0; /*逆时针选装90度*/


glClear(GL_COLOR_BUFFER_BIT);/*清空显示窗口*/


glColor3f(0.0, 0.0, 1.0);/*设置初始化填充颜色*/
triangle(verts);/*蓝色三角*/


/*初始化复合矩阵*/
matrix3x3SetIdentity(matComposite);/*matComposite
1 00
0 10
0 01*/
/*构造复合矩阵*/
scale2D(sx, sy, fixedPt);/*第一次缩放转换*/
rotate2D(pivPt, theta);/*第二次旋转转换*/
translate2D(tx, ty);/*最后一次平移转换*/


/*应用复合矩阵三角定点*/
transformVerts2D(nVerts, verts);


glColor3f(1.0, 0.0, 0.0);
triangle(verts);


glFlush();
}


void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glViewport(0, 0, 300, 300);
gluOrtho2D(xwcMin, newWidth, ywcMin, newHeight);


glClear(GL_COLOR_BUFFER_BIT);
}


void main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(200, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("Geometric Transformation Sequence");


init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);


glutMainLoop();
}

 

//仰天大笑出门去,我辈岂是蓬蒿人

结果

 

 



gluOrtho2D(-1.0, 1.5, -1.5, 1.5*(GLfloat)h / (GLfloat)w);
glutInitWindowSize(400, 400);//窗口大小跟坐标轴大小不是同一个单位,就像在纸上画不同大小坐标轴一样

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程解决的问题: 作为游戏行业或者图形学从业者,你是否面临以下问题: 到底openGL底层如何实现的? 到底矩阵操作变换是怎么做到的? 到底光栅化的算法以及原理是什么? 到底如何才能从3D世界投射到2D屏幕呢? 图形学有这么多的矩阵操作,到底如何推导如何应用呢? 学完这门课程,你应该就可以从底层了解一个初级的openGL图形接口如何实现,图形学最底层的封装到底面临哪些挑战;跟随我们一行一行写完代码,你就会得到一个迷你版本的openGL图形库,你可以深度体会图形从模型变换,观察矩阵变换,投影矩阵变换一直到光栅化纹理操作的全套模拟流程。 课程介绍: 本课程将带领学员不使用任何图形库,实现从0到1的图形学接口封装以及算法讲解,并且带领大家手敲代码,一行一行进行实现。 涵盖了(环境搭建,绘制点,Bresenham算法绘制完美直线,三角形拆分绘制算法,颜色插值算法,图片操作,图片二次插值放缩算法,纹理系统接口搭建及封装,矩阵操作理论以及实践,openGL类似接口封装,3D世界的图形学理论及接口封装等) 最终将带领大家通过C++实现一个3D世界的图形接口,方便所有人入门图形学,进行接下来的openGL接口以及GPU编程的学习   本课程为系列课程的第一步入门,且带领所有人进行实现,更加实用,可以让大家打牢图形学的基础知识及编程技能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值