2013-02-24 2 views
0

В настоящее время я работаю над программой, которая сможет визуализировать эволюцию точки на плоскости, которая течет вдоль векторного поля. Я закончил первую версию, которую я вставил ниже. При запуске программы с большим количеством точек кажется, что в окно втягивается только последнее 30000 очков. Я хотел бы иметь возможность набрать около 1000000 очков, поэтому я ухожу.Opengl, C++: Большое количество баллов

Я пробовал любоваться номером, если итерации (переменная Iteration - контроль количества очков), и здесь он действует просто отлично. Однако при его существенном увеличении первая часть больше не нарисована.

#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; 
    } 
+2

'glVertex2f' устарел. Вероятно, вы хотите изучать современный OpenGL, а не OpenGL 1990-х: http://www.arcsynthesis.org/gltut/. В частности, если вы хотите, чтобы все хорошо масштабировалось. – Flexo

+0

Спасибо за ссылку - посмотрим на нее. – Martin

+0

Весь ваш OpenGL является достаточно правильным; Я подозреваю, что проблема кроется в другом месте. В частности, ваш вызов 'gluOrtho2D' ограничивает все ваши частицы диапазоном [-2,2] в x и y. Вы уверены, что все ваши числовые интеграции (и, следовательно, конкретные позиции) остаются в этом диапазоне? – radical7

ответ

4

Если вы хотите просто окрасить определенные пиксели на экране, вы не должны использовать glVertex. Поместите их все в блок памяти contiguos, создайте текстуру из нее и сделайте квадрат, покрывающий весь экран. Это может быть быстрее, чем вычисление их позиций внутри OpenGL.

+0

Хороший трюк - тогда я посмотрю на текстуры. – Martin

+0

На самом деле, я не вижу проблемы с использованием 'glVertex' в этом экземпляре (за исключением, возможно, отвращения к использованию OpenGL в старом стиле). То, что OP хочет сделать, это просто построить набор двумерных точек (игнорируя характеристики скорости, из которых есть способы (например, VBOs)), это путь. Он просто решает проблему без того, чтобы программист должен был эффективно писать растеризатор. Это «стиль» (используйте современный OpenGL, потому что это классный способ) и «производительность» (выполняйте свою работу). – radical7

-2

Возможно, в вашей реализации размер примитива ограничен подписанным коротким, то есть 32768 точками. Если это так, вы должны сделать glEnd/glBegin для каждой группы 32768 точек или так:

for (int i = 0, x = 0; i <Iterations ; i++, x++) { 
    //... 
    if (x >= 32768) 
    { 
     x = 0; 
     glEnd(); 
     glBegin(GL_POINTS); 
    } 
    //... 
} 

Кстати, вы можете рассмотреть возможность использования буфера вершин объектов (ВБО). Это ограничение, вероятно, одно и то же, но довольно быстро сделать.

+0

Кажется, ваше право об ограничении до 32768 пикселей. Спасибо, и я посмотрю на VBO. – Martin

+0

@rodrigo Нет, это неправильно. В OpenGL нет такого предела для количества вершин, которые вы можете отправить между парой 'glBegin' /' glEnd' и, в частности, для 'GL_POINTS'. В зависимости от примитивного типа (например, 'GL_POINTS'), и когда OpenGL получает столько вершин, он растеризует этот геометрический примитив. Посмотрите на (провоцирующую вершину) [https://www.opengl.org/wiki/Primitive#Provoking_vertex]. BTW, это верно, независимо от того, используете ли вы семантику начала/конца или VBOs и 'glDrawArrays' или' glDrawElements'. – radical7

Смежные вопросы