答案 0 :(得分:0)
这是使用固定功能opengl管道的一个小优化示例:
#define FREEGLUT_LIB_PRAGMAS 1
#define NDEBUG 1
#include <GL/glut.h>
#include <cmath>
using namespace std;
#define MAX_POINTS 8
#define PROJ_VALUE 40
float points[MAX_POINTS][2];
void init() {
points[0][0] = 0;
points[0][1] = 10;
points[1][0] = 1;
points[1][1] = 8;
points[2][0] = 2;
points[2][1] = 4;
points[3][0] = 3;
points[3][1] = 7;
points[4][0] = 4;
points[4][1] = 3;
points[5][0] = 5;
points[5][1] = 4;
points[6][0] = 6;
points[6][1] = 5;
points[7][0] = 7;
points[7][1] = 0;
}
float lerp(float x, float a, float b) {
return x * b + (1 - x) * a;
}
void plot_function(int step_x, int step_y) {
for (int i = 0; i < MAX_POINTS; i++) {
float x0 = (float)points[i][0] * step_x + step_x;
float y0 = (float)points[i][1] * step_y;
float x1 = (float)points[i + 1][0] * step_x + step_x;
float y1 = (float)points[i + 1][1] * step_y;
for (int j = 0; j < step_x; j++) {
float k = (float)j / step_x;
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex2f(x0 + j, 0);
glVertex2f(x0 + j, lerp(k, y0, y1));
glEnd();
}
glColor3f(0.0, 1.0, 0.0);
glPointSize(8);
glBegin(GL_POINTS);
glVertex2f(x0, y0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex2f(x0, y0);
glVertex2f(x1, y1);
glEnd();
}
}
void display() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, PROJ_VALUE, 0, PROJ_VALUE, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
plot_function(5, 2);
glutSwapBuffers();
}
int main(int argc, char **argv) {
init();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
glutCreateWindow("StackOverflow gl plotting");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
结果如下:
我会给你练习让它变得更漂亮(圆点,抗锯齿,剪裁,平滑渲染)并正确地重构代码以更快更清洁。希望它有所帮助。
编辑:
上述代码的简要说明:
一开始你会有一些控制点(绿点)。通常将这些点存储到浮点值数组中,在上面的代码中,它们只存储在名为points
的全局变量中。要绘制这些点,您只需要遍历数组并使用opengl函数绘制点,它们代表x&amp; y坐标。您也可以轻松地从[x,y]到[x,0]绘制白线。
现在,棘手的部分,我们如何绘制中间点?它们实际上是什么?首先,您需要了解线性插值是什么,读取here,但基本上是一个类似x*b+(1-x)*a
的公式,如果考虑x = 0,结果将是a,如果x = 1结果将是b,如果值在[0,1]之间,你将获得a和b之间的值。因此,为了计算中间点,您只需在前一个和下一个点之间应用线性插值,您可以在行glVertex2f(x0 + j, lerp(k, y0, y1))
中看到。
关于step_x&amp; step_y参数,如果你更容易理解,用0替换它们并删掉它们,这样你就可以很容易地理解代码了。