Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Very Slow Display function?

  1. #1
    Junior Member Newbie
    Join Date
    May 2014
    Posts
    9

    Very Slow Display function?

    Hi,

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


    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?

  2. #2
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by Capt.Yoda View Post
    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.

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,201
    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.

  4. #4
    Junior Member Newbie
    Join Date
    May 2014
    Posts
    9
    Thanks Guys, it helped.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •