I can't resolve a very stupid problem

hi, i started to study opengl few days ago, and i wanted to try to draw a mandelbrot set (the fractal by definition) in 2d using opengl/glut
the problem i get is that everything i obtain is a black window :frowning:

here i post the code (very simple):

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>

#define W 640
#define H 480

#define Xmin -2.0
#define Xmax 2.0
#define Ymin -2.0
#define Ymax 2.0

#define STEP 0.005
#define ITERS 512

typedef struct _complex
{
	double r, i;
}Complex;


void reshape(int w, int h)
{
	//rende l'intera area visibile
	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	//impostano il sistema di coordinate
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D((GLdouble)0, (GLdouble) W, (GLdouble)0, (GLdouble) H);
}

void display(void)
{
	Complex c, z_n;
	int x, y, n;
	
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_POINTS);
	
		glColor3d((GLdouble) 1.0, (GLdouble) 1.0, (GLdouble) 1.0);
	//creazione frattale
		for(x = 0; x < W; x++)
		{
			z_n.r = c.r = (x / W) * (Xmax - Xmin) + Xmin; //calcolo c.r solo quando cambia
			for(y = 0; y < H; y++)
			{
				z_n.i = c.i = (y / H) * (Ymax - Ymin) + Ymin;
				//inizio del ciclo di iterazioni per scoprire se la funzione iterata converge o meno
				for(n = 0; n < ITERS; n++)
				{
					if((((z_n.r * z_n.r) + (z_n.i * z_n.i))) > 4.0)
					{
						glVertex2i(x, y);
						break;
					}
					//else
					z_n.r = (z_n.r * z_n.r) -  (z_n.i * z_n.i) + c.r;
					z_n.i = (2 * z_n.r * z_n.i) + c.i;
				}
			}
		}
	
	glEnd();
	
	glFlush();
}


int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(W, H);
	glutCreateWindow("glFractal");
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	
	glutMainLoop();
	return 0;
}

i would really appreciate if someone can help me in these first steps in the world of opengl
bye :slight_smile:

Your coordinates are screen coordinates. The coordinate system uses values from -1.0 to 1.0. So your are rendering outside the screen I guess. Use float or double as coordinates and have the values range from -1.0 to 1.0.

the xy plane is defined by this instruction
gluOrtho2D((GLdouble)0, (GLdouble) W, (GLdouble)0, (GLdouble) H);

so, for each pixel, i map the pixel coordinates on the complex plane and then calc for that pixel if the iterated functiond diverges or not

somebody can help me?

512 iteration O_O it will take forever…
Here the corrected code.


Complex temp, z_n, c;
	
float scale = 0.005f; // 200 pixel un unita'
float xLimit = (winWidth_*0.5f)*scale;
float yLimit = (winHeight_*0.5f)*scale;
	
if(viewportNeedUpdate_){
// you can move this part in your resize function
   glLoadIdentity();
   glOrtho(-xLimit, xLimit, -yLimit, yLimit, -1, 1);
}

glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
	
//creazione frattale
for(float x = -xLimit; x < xLimit; x += scale)
{
   for(float y = -yLimit; y < yLimit; y+= scale)
   {
      z_n.r = .0f;
      z_n.i = .0f;
      c.r = x;
      c.i = y;
      for(unsigned int n = 0; n < 50; n++)
      {
         if((((z_n.r * z_n.r) + (z_n.i * z_n.i))) > 4.0)
         {
            glColor3f(n*0.02f, 0.02f, 0.02f);
            glVertex2f(x, y);
            break;
         }
         temp.r = (z_n.r * z_n.r) -  (z_n.i * z_n.i) + c.r;
         temp.i = (2 * z_n.r * z_n.i) + c.i;
         z_n.r = temp.r;
         z_n.i = temp.i;
      }
   }
}
glEnd();

Here the corrected code, I modified a little bit your application
First, the computation of the orbit was wrong.
The right computation is
Z = 0 (not c)
Z_n+1 = z_n^2 + c
You need to use a temp variable or you are computing the wrong value.

Also you can change color per pixel based on the number of iteration. It give a better effect.

I modified also the work area, now there is a scale factor (200 pixel = 1 unit) so the curve is not distorted and you can resize the windows without problem.

In Italian (sorry guys, only basic openGL hints):
Ho modificato un po’ la parte di disegno, il resto è solo glut standard ed era giusto.

A proposito, openGl non è fatto apposta per fare questo tipo di programma. openGL è organizzato per renderizzare triangoli e possibilmente far fare tutto il lavoro alla scheda video. In pratica così la tua applicazione fa tutti i calcoli sulla CPU e manda un vertice ogni morte di papa alla scheda video (che lo processa in un picosecondo). Prova a rifare la stessa cosa dentro uno shader, vedrai che andrà cento volte più veloce. :wink:

hi rosario, thanks very much for your tips.
the main problem was the lack of a temp complex variable. the program will work just adding it. but with this other corrections it goes better.

regarding the initialization of the variable z_n, both are right, because if z_n = 0, in the first iteration it’ll become z_n = c. in practice i skip an iteration, but that’s not the point…

i know that all the computations are made by the cpu, i guess with a shader this work will be done by the gpu, am i right?

when i read something about the shaders, i will try it.

for now thanks for the help :slight_smile: