OpenGL的学习之路-3

前面1、2介绍的都是glut编程

下面就进行opengl正是部分啦。

1.绘制点

cpp 复制代码
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>


void myMainWinDraw();

int main(int argc,char** argv) {
    glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(0, 0);

	glutCreateWindow("Hello");

	glutDisplayFunc(myMainWinDraw);

	glutMainLoop();
	return 0;
}

void myMainWinDraw(){
    glClearColor(0.0,0.0,0.0,0.0);//设置清除色
    glClear(GL_COLOR_BUFFER_BIT); //清除颜色缓冲区

    float a[2];
    glGetFloatv(GL_POINT_SIZE_RANGE,a);
    std::cout<<a[0]<<"---"<<a[1]<<"\n";   //输出的是,点大小的范围(不过没有这么严格)

    glPointSize(10);   //设置点的大小

    glBegin(GL_POINTS);

    #if 0
    (0.5f,0.4f);
    (-0.5f,0.4f,0.0f);
    (0.0f,-0.4f,0.0f);
    #else
    glColor3f(1.0f,0.0f,0.0f);  //为点设置颜色
    glVertex3f(0.5f,0.4f,0.0f); //该语句可绘制

    glColor3f(0.0f,0.0f,1.0f);
    glVertex3f(-0.5f,0.4f,0.0f);

    glColor3f(0.0f,1.0f,0.0f);
    glVertex3f(0.0f,-0.4f,0.0f);
    #endif // 0
    
    glEnd();

    glFlush();
}

这里留下小思考题:

掷骰子是随机事件,现在平面上有三个点A、B、C,还有一个点P,位置可随机。令点A代表骰子的点数为1、4,点B代表骰子的点数为2、5,点C代表骰子的点数为3、6。现在开始扔,如果扔的点数为1或者4,那么取AP的中点作为新的P;如果扔到2或者5,则取BP的中点作为新的P;如果扔到的点数为3,6,则同理取CP的中点作为新的P。同时,要把每次取得的新的P绘制出来,并保持与相应的A或B或C同色。前面一定次数(如前20次),我们先不画点(还未进入稳态),后面再开始绘制。看看最终得到的图形是什么样子。

结果很奇妙!

明明是随机的,却呈现了规律性。赞叹数学、赞叹科学?是的,但我也想赞叹让我知道这个的我的老师。

2.绘制线

cpp 复制代码
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

void myMainWinDraw();

int main(int argc,char** argv) {
    glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(0, 0);

	glutCreateWindow("Hello");

	glutDisplayFunc(myMainWinDraw);

	glutMainLoop();
	return 0;
}

void myMainWinDraw(){
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glLineWidth(2);

    glBegin(GL_LINES);

#if 0
    glVertex3f(0.5f,0.0f,0.0f);
    glVertex3f(0.5f,0.4f,0.0f);
    glVertex3f(0.0f,0.4f,0.0f);
    glVertex3f(0.0f,-0.4f,0.0f);
#else
    glColor3f(1.0f,0.0f,0.0f);
    glVertex3f(0.5f,0.0f,0.0f);

    glColor3f(0.0f,1.0f,0.0f);
    glVertex3f(0.5f,0.4f,0.0f);

    glColor3f(1.0f,0.0f,0.0f);
    glVertex3f(0.0f,0.4f,0.0f);

    glColor3f(0.0f,0.0f,1.0f);
    glVertex3f(0.0f,-0.4f,0.0f);

#endif

    glEnd();

    glFlush();

}

两点连成一条直线。点和点之间是配对的,如果给的点的个数是奇数,那么最后一个点没有找到和他配对的点,会不起作用。

关于颜色:

默认状态,是两边点颜色的线性插值,结果如下:

如果不想这样,就需要 glShadeModel(GL_FLAT) 变成:

glShadeModel(GL_SMOOTH) 和 glShadeModel(GL_FLAT) !!

联系:绘制环

glBegin(GL_LINES_LOOP) :给出的两个相邻的点首尾相连,最后一个点和第一个点相连,构成环。两种颜色模式下:

3.绘制三角形

cpp 复制代码
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

void myMainWinDraw();

int main(int argc,char** argv) {
    glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(0, 0);

	glutCreateWindow("Hello");

	glutDisplayFunc(myMainWinDraw);

	glutMainLoop();
	return 0;
}

void myMainWinDraw(){
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    //glShadeModel(GL_FLAT); //GL_SMOOTH

    glBegin(GL_TRIANGLES);

#if 0
    glVertex3f(0.5f,0.0f,0.0f);
    glVertex3f(0.5f,0.4f,0.0f);
    glVertex3f(0.0f,0.4f,0.0f);

    glVertex3f(0.0f,-0.4f,0.0f);
    glVertex3f(0.3f,-0.4f,0.0f);
    glVertex3f(0.0f,-0.2f,0.0f);
#else
    glColor3f(1.0f,0.0f,0.0f);
    glVertex3f(0.5f,0.0f,0.0f);

    glColor3f(0.0f,1.0f,0.0f);
    glVertex3f(0.5f,0.4f,0.0f);

    glColor3f(1.0f,0.0f,0.0f);
    glVertex3f(0.0f,0.4f,0.0f);

    glColor3f(0.0f,0.0f,1.0f);
    glVertex3f(0.0f,-0.4f,0.0f);

    glColor3f(1.0f,0.0f,1.0f);
    glVertex3f(0.3f,-0.4f,0.0f);

    glColor3f(0.0f,1.0f,1.0f);
    glVertex3f(0.0f,-0.2f,0.0f);

#endif

    glEnd();

    glFlush();

}

三个点一组,绘制一个三角形。

推广:

(后面几个平时用不太到)

4.绘制的线型

cpp 复制代码
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

void myMainWinDraw();

int main(int argc,char** argv)
{
    glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(0, 0);

	glutCreateWindow("Hello");

	glutDisplayFunc(myMainWinDraw);

	glutMainLoop();
	return 0;
}

void myMainWinDraw(){
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glLineWidth(2);
    glEnable(GL_LINE_STIPPLE);

    glLineStipple(1,0xF0F0);  //第一个参数是重复度、第二个参数代表线型
    glBegin(GL_LINES);
    glVertex3f(0.5f, 0.4f ,0.0f);
    glVertex3f(-0.5f, 0.4f ,0.0f);
    glEnd();

    glLineWidth(10);
    glLineStipple(5,0xF0F0);
    glColor3f(1.0f,0.0f,0.0f);
    glBegin(GL_LINES);
    glVertex3f(0.5f, 0.0f, 0.0f);
    glVertex3f(-0.5f, 0.0f,0.0f);
    glEnd();

    glLineWidth(20);
    glLineStipple(3,0x7555);
    glColor3f(1.0f,1.0f,0.0f);
    glBegin(GL_LINES);
    glVertex3f(0.5f, -0.4f, 0.0f);
    glVertex3f(-0.5f, -0.8f,0.0f);
    glEnd();

    glLineWidth(5);
    glBegin(GL_LINE_LOOP);
    glVertex3f(-0.8f,  0.8f, 0.0f);
    glVertex3f(-0.8f, -0.8f, 0.0f);
    glVertex3f( 0.8f, -0.8f, 0.0f);
    glVertex3f( 0.8f,  0.8f, 0.0f);
    glEnd();

    glFlush();

}

新的知识点:

  1. glEnable(GL_LINE_STIPPLE) :将开关打开

  2. glLineStipple(1,0xF0F0):第一个参数是重复度,第二个参数是线型。这里是,1111000011110000。如果将第一个参数改为2,那么将变成1111111100000000...这个样子。

绘制结果:

5.多边形绘制的模式(填充/线框)

cpp 复制代码
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

void myMainWinDraw();

int main(int argc,char** argv)
{
    glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(0, 0);

	glutCreateWindow("Hello");

	glutDisplayFunc(myMainWinDraw);

	glutMainLoop();
	return 0;
}

void myMainWinDraw(){
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glDisable(GL_LIGHTING);

    glPolygonMode(GL_FRONT,GL_FILL);
    glPolygonMode(GL_BACK,GL_LINE);
    glBegin(GL_TRIANGLES);
    glVertex2f(-1.0f, 0.0f);
    glVertex2f( 0.0f, 0.0f);
    glVertex2f( 0.0f, 1.0f);
    glEnd();

    glPolygonMode(GL_FRONT,GL_LINE);
    glBegin(GL_TRIANGLES);
    glVertex2f( 1.0f, 0.0f);
    glVertex2f( 0.0f, 1.0f);
    glVertex2f( 0.0f, 1.0f);
    glEnd();


    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    glBegin(GL_TRIANGLES);
    glVertex2f(  0.0f, 0.0f);
    glVertex2f( -1.0f, 0.0f);
    glVertex2f(  0.0f,-1.0f);
    glEnd();

    glFrontFace(GL_CW);
    glPolygonMode(GL_BACK,GL_FILL);
    glPolygonMode(GL_FRONT,GL_LINE);
    glBegin(GL_TRIANGLES);
    glVertex2f(  0.0f, 0.0f);
    glVertex2f(  0.0f,-1.0f);
    glVertex2f(  1.0f, 0.0f);
    glEnd();

    glFlush();
}

新的知识点:

  1. glPolygonMode(GL_FRONT,GL_FILL):设置正面或者背面的填充方式为GL_FILL或者GL_LINE模式。

  2. glFrontFace(GL_CW):初始状态将CCW方向(点的顺序)视为正面,该语句将CW方向转为正面。

6.多边形填充的效果

填充图形的定义:

下面就是glBegin()和glEnd() 了

相关推荐
西岸行者9 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意9 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码9 天前
嵌入式学习路线
学习
毛小茛9 天前
计算机系统概论——校验码
学习
babe小鑫9 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms9 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下9 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。9 天前
2026.2.25监控学习
学习
im_AMBER9 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J9 天前
从“Hello World“ 开始 C++
c语言·c++·学习