跨顶点的 OpenGL 颜色插值

发布于 2024-08-28 19:53:49 字数 369 浏览 6 评论 0原文

现在,我有超过 25 个顶点构成模型。我想在第一个和最后一个顶点之间线性插值颜色。问题是当我编写以下代码时,

glColor3f(1.0,0.0,0.0);
vertex3f(1.0,1.0,1.0);
vertex3f(0.9,1.0,1.0);
.
.`<more vertices>;
glColor3f(0.0,0.0,1.0);
vertex3f(0.0,0.0,0.0);

除了最后一个顶点之外的所有顶点都是红色的。现在我想知道是否有一种方法可以在这些顶点上插入颜色,而无需我在每个顶点手动插入颜色(而不是本地,就像opengl如何自动插入),因为我将在不同的位置有更多数量的颜色顶点。任何帮助将不胜感激。

谢谢你!

Right now, I have more than 25 vertices that form a model. I want to interpolate color linearly between the first and last vertex. The Problem is when I write the following code

glColor3f(1.0,0.0,0.0);
vertex3f(1.0,1.0,1.0);
vertex3f(0.9,1.0,1.0);
.
.`<more vertices>;
glColor3f(0.0,0.0,1.0);
vertex3f(0.0,0.0,0.0);

All the vertices except that last one are red. Now I am wondering if there is a way to interpolate color across these vertices without me having to manually interpolate color (instead natively, like how opengl does it automatically) at each vertex since, I will be having a lot more number of colors at various vertices. Any help would be extremely appreciated.

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毅然前行 2024-09-04 19:53:49

OpenGL 将在一个顶点和下一个顶点之间插入像素的颜色,但我不知道有什么方法可以让它自动插入中间顶点的值。通常,这并不是特别困难 - 无论如何,您都不想为每个单独的顶点编写代码,因此添加计算非常简单:

class pointf { 
    GLfloat x, y, z;
};

std::vector<pointf> spots;

// ...
GLfloat start_blue = 1.0f;
GLfloat end_blue = 0.0f;
GLfloat start_green = 0.0f;
GLfloat end_green = 0.0f;
GLfloat start_red = 0.0f;
GLfloat end_red = 1.0f;

GLfloat size = spots.size();

glBegin(GL_POLYGON);
for (int i=0; i<spots.size(); i++) {
    GLfloat red = start_red + (end_red-start_red) * i/size;
    GLfloat green = start_green + (end_green-start_green) * i/size;
    GLfloat blue = start_blue + (end_blue-start_blue) * i/size;

    glColor3f(red, green, blue);
    glVertex3f(spots[i].x, spots[i].y, spots[i].z);
}
glEnd();

不过有一件事:这对每个顶点进行纯线性插值。例如,它不会尝试考虑一个顶点与下一个顶点之间的距离。我猜想如何做这样的事情的问题是(至少部分)OpenGL 不自己尝试这样做的原因。

编辑:对于跨半球的渐变,我会尝试这样的操作:

// Blue light on the left  
GLfloat blue[] = {0.0f, 0.0f, 1.0f, 1.0f};
GLfloat blue_pos[] = {-1.0f, 0.0f, -0.3f, 0.0f};

// red light on the right
GLfloat red[] = {1.0f, 0.0f, 0.0f, 1.0f};
GLfloat red_pos[] = {1.0f, 0.0f, -0.3f, 0.0f};

// turn on lighting:
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);

// Set up the two lights:
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, blue);
glLightfv(GL_LIGHT0, GL_POSITION, blue_pos);

glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, red);
glLightfv(GL_LIGHT1, GL_POSITION, red_pos);

// set up the material for our sphere (light neutral gray):
GLfloat sph_mat[] = {0.8f, 0.8f, 0.8f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sph_mat);

// Draw a sphere:
GLUquadric *q = gluNewQuadric();
gluQuadricOrientation(q, GLU_OUTSIDE);
gluQuadricDrawStyle(q, GLU_FILL);
gluQuadricNormals(q, GLU_SMOOTH);
gluSphere(q, 1.0, 64, 64);

目前,我已经完成了球体的外部,但制作半球并没有太大不同。

OpenGL will interpolate colors of pixels between one vertex and the next, but I don't know of any way to get it to automatically interpolate the values for intermediate vertexes. Normally, that's not particularly difficult though -- you don't want to write code for each individual vertex anyway, so adding the computation is pretty trivial:

class pointf { 
    GLfloat x, y, z;
};

std::vector<pointf> spots;

// ...
GLfloat start_blue = 1.0f;
GLfloat end_blue = 0.0f;
GLfloat start_green = 0.0f;
GLfloat end_green = 0.0f;
GLfloat start_red = 0.0f;
GLfloat end_red = 1.0f;

GLfloat size = spots.size();

glBegin(GL_POLYGON);
for (int i=0; i<spots.size(); i++) {
    GLfloat red = start_red + (end_red-start_red) * i/size;
    GLfloat green = start_green + (end_green-start_green) * i/size;
    GLfloat blue = start_blue + (end_blue-start_blue) * i/size;

    glColor3f(red, green, blue);
    glVertex3f(spots[i].x, spots[i].y, spots[i].z);
}
glEnd();

One thing though: this does purely linear interpolation per vertex. It does not, for example, attempt to take into account the distance between one vertex and the next. I'd guess questions of how to do things like this are (at least part of) why OpenGL doesn't attempt this on its own.

Edit: for a gradient across a hemisphere, I'd try something like this:

// Blue light on the left  
GLfloat blue[] = {0.0f, 0.0f, 1.0f, 1.0f};
GLfloat blue_pos[] = {-1.0f, 0.0f, -0.3f, 0.0f};

// red light on the right
GLfloat red[] = {1.0f, 0.0f, 0.0f, 1.0f};
GLfloat red_pos[] = {1.0f, 0.0f, -0.3f, 0.0f};

// turn on lighting:
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);

// Set up the two lights:
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, blue);
glLightfv(GL_LIGHT0, GL_POSITION, blue_pos);

glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, red);
glLightfv(GL_LIGHT1, GL_POSITION, red_pos);

// set up the material for our sphere (light neutral gray):
GLfloat sph_mat[] = {0.8f, 0.8f, 0.8f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sph_mat);

// Draw a sphere:
GLUquadric *q = gluNewQuadric();
gluQuadricOrientation(q, GLU_OUTSIDE);
gluQuadricDrawStyle(q, GLU_FILL);
gluQuadricNormals(q, GLU_SMOOTH);
gluSphere(q, 1.0, 64, 64);

For the moment, I've done the outside of a sphere, but doing a hemisphere isn't drastically different.

浅暮の光 2024-09-04 19:53:49

OpenGL 将在多边形内插值颜色,但不会跨多边形插值。

OpenGL will interpolate color within polygons, but not across polygons.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文