OpenGL绘制图形
# OpenGL绘制图形
# 坐标系定义
屏幕空间坐标系,以屏幕中心为原点,左下角为(-1,-1),右上角为(1,1),符合右手坐标系。在OpenGL中规定,x,y轴的取值范围均为[-1,1]。
当屏幕不是正方形的时候,画圆可能被压成椭圆,这是需要通过宽高比进行调整比例。
# 绘制图形
在默认情况下,OpenGL会默认把世界空间坐标当作屏幕空间坐标。
使用glBegin(GL_xxx)
用来指定绘图模式,用glVertex3f
指定在该种模式下的一些顶点坐标,最后调用glEnd()
结束绘制。
glBegin(GL_POINTS)
// 在原点处画一个点
glVertex3f(0.0f, 0.0f, 0.0f);
glEnd()
绘图模式包括:
- 点:GL_POINTS
- 线;GL_LINES
- 面:GL_TRIANGLES
# 调整点的大小
利用glPointSize()
设置点的像素大小
使用glEnable()
可以启用一些特性,例如GL_POINT_SMOOTH
让点的形状变为圆形,使用GL_BLEND
开启抗锯齿等。
以上设置可以放在main函数中,一次设置,永久生效,知道再次设置或取消。
# 调整点的颜色
使用glColor3f
指定颜色,格式是按照(R, G, B)三个0到1之间的浮点数指定。如下是一个示例:
glBegin(GL_POINTS);
glColor3f(0.1137f, 0.2980f, 0.3137f);
glVertex3f(0.0f, 0.0f, 0.0f);
glColor3f(0.8275f, 0.6431f, 0.5333f);
glVertex3f(0.0f, 0.4f, 0.0f);
glColor3f(0.7412f, 0.6824f, 0.6784f);
glVertex3f(-0.3f, -0.2f, 0.0f);
glColor3f(0.9412f, 0.6549f, 0.1804f);
glVertex3f(0.3f, -0.2f, 0.0f);
glEnd();
其效果如图:
![](https://cdn.jsdelivr.net/gh/Sirius0v0/image_store/blog/20230826001324.png)
如果绘制的是三角形,那么如果指定了颜色,则会呈现渐变的效果:
glBegin(GL_TRIANGLES);
glColor3f(0.1137f, 0.2980f, 0.3137f);
glVertex3f(0.0f, 0.6f, 0.0f);
glColor3f(0.7412f, 0.6824f, 0.6784f);
glVertex3f(-0.3f, 0.0f, 0.0f);
glColor3f(0.9412f, 0.6549f, 0.1804f);
glVertex3f(0.3f, 0.0f, 0.0f);
glColor3f(0.8275f, 0.6431f, 0.5333f);
glVertex3f(-0.6f, -0.6f, 0.0f);
glVertex3f(0.6f, -0.6f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();
![](https://cdn.jsdelivr.net/gh/Sirius0v0/image_store/blog/20230826130039.png)
# 画点好玩的
- 加载中...
static float current = 0.0f;
glColor3f(0.0f, 0.5f, 0.4f);
glBegin(GL_POINTS);
constexpr float r = 0.8f;
constexpr int n = 15;
constexpr float v = 0.05f;
constexpr float pi = 3.1415926535897932f;
for (int i = 0; i < n; ++i)
{
if (std::abs(i-static_cast<int>(current))<1e-7) continue;
float angle = i / static_cast<float>(n) * pi * 2.0f;
glVertex3f(r * std::sin(angle) / WdH, r * std::cos(angle), 0.0f);
}
current += v;
if (current > n) current = 0;
glEnd();
![](https://cdn.jsdelivr.net/gh/Sirius0v0/image_store/blog/opengl_loading.gif)
- OpenCV
void paint(float angle, float angle_next, float angle_offset, float x, float y)
{
angle += angle_offset;
angle_next += angle_offset;
constexpr float R = 0.4f;
constexpr float r = R / 3.0f;
glVertex3f((x+r * std::cos(angle)) / WdH, y+r * std::sin(angle), 0.0f);
glVertex3f((x+R * std::cos(angle)) / WdH, y+R * std::sin(angle), 0.0f);
glVertex3f((x+R * std::cos(angle_next)) / WdH, y+R * std::sin(angle_next), 0.0f);
glVertex3f((x+r * std::cos(angle)) / WdH, y+r * std::sin(angle), 0.0f);
glVertex3f((x+r * std::cos(angle_next)) / WdH, y+r * std::sin(angle_next), 0.0f);
glVertex3f((x+R * std::cos(angle_next)) / WdH, y+R * std::sin(angle_next), 0.0f);
}
void render()
{
glBegin(GL_TRIANGLES);
constexpr int n = 200;
constexpr float pi = 3.1415926535897932f;
float angle_offset = 0;
float zoom = 2.6f;
for (int i = 0; i < n; ++i)
{
float angle = i / static_cast<float>(n) * (2 * pi * 5.0f / 6.0f);
float angle_next = (i + 1) / static_cast<float>(n) * (2 * pi * 5.0f / 6.0f);
angle_offset = -pi / 3.0f;
glColor3f(1.0f, 0.0f, 0.0f);
paint(angle, angle_next, angle_offset, 0.0f, 0.2f*zoom);
angle_offset = pi / 3.0f;
glColor3f(0.0f, 1.0f, 0.0f);
paint(angle, angle_next, angle_offset, -0.1732f*zoom, -0.1f*zoom);
angle_offset = pi / 3.0f * 2.0f;
glColor3f(0.0f, 0.0f, 1.0f);
paint(angle, angle_next, angle_offset, 0.1732f*zoom, -0.1f*zoom);
}
glEnd();
}
![](https://cdn.jsdelivr.net/gh/Sirius0v0/image_store/blog/20230826153326.png)
- 太极图
glBegin(GL_TRIANGLES);
constexpr int n = 100;
constexpr float R = 0.8f;
constexpr float pi = 3.1415926535897932f;
for(int i = 0; i < n; ++i) {
float angle = i / static_cast<float>(n) * pi;
float angle_next = (i+1) / static_cast<float>(n) * pi;
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(R*std::sin(angle)/WdH, R*std::cos(angle), 0.0f);
glVertex3f(R*std::sin(angle_next)/WdH, R*std::cos(angle_next), 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(R*std::sin(-angle)/WdH, R*std::cos(-angle), 0.0f);
glVertex3f(R*std::sin(-angle_next)/WdH, R*std::cos(-angle_next), 0.0f);
}
for(int i = 0; i < n; ++i) {
float angle = i / static_cast<float>(n) * pi;
float angle_next = (i+1) / static_cast<float>(n) * pi;
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, R/2.0f, 0.0f);
glVertex3f(R/2*std::sin(angle)/WdH, R/2.0f+R/2*std::cos(angle), 0.0f);
glVertex3f(R/2*std::sin(angle_next)/WdH, R/2.0f+R/2*std::cos(angle_next), 0.0f);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, -R/2.0f, 0.0f);
glVertex3f(R/2*std::sin(-angle)/WdH, -R/2.0f+R/2*std::cos(-angle), 0.0f);
glVertex3f(R/2*std::sin(-angle_next)/WdH, -R/2.0f+R/2*std::cos(-angle_next), 0.0f);
}
for(int i = 0; i < 2*n; ++i) {
float angle = i / static_cast<float>(2*n) * 2 * pi;
float angle_next = (i+1) / static_cast<float>(2*n) * 2 * pi;
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, R/2.0f, 0.0f);
glVertex3f(R/6*std::sin(angle)/WdH, R/2.0f+R/6*std::cos(angle), 0.0f);
glVertex3f(R/6*std::sin(angle_next)/WdH, R/2.0f+R/6*std::cos(angle_next), 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, -R/2.0f, 0.0f);
glVertex3f(R/6*std::sin(-angle)/WdH, -R/2.0f+R/6*std::cos(-angle), 0.0f);
glVertex3f(R/6*std::sin(-angle_next)/WdH, -R/2.0f+R/6*std::cos(-angle_next), 0.0f);
}
glEnd();
![](https://cdn.jsdelivr.net/gh/Sirius0v0/image_store/blog/20230826141331.png)
编辑 (opens new window)
上次更新: 2023/08/27, 00:31:08