openGL
Posted kimsimple
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了openGL相关的知识,希望对你有一定的参考价值。
#include "iostream" #include <GL/glut.h> #include<cmath> #define PI acos(-1) using namespace std; struct MPOINT { GLdouble x, y; MPOINT(int x, int y) { this->x = x; this->y = y; } }; struct MPOINT *oldPoint, *curPoint; GLdouble a, b,angle;//输入为角度,计算时转化为弧度 int flag = 0; void Line_sin() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_LINES); { glVertex2f(-1.0f, 0.0f); glVertex2f(1.0f, 0.0f); // 以上两个点可以画x轴 glVertex2f(0.0f, -1.0f); glVertex2f(0.0f, 1.0f); // 以上两个点可以画y轴 } glEnd(); glBegin(GL_LINE_STRIP); { for (int i = 0; i < 1000; i++) { glVertex2f(i, 100*sin(i*1.0)); } } glEnd(); glFlush(); } void Show() { const GLfloat factor = 0.1f; GLfloat x; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINES); { glVertex2f(-1.0f, 0.0f); glVertex2f(1.0f, 0.0f); // 以上两个点可以画x轴 glVertex2f(0.0f, -1.0f); glVertex2f(0.0f, 1.0f); // 以上两个点可以画y轴 } glEnd(); glBegin(GL_POINTS); { for (x = -1.0f / factor; x < 1.0f / factor; x += 0.01f) { glVertex2f(x*factor, sin(x)*factor); } } glEnd(); glFlush(); } /* 函数用来画图 */ void display(void) { } //----------------------------------------------------------------------直线 //1.DDA void Line_DDA(struct MPOINT* p1, struct MPOINT* p2) { //glClear(GL_COLOR_BUFFER_BIT); //glColor3f(1.0f, 0.0f, 0.0f); //glPointSize(5);//设置点大小为5像素 GLdouble Xa = p1->x, Ya = p1->y, Xb = p2->x, Yb = p2->y; GLint dx = Xb - Xa, dy = Yb - Ya, steps, k; GLdouble xIncrement, yIncrement, x = Xa, y = Ya; if (abs(dx) > abs(dy)) steps = abs(dx); else steps = abs(dy); xIncrement = dx / (GLdouble)steps; yIncrement = dy / (GLdouble)steps; glBegin(GL_POINTS); { glVertex2d((GLdouble)round(x), (GLdouble)round(y)); for (k = 0; k < steps; k++) { x += xIncrement; y += yIncrement; glVertex2d((GLdouble)round(x), (GLdouble)round(y)); } } glEnd(); glFlush(); } //中点Bresenham算法(改进版) void Line_Bresenham(struct MPOINT* p1, struct MPOINT* p2) { GLint dx = p2->x - p1->x, dy = p2->y - p1->y,x = p1->x, y= p1->y,e=0; GLdouble k = (dy) / (GLdouble)dx; glBegin(GL_POINTS); { glVertex2i(round(x), round(y)); if (k >= 0) { if (p1->x > p2->x || ((p1->x == p2->x) &&(p1->y > p2->y))) { GLint tmp = p1->x; x = p2->x; p2->x = tmp; tmp = p1->y; y = p2->y; p2->y = tmp; dx *= -1; dy *= -1; } if (k <= 1) { e = -dx; while (x != p2->x && y != p2->y) { e += 2 * dy; if (e > 0) { if (x < p2->x || y< p2->y) { x++; y++; } else if (x > p2->x || y > p2->y) { x--; y--; } e -= 2 * dx; } else { if (x < p2->x) { x++; } else if(x > p2->x) { x--; } } glVertex2i(round(x), round(y)); } } else if (k > 1) { e = -dy; while (x != p2->x && y != p2->y) { e += 2 * dx; if (e > 0) { if (x < p2->x || y< p2->y) { x++; y++; } else if (x > p2->x || y > p2->y) { x--; y--; } e -= 2 * dy; } else { if (y < p2->y) { y++; } else if (y > p2->y) { y--; } } glVertex2i(round(x), round(y)); } } } else { if (k >= -1) { e = -dx; while (x != p2->x && y != p2->y) { e += abs(dy)*2; if (e > 0) { if (x > p2->x || y< p2->y) { x--; y++; } else if (x < p2->x || y > p2->y) { x++; y--; } e -= abs(dx)*2; } else { if (x < p2->x) { x++; } else if (x > p2->x) { x--; } } glVertex2i(round(x), round(y)); } } else { e = -dy; while (x != p2->x && y != p2->y) { e += 2 * abs(dx); if (e > 0) { if (x > p2->x || y< p2->y) { x--; y++; } else if (x < p2->x || y > p2->y) { x++; y--; } e -= 2 * abs(dy); } else { if (y < p2->y) { y++; } else if (y > p2->y) { y--; } } glVertex2i(round(x), round(y)); } } } } glEnd(); glFlush(); } //----------------------------------------------------------------------圆形 //极坐标法 for Ciecle void Circle_Polar(struct MPOINT *c, GLdouble R) { GLint n = 100; GLdouble x=c->x, y=c->y; glBegin(GL_POINTS); { for (int i = 0; i < n; i++) { x =c->x + R * cos(2 * PI *i/ n); y =c->y + R * sin(2 * PI *i/ n); glVertex2f(x,y); } } glEnd(); glFlush(); } //中点Bresenham for Circle //画点(x,y)和他的7个对称点 void Draw8(struct MPOINT *c,GLdouble x, GLdouble y) { GLdouble X = c->x, Y = c->y; glBegin(GL_POINTS); { glVertex2d(x +X,y + Y); glVertex2d(-x +X, y + Y); glVertex2d(x + X, -y + Y); glVertex2d(-x + X, -y + Y); glVertex2d(y + X, x + Y); glVertex2d(-y + X, x + Y); glVertex2d(y + X, -x + Y); glVertex2d(-y + X, -x + Y); } glEnd(); glFlush(); } void Circle_Bresenham(struct MPOINT *c,GLdouble R) { GLdouble d = 1 - R, x = 0, y = R; while (x <= y) { Draw8(c, x ,y); if (d <= 0) { d += 2 * x + 3; x++; } else { d += 2 * (x-y) + 5; x++; y--; } } } //DDA for Circle void Circle_DDA(struct MPOINT *c, GLdouble R) { GLdouble xc = c->x, yc = c->y, x = xc + R, y = yc, theta = 0, e = 1 / R; glBegin(GL_POINTS); { while (theta < 2 * PI) { glVertex2f(x, y); x = x - (y - yc)*e; y = y + (x - xc)*e; theta += e; } } glEnd(); glFlush(); } //----------------------------------------------------------------------椭圆 //某点绕某点旋转后的新坐标 void getNewPoint(struct MPOINT* c,GLdouble X, GLdouble Y,GLdouble& x,GLdouble& y) { x = (X - c->x)*cos(angle*PI / 180) - (Y - c->y)*sin(angle*PI / 180) + c->x; y = (X - c->x)*sin(angle*PI / 180) + (Y - c->y)*cos(angle*PI / 180) + c->y; } //画点(x,y)和它的3个对称点 void Draw4(struct MPOINT* c,GLdouble x, GLdouble y) { GLdouble X = c->x, Y = c->y,xn,yn; glBegin(GL_POINTS); { /* glVertex2f(x+X,y+Y); glVertex2f(-x+X, y+Y); glVertex2f(x+X, -y+Y); glVertex2f(-x+X, -y+Y); */ getNewPoint(c,x + X, y + Y, xn, yn); glVertex2f(xn, yn); getNewPoint(c, -x + X, y + Y, xn, yn); glVertex2f(xn, yn); getNewPoint(c, x + X, -y + Y, xn, yn); glVertex2f(xn, yn); getNewPoint(c, -x + X, -y + Y, xn, yn); glVertex2f(xn, yn); } glEnd(); glFlush(); } //中点Bresenham算法 for Oval void Oval_Bresenham(struct MPOINT* c) { if (a <= 0 || b <= 0) { a = 50, b = 10; } GLdouble d = b * b + a * a*(0.25 - b), x = 0, y = b; while (b*b*(x + 1) < a*a*(y - 0.5)) { Draw4(c,x, y); if (d <= 0) { d += b * b*(2 * x + 3); x++; } else { d += b * b*(2 * x + 3) + a * a*(-2 * y + 2); x++; y--; } } d = b * b*(x + 0.5)*(x + 0.5) + a * a*(y - 1)*(y - 1) - a * a * b * b; while (y >= 0) { Draw4(c,x,y); if (d <= 0) { d += b*b*(2*x + 2) + a*a*(-2*y + 3); x++; y--; } else { d += a*a*(-2*y + 3), y--; } } } //==========================================================================事件======== /*鼠标点击事件 */ void mouseClick(int btn, int state, int x, int y) { if (btn == 0 && state == 1) { if (oldPoint == NULL) { oldPoint = new MPOINT(x, y); } else { curPoint = new MPOINT(x, y); } } if (btn == 2 && state == 1) { flag += 1; if (oldPoint == NULL) { oldPoint = new MPOINT(x, y); } else { curPoint = new MPOINT(x, y); } } if (oldPoint != NULL && curPoint != NULL) { if (flag == 0) { Line_DDA(oldPoint, curPoint); // DDA for line //Line_Bresenham(oldPoint, curPoint);// Bresenham for Line } else if (flag == 1) { GLdouble R = sqrt(pow(curPoint->x - oldPoint->x, 2) + pow(curPoint->y - oldPoint->y, 2)); //Circle_DDA(oldPoint, R); // DDA for Circle //Circle_Polar(oldPoint,R); // Polar for Circle Circle_Bresenham(oldPoint, R); // Bresenham for Circle } else if (flag == 2) { Oval_Bresenham(oldPoint); // Bresenham for Oval } flag = 0; free(oldPoint); free(curPoint); oldPoint = NULL; curPoint = NULL; } //btn 0 left 2 right state 0 按下 1松开 (x,y)代表坐标 /* printf("点击了鼠标,btn:%d,state:%d,x:%d,y:%d\n", btn, state, x, y); if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { printf("按下了左边按钮\n"); } if (btn == GLUT_LEFT_BUTTON && state == GLUT_UP) { printf("松开了左边按钮\n"); } if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { printf("按下了右边按钮\n"); } if (btn == GLUT_RIGHT_BUTTON && state == GLUT_UP) { printf("松开了右边按钮\n"); } */ } //键盘事件 void SpecialKey(GLint c, GLint x, GLint y) { if (c == GLUT_KEY_UP) { glClear(GL_COLOR_BUFFER_BIT); glFlush(); //exit(0); } if (c == GLUT_KEY_DOWN) { cout << "Please input the long axis, shaort axis and the rotation angle of Oval\n"; cin >> a >> b >> angle; } if (c == 27) { exit(0); } } /* 鼠标移动事件 */ void mouseMove(int x, int y) { printf("移动鼠标中,x:%d,y%d\n", x, y); } //============================================== MAIN ============================= int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH); glutInitWindowPosition(100, 100); glutInitWindowSize(400, 400); glutCreateWindow("OpenGL"); //观察参数: //gluOrtho2D(-200.0, 200.0, -200.0, 200.0); gluOrtho2D(0, 400.0, 400.0, 0); glutDisplayFunc(display); /*鼠标点击事件,鼠标点击或者松开时调用 */ glutMouseFunc(mouseClick); /*鼠标移动事件,鼠标按下并移动时调用 */ glutMotionFunc(mouseMove); /*键盘事件,键盘按下时调用 */ glutSpecialFunc(&SpecialKey); glutMainLoop(); return 0; } /* readme: 连续两次左键:绘制直线 连续两次右键:绘制圆形 一左一右/一右一左:绘制椭圆,输入长轴a,短轴b,偏转角度q */
以上是关于openGL的主要内容,如果未能解决你的问题,请参考以下文章
带有顶点/片段着色器的光。使用不同的变量。 (openGL)