PDA

View Full Version : Very Slow Display function?



Capt.Yoda
05-16-2014, 12:22 PM
Hi,

I'm trying to work on a basic powder game like project but just with OpenGL and I created this basic code:




#include <GL/glut.h>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <cstdio>

#define screen_x 1024
#define screen_y 768

#define M_PI 3.14
struct Particle {
float x;
float y;
float r;
float vx;
float vy;
float m;
int type;
float color[3];
};

struct Line {
float x1;
float y1;
float x2;
float y2;
} line;

void timer(int = 0);
void display();
void mouse(int, int, int, int);
void mouseMotion(int, int);
void add_particle(float, float = 0, float = 0);
void remove_particles();
void keyboard(unsigned char, int, int);

int NEXT = 0;
int mouse_x, mouse_y, WIN,
mode = 2,
crit_mass = 1,
MAX_MASS = 50000000;
float cnst_elastic = 0.75;
double z = 0.0;
bool PRESSED_LEFT = false, PRESSED_RIGHT = false,
PRESSED_MIDDLE = false, SPEED_PARTICLES = false;

std::vector<Particle> particles;

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(screen_x, screen_y);
glutInitWindowPosition(50, 50);
WIN = glutCreateWindow("Rohan Toy");

glClearColor(0, 0, 0, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-screen_x / 2, screen_x / 2, screen_y / 2, -screen_y / 2, 0, 1);

glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutKeyboardFunc(keyboard);
timer();

glutMainLoop();
return 0;
}

void timer(int){
display();
if (PRESSED_LEFT && !SPEED_PARTICLES)
{
add_particle(1);
PRESSED_LEFT = false;
}

if (PRESSED_RIGHT)
{
int x = mouse_x;
int y = mouse_y;
for (int i = 0; i<250; i++){
mouse_x = rand() % 250 - 125 + x;
mouse_y = rand() % 250 - 125 + y;
add_particle(rand() % 500 + 250);
}
PRESSED_RIGHT = false;
}

if (PRESSED_MIDDLE)
remove_particles();


for (int i; i < particles.size(); i++)
{
Particle &p = particles[i];
if (p.type == 2)
p.y += 0.45;
else
p.y += 0.50;
particles[i] = p;
}

for (int i; i < particles.size(); i++)
{
Particle &p = particles[i];
for (int c; c < particles.size(); c++)
{
Particle &z = particles[i];
if (z.y == p.y)
{
p.y -= 0.50;
particles[i] = p;
}
}
}

glutTimerFunc(0.1, timer, 0);
}

void display(){
glClear(GL_COLOR_BUFFER_BIT);


for (int i = 0; i < particles.size(); i++){
Particle &p = particles[i];
glColor3f(p.color[0], p.color[1], p.color[2]);
glBegin(GL_POLYGON);
for (float a = 0; a < 2 * M_PI; a += 0.25)
glVertex2f(p.r*cos(a) + p.x, p.r*sin(a) + p.y);
glEnd();
}

glFlush();
glutSwapBuffers();

}

void mouse(int button, int state, int x, int y){
mouse_x = x - screen_x / 2;
mouse_y = y - screen_y / 2;

if (SPEED_PARTICLES){
if (line.x2 != 0 && line.y2 != 0 && state == GLUT_UP && PRESSED_LEFT)
add_particle(100, line.x1 - line.x2, line.y1 - line.y2);
else{
line.x1 = line.x2 = mouse_x;
line.y1 = line.y2 = mouse_y;
}
}

if (button == GLUT_LEFT_BUTTON)
PRESSED_LEFT = state == GLUT_DOWN;
else if (button == GLUT_RIGHT_BUTTON)
PRESSED_RIGHT = state == GLUT_DOWN;
else if (button == GLUT_MIDDLE_BUTTON)
PRESSED_MIDDLE = state == GLUT_DOWN;
}

void mouseMotion(int x, int y){
mouse_x = x - screen_x / 2;
mouse_y = y - screen_y / 2;

if (SPEED_PARTICLES && PRESSED_LEFT){
line.x2 = mouse_x;
line.y2 = mouse_y;
}
}

void add_particle(float m, float vx, float vy){
Particle p;
p.x = mouse_x;
p.y = mouse_y;
p.vx = vx / 30;
p.vy = vy / 30;
p.m = m;
p.r = pow((p.m / M_PI), 0.175);
if (NEXT == 0)
p.type = 1;
else
p.type = 2;
p.color[0] = 1.0;
p.color[1] = 1.0 - p.m * 1 / MAX_MASS;
p.color[2] = 0.0;

particles.push_back(p);

if (line.x1 != 0)
line.x1 = line.x2 = line.y1 = line.y2 = 0;
}

void remove_particles(){
for (int j = 0; j<5; j++){
for (int i = 0; i < particles.size(); i++)
particles.pop_back();
}
}

void keyboard(unsigned char key, int x, int y)


Press\Hold "R" on keyboard and it becomes extremely slow while other games like Powder toy are barely even lagging, is there a different way of doing this maybe using some Video function than this?

GClements
05-17-2014, 03:34 PM
is there a different way of doing this maybe using some Video function than this?
1. Store the data as a 2D array and render it as a texture, not as individual points.

2. If you're rendering many primitives, use vertex arrays (glDrawArrays etc) rather than glBegin/glEnd. Modern versions of OpenGL (OpenGL 3, OpenGL ES, WebGL) have either deprecated or removed those operations because they're too inefficient.

mhagain
05-17-2014, 08:48 PM
glBegin/glEnd are more than capable of being plenty fast enough if you can put them outside a loop rather than inside it. Unfortunately because you're using GL_POLYGON you can't do that. If you can find a way to switch to GL_QUADS or GL_TRIANGLES and move that glBegin/glEnd outside your "for (int i" loop, this will go like a rocket and you won't need a VBO or glDrawArrays/glDrawElements.

Capt.Yoda
05-26-2014, 04:07 AM
Thanks Guys, it helped.