В настоящее время я работаю над программой, которая сможет визуализировать эволюцию точки на плоскости, которая течет вдоль векторного поля. Я закончил первую версию, которую я вставил ниже. При запуске программы с большим количеством точек кажется, что только последние, скажем, 30000 точек попадают в окно. Я хотел бы иметь возможность рисовать около 1000000 точек, так что я далеко.
Я попытался перебрать число итераций (переменная Итерация — контролирует количество точек), и здесь все работает отлично. Однако при его увеличении по существу первая часть больше не рисуется.
#include <iostream>
#include <stdio.h>
#include <math.h>
//#include <gsl/gsl_math.h>
//#include <gsl/gsl_sf.h>
#include <GL/freeglut.h>
#include <GL/gl.h>
using namespace std;
//Initial iterations to make the system settle:
int initIter=0;
//Iterations once system has settled:
int Iterations = 100000;
/**Starting point in time-phase-space (t,x,y,vx,vy).
For mathematical reasons the last two components should
always be 0**/
float TPS[5]={0,0.00,0.100,0.00,0.000};
//Timestep:
float dt=0.001;/**The Step function make one Picard
iteration **/
float * Step(float * Arr){
static float NewTPS[5];
NewTPS[0] = Arr[0]+dt;
NewTPS[1] = Arr[1]+Arr[3]*dt;
NewTPS[2] = Arr[2]+Arr[4]*dt;
//This is the dynamical functions:
NewTPS[3] = -Arr[2];
NewTPS[4] = Arr[1];
return NewTPS;
}/** This function sets up GLUT plotting
window: **/
void myInit(){
// set the background color
glClearColor(0.0f, 0.0f, 0.0f, 1.00f);
// set the foreground (pen) color
glColor4f(1.0f, 1.0f, 1.0f, 0.04f);
// set up the viewport
glViewport(0, 0, 800, 800);
// set up the projection matrix (the camera)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-2.0f, 2.0f, -2.0f, 2.0f);
// set up the modelview matrix (the objects)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Computing initial iterations:
for (int i=0;i<initIter;i++){
//cout << TPS[1]<<" " << TPS[2] << endl;
float * newTPS2;
newTPS2 = Step(TPS);
//Assigning the values of newTPS2 to TPS:
for (int j=0; j<5;j++){
TPS[j]=*(newTPS2+j);
}
}
// enable blending
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// enable point smoothing
//glEnable(GL_POINT_SMOOTH);
//glPointSize(1.0f);
}
/** This function draws a the point that
is passed to it: **/
void Draw(){
// clear the screen
glClear(GL_COLOR_BUFFER_BIT);
// draw some points
glBegin(GL_POINTS);
for (int i = 0; i <Iterations ; i++) {
float * newTPS2;
//cout << TPS[0]<< " " << TPS[1] << " " << TPS[2]<< endl;
newTPS2 = Step(TPS);
//Assigning the values of newTPS to TPS:
for (int j=0; j<5;j++){
TPS[j]=*(newTPS2+j);
}
// draw the new point
glVertex2f(TPS[1], TPS[2]);
}
glEnd();
// swap the buffers
glutSwapBuffers();
//glFlush();
}int main(int argc, char** argv){
// initialize GLUT
glutInit(&argc, argv);
// set up our display mode for color with alpha and double buffering
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);glutInitWindowSize(800, 800);
glutCreateWindow("Trace of 2D-dynamics");
myInit();
// register our callback functions
glutDisplayFunc(Draw);
// glutKeyboardFunc(mykey);
// start the program
glutMainLoop();
return 0;
}
Если вы хотите просто раскрасить определенные пиксели на экране, вы не должны использовать glVertex
совсем. Поместите их в непрерывный блок памяти, создайте из него текстуру и визуализируйте квад, покрывающий весь экран. Это может быть быстрее, чем вычисление их позиций внутри OpenGL.
Возможно, в вашей реализации размер примитива ограничен коротким знаком, то есть 32768 баллов. Если это так, вы должны сделать glEnd/glBegin
для каждой группы 32768 баллов или около того:
for (int i = 0, x = 0; i <Iterations ; i++, x++) {
//...
if (x >= 32768)
{
x = 0;
glEnd();
glBegin(GL_POINTS);
}
//...
}
Кстати, вы можете рассмотреть возможность использования объектов буфера вершин (VBO). Это ограничение, вероятно, то же самое, но рисовать довольно быстро.