理解视口viewport函数
使用opengl实现如下图所示的二维螺旋线,但只能有一个drawSpiralLine的函数(使用视口):
原理
使用glViewport
设置视口,即图形在窗口的什么位置显示。
代码
/**
* @Date: 2017.06.08
*/
#include <GL/glut.h>
#include <math.h>
void init(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 1000.0, 0.0, 900.0);
}
// 画螺旋线。
void drawSpriralLine() {
GLfloat pi2 = 3.1415936 * 2;
GLfloat one = 1.0;
GLfloat zero = 0.0;
GLfloat r = 450;
GLfloat x = 500.0;
GLfloat y = 450.0;
GLfloat c = 0.08;
glBegin(GL_POINTS);
for (GLfloat j = 0; j < pi2 * 10; j += 0.01) {
r = r < zero ? zero : r;
glVertex2f(x + r * cos(j) + one, y + r * sin(j) + one);
glVertex2f(x + r * cos(j) + one, y + r * sin(j) - one);
glVertex2f(x + r * cos(j) - one, y + r * sin(j) + one);
glVertex2f(x + r * cos(j) - one, y + r * sin(j) - one);
glVertex2f(x + r * cos(j), y + r * sin(j));
r -= c;
}
glEnd();
}
// 通过修改视口,在同一个显示窗口中,画出四个螺旋圈。
// 视口指定在输出设备上的什么位置进行观察。
void simulate(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glViewport(500, 450, 500, 450); // 右上
drawSpriralLine();
glViewport(0, 0, 500, 450); // 左下
drawSpriralLine();
glViewport(0, 450, 500, 450); // 左上
drawSpriralLine();
glViewport(500, 0, 500, 450); // 右下
drawSpriralLine();
glFlush();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(1000, 900);
glutCreateWindow("spiral line OpenGL Program");
init();
glutDisplayFunc(simulate);
glutMainLoop();
return 0;
}
glutReshapeFunc函数
在窗口高宽的时候会被调用,包括第一次创建窗口的时候。调用此函数类似于像openg注册了一个函数。
移动窗口,窗口也会跟着变化。
/**
* @Date: 2017.06.08
*/
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
void init(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 1000.0, 0.0, 900.0);
}
// 画螺旋线。
void drawSpriralLine() {
GLfloat pi2 = 3.1415936 * 2;
GLfloat one = 1.0;
GLfloat zero = 0.0;
GLfloat r = 450;
GLfloat x = 500.0;
GLfloat y = 450.0;
GLfloat c = 0.08;
glBegin(GL_POINTS);
for (GLfloat j = pi2 * 10; j >= 0; j -= 0.01) {
r = r < zero ? zero : r;
glVertex2f(x + r * cos(j) + one, y + r * sin(j) + one);
glVertex2f(x + r * cos(j) + one, y + r * sin(j) - one);
glVertex2f(x + r * cos(j) - one, y + r * sin(j) + one);
glVertex2f(x + r * cos(j) - one, y + r * sin(j) - one);
glVertex2f(x + r * cos(j), y + r * sin(j));
r -= c;
}
glEnd();
}
// 通过修改视口,在同一个显示窗口中,画出四个螺旋圈。
// 视口指定在输出设备上的什么位置进行观察。
void simulate(void) {
}
void reshapFunc(int w, int h) {
printf("reshapeFunc invoked %lld \n", time((time_t*)NULL));
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glViewport(0, 0, w / 2, h / 2); //
drawSpriralLine();
glViewport(0, h / 2, w / 2, h / 2); //
drawSpriralLine();
glViewport(w / 2, 0, w / 2, h / 2); //
drawSpriralLine();
glViewport(w / 2, h / 2, w / 2, h / 2); //
drawSpriralLine();
glFlush();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(1000, 900);
glutCreateWindow("spiral line OpenGL Program");
init();
glutDisplayFunc(simulate);
glutReshapeFunc(reshapFunc);
glutMainLoop();
return 0;
}
githup链接:
https://github.com/lifeSo/graphicsDemo/blob/master/01.get start/03.glviewport.c
,
https://github.com/lifeSo/graphicsDemo/blob/master/01.get start/04.glutReshapeFunc.c