OpenGL 在做渐变时跳过一个顶点
OpenGL skips a vertex when doing gradient
当我这样做时:
void drawTest()
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glShadeModel(GL_SMOOTH);
glBegin(GL_POLYGON);
glColor3d(1, 0, 0); // red
glVertex2d(-200, 100); // top-left
glColor3d(0, 1, 0); // green
glVertex2d(-200, 0); // middle-left
glColor3d(0, 0, 1); // blue
glVertex2d(-200, -100); // bottom-left
glColor3d(0, 0, 1); // blue
glVertex2d(200, -100); // bottom-right
glColor3d(0, 1, 0); // green
glVertex2d(200, 0); // middle-right
glColor3d(1, 0, 0); // red
glVertex2d(200, 100); // top-right
glEnd();
}
我明白了:
但是当我在第三行切换到glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
时,结果如下:
如您所见,GL_FILL
选项在进行渐变时会跳过 middle-left
顶点,而 GL_LINE
选项会正确执行。
我该怎么做才能解决这个问题?
停止使用 GL_POLYGON
。
GL_POLYGON
原始类型将被转换为一系列三角形,但这种三角剖分的方式将完全取决于实现。在您的情况下,实现可能是采用前 3 个顶点并从中制作一个三角形。好吧,由于前 3 个顶点共线,因此形成一个没有面积的三角形,因此不会为它们渲染任何内容。
您需要一个非常具体的三角剖分,因此请自己进行三角剖分并使用 GL_TRIANGLES
进行渲染。例如:
float positions[] =
{
-200, 100, // top-left
-200, 0, // middle-left
-200, -100, // bottom-left
200, -100, // bottom-right
200, 0, // middle-right
200, 100, // top-right
};
//In the same order as `positions`.
enum pos_indices { top_left, middle_left, bottom_left, bottom_right, middle_right, top_right };
void position(pos_indices index)
{
int ix = index * 2;
glVertex2f(positions[ix], positions[ix + 1]);
}
float colors[] =
{
1, 0, 0, // red
0, 1, 0, // green
0, 0, 1, // blue
};
//In the same order as `colors`
enum color_indices { red, green, blue };
void color(color_indices index)
{
int ix = index * 3;
glColor3f(colors[ix], colors[ix + 1], colors[ix + 2]);
}
void drawTest()
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glShadeModel(GL_SMOOTH);
glBegin(GL_TRIANGLES);
{
color(red);
position(top_left);
color(green);
position(middle_left);
color(red);
position(top_right);
color(green);
position(middle_left);
color(green);
position(middle_right);
color(red);
position(top_right);
color(green);
position(middle_left);
color(blue);
position(bottom_left);
color(green);
position(middle_right);
color(blue);
position(bottom_left);
color(blue);
position(bottom_right);
color(green);
position(middle_right);
}
glEnd();
}
当我这样做时:
void drawTest()
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glShadeModel(GL_SMOOTH);
glBegin(GL_POLYGON);
glColor3d(1, 0, 0); // red
glVertex2d(-200, 100); // top-left
glColor3d(0, 1, 0); // green
glVertex2d(-200, 0); // middle-left
glColor3d(0, 0, 1); // blue
glVertex2d(-200, -100); // bottom-left
glColor3d(0, 0, 1); // blue
glVertex2d(200, -100); // bottom-right
glColor3d(0, 1, 0); // green
glVertex2d(200, 0); // middle-right
glColor3d(1, 0, 0); // red
glVertex2d(200, 100); // top-right
glEnd();
}
我明白了:
但是当我在第三行切换到glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
时,结果如下:
如您所见,GL_FILL
选项在进行渐变时会跳过 middle-left
顶点,而 GL_LINE
选项会正确执行。
我该怎么做才能解决这个问题?
停止使用 GL_POLYGON
。
GL_POLYGON
原始类型将被转换为一系列三角形,但这种三角剖分的方式将完全取决于实现。在您的情况下,实现可能是采用前 3 个顶点并从中制作一个三角形。好吧,由于前 3 个顶点共线,因此形成一个没有面积的三角形,因此不会为它们渲染任何内容。
您需要一个非常具体的三角剖分,因此请自己进行三角剖分并使用 GL_TRIANGLES
进行渲染。例如:
float positions[] =
{
-200, 100, // top-left
-200, 0, // middle-left
-200, -100, // bottom-left
200, -100, // bottom-right
200, 0, // middle-right
200, 100, // top-right
};
//In the same order as `positions`.
enum pos_indices { top_left, middle_left, bottom_left, bottom_right, middle_right, top_right };
void position(pos_indices index)
{
int ix = index * 2;
glVertex2f(positions[ix], positions[ix + 1]);
}
float colors[] =
{
1, 0, 0, // red
0, 1, 0, // green
0, 0, 1, // blue
};
//In the same order as `colors`
enum color_indices { red, green, blue };
void color(color_indices index)
{
int ix = index * 3;
glColor3f(colors[ix], colors[ix + 1], colors[ix + 2]);
}
void drawTest()
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glShadeModel(GL_SMOOTH);
glBegin(GL_TRIANGLES);
{
color(red);
position(top_left);
color(green);
position(middle_left);
color(red);
position(top_right);
color(green);
position(middle_left);
color(green);
position(middle_right);
color(red);
position(top_right);
color(green);
position(middle_left);
color(blue);
position(bottom_left);
color(green);
position(middle_right);
color(blue);
position(bottom_left);
color(blue);
position(bottom_right);
color(green);
position(middle_right);
}
glEnd();
}