PDA

View Full Version : Mandelbrot on GPU



web
01-28-2007, 04:41 AM
hello,
i don't know if im on the right place here but i'll ask:
i have to program the mandelbrot set for my study.
But i have no experience in C-programming so that i need a compelte simple code with grapical output which runs on the gpu. without zoom etc..

i think it gives many complete code for the mandelbrot in Cg but i haven't found.


please help me.
thanks!!!

Komat
01-28-2007, 06:11 AM
I think I have seen Mandelbrot demo in some SDK. Probably it was ATI SDK (http://ati.de/developer/radeonSDK.html)

web
01-28-2007, 08:23 AM
hi, thx for this answer first!
yes it's in the NVIDIA SDK, too.
but i need a simple code. not a huge code like this.

jide
01-28-2007, 12:19 PM
:)

web
01-28-2007, 01:53 PM
???

jide
01-29-2007, 06:18 AM
I just sheded some smiles :)

In the book OpenGL shading language there's an exemple about that. I don't know if it has been released on the book's website.

Brian Paul
01-29-2007, 07:39 AM
See "mandelbrot.c" here:
http://gitweb.freedesktop.org/?p=mesa/me...-1;f=progs/glsl (http://gitweb.freedesktop.org/?p=mesa/mesa.git;a=tree;h=0add31861ef13678dd3d150b333403ff c1f10a74;hb=glsl-compiler-1;f=progs/glsl)

It's a test program using the shaders from the OpenGL orange book.

-Brian

gigadude
01-30-2007, 02:06 AM
Here's a quick-and-dirty GL2.0 mandelbrot/julia explorer that I wrote a while back using GLUT:


//
// psmand - gl2.0 mandelbrot/julia shader demo
//
// Author: Edward Hutchins, Jan 2006
// License: Public Domain
//

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glut.h>

static const GLint SCREEN_W = 600;
static const GLint SCREEN_H = 600;
static const GLfloat NEAR_W = 0.1;
static const GLfloat FAR_W = 10.0;

static GLint screen_w = SCREEN_W;
static GLint screen_h = SCREEN_H;

// mandelbrot center
static GLfloat cx = 0;
static GLfloat cy = -0.5;
// zoom to edges of rect
static GLfloat zoom = 1.5;

// mandelbrot shader
static GLuint hMandProg = 0;
// julia shader
static GLuint hJuliaProg = 0;
// uniform seed
static GLint julia_c_pos = 0;

static bool bDragging = false;
static int nDragPt[2];
static bool bJuliaing = false;
static int nJuliaPt[2];

#define FAIL(x) do { printf x; printf( "\n" ); exit( 1 ); } while (0)

void display()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );

glColor4f( 1, 0, 0, 1 );

GLfloat left = cx - zoom;
GLfloat right = cx + zoom;
GLfloat top = cy - zoom;
GLfloat bottom = cy + zoom;

glBegin( GL_TRIANGLE_STRIP );
glTexCoord2f( left, bottom );
glVertex2f( -1, -1 );

glTexCoord2f( right, bottom );
glVertex2f( 1, -1 );

glTexCoord2f( left, top );
glVertex2f( -1, 1 );

glTexCoord2f( right, top );
glVertex2f( 1, 1 );
glEnd();

glutSwapBuffers();
}

void make_tex()
{
const int TEX_SIZE = 1024;
GLfloat tex[TEX_SIZE][4];

// create a rainbow lookup table for coloring the iteration count
// (could be any function you like)
for (int x = 0; x < TEX_SIZE - 1; ++x)
{
float f = 3.1415927 * x / TEX_SIZE;
float c = cos( f );
float s = sin( f );
tex[x][0] = 1 - c;
tex[x][1] = s * s;
tex[x][2] = c;
tex[x][3] = 1;
}
tex[TEX_SIZE - 1][0] = tex[TEX_SIZE - 1][1] = tex[TEX_SIZE - 1][2] = tex[TEX_SIZE - 1][3] = 0;

glTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, TEX_SIZE, 0, GL_RGBA, GL_FLOAT, tex );
}

GLuint make_frag_prog( const GLchar *pcszShader )
{
GLuint hShader = glCreateShader( GL_FRAGMENT_SHADER );
if (!hShader) FAIL(( "Can't create shader!" ));

const GLchar *ppcszShader[1] = { pcszShader };

glShaderSource( hShader, 1, ppcszShader, NULL );
glCompileShader( hShader );
GLint nStatus;
glGetShaderiv( hShader, GL_COMPILE_STATUS, &amp;nStatus );
if (!nStatus)
{
char szBuff[10240];
glGetShaderInfoLog( hShader, sizeof(szBuff), NULL, szBuff );
FAIL(( "Shader failed to compile:\n%s", szBuff ));
}
else printf( "Shader compiled okay!\n" );

GLuint hProgram = glCreateProgram();
if (!hProgram) FAIL(( "Can\'t create program!" ));

glAttachShader( hProgram, hShader );

glLinkProgram( hProgram );
glGetProgramiv( hProgram, GL_LINK_STATUS, &amp;nStatus );
if (!nStatus)
{
char szBuff[10240];
glGetProgramInfoLog( hProgram, sizeof(szBuff), NULL, szBuff );
FAIL(( "Program failed to link:\n%s", szBuff ));
}
else printf( "Program linked okay!\n" );

return( hProgram );
}

void init()
{
make_tex();

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glEnable( GL_TEXTURE_1D );

//glAlphaFunc( GL_GEQUAL, 0.5 );
//glEnable( GL_ALPHA_TEST );

hMandProg = make_frag_prog(
"uniform sampler1D myTexture;\n"
"void main( void )\n"
"{\n"
" // swap x,y on texcoords to get nice orientation (should be via viewport)\n"
" vec2 p; p.x = p.y = 0;\n"
" vec2 c = vec2( gl_TexCoord[0].yx );\n"
" float iters = 0;\n"
" while ((iters < 1) &amp;&amp; (dot( p, p ) < 4))\n"
" {\n"
" float nx = p.x * p.x - p.y * p.y + c.x;\n"
" float ny = 2 * p.x * p.y + c.y;\n"
" p.x = nx; p.y = ny;\n"
" iters += 1 / 255.0;\n"
" }\n"
" gl_FragColor = texture1D( myTexture, iters );\n"
"}\n"
);

hJuliaProg = make_frag_prog(
"uniform sampler1D myTexture;\n"
"uniform vec2 c;\n"
"void main( void )\n"
"{\n"
" // swap x,y on texcoords to get nice orientation (should be via viewport)\n"
" vec2 p = vec2( gl_TexCoord[0].yx );\n"
" float iters = 0;\n"
" while ((iters < 1) &amp;&amp; (dot( p, p ) < 4))\n"
" {\n"
" float nx = p.x * p.x - p.y * p.y + c.x;\n"
" float ny = 2 * p.x * p.y + c.y;\n"
" p.x = nx; p.y = ny;\n"
" iters += 1 / 255.0;\n"
" }\n"
" gl_FragColor = texture1D( myTexture, iters );\n"
"}\n"
);

julia_c_pos = glGetUniformLocation( hJuliaProg, "c" );
if (julia_c_pos < 0)
{
FAIL(( "Failed find julia shader \"c\" uniform!\n" ));
}
printf( "julia_c_pos = %d!\n", julia_c_pos );

glUseProgram( hMandProg );
}

void reshape( int w, int h )
{
screen_w = w;
screen_h = h;

glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -1, 1, -1, 1, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}

static void motion( int x, int y )
{
if (bDragging)
{
int dx = x - nDragPt[0];
int dy = y - nDragPt[1];
cx -= (2 * zoom / screen_w) * dx;
cy -= (2 * zoom / screen_h) * dy;
nDragPt[0] = x;
nDragPt[1] = y;
glutPostRedisplay();
}

if (bJuliaing)
{
int dx = x - nJuliaPt[0];
int dy = y - nJuliaPt[1];
GLfloat jx = cx + (2 * zoom / screen_w) * dx;
GLfloat jy = cy + (2 * zoom / screen_h) * dy;
// backwards, yech
//glUniform2f( julia_c_pos, jx, jy );
glUniform2f( julia_c_pos, jy, jx );
glutPostRedisplay();
}
}

static void mouse( int button, int state, int x, int y )
{
switch (button)
{
case GLUT_LEFT_BUTTON:
bDragging = (state == GLUT_DOWN);
nDragPt[0] = x;
nDragPt[1] = y;
if (bDragging) glutPostRedisplay();
break;

case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
{
bJuliaing = true;
glUseProgram( hJuliaProg );
// first point is at current center
nJuliaPt[0] = screen_w / 2;
nJuliaPt[1] = screen_h / 2;
}
else if (state != GLUT_DOWN)
{
bJuliaing = false;
glUseProgram( hMandProg );
}
glutPostRedisplay();
break;

case 3:
if (state == GLUT_DOWN)
{
zoom *= 0.9;
if (zoom < 1e-9) zoom = 1e-9;
glutPostRedisplay();
}
break;

case 4:
if (state == GLUT_DOWN)
{
zoom *= 1.1;
if (zoom > 2) zoom = 2;
glutPostRedisplay();
}
break;

default:
printf( "button %d %s\n", button, (state == GLUT_DOWN) ? "down" : "up" );
break;
}
}

static void keyboard( unsigned char c, int x, int y )
{
switch (c)
{
case 27:
exit( 0 );
break;
}
}

int main( int argc, char *argv[] )
{
glutInit( &amp;argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
glutInitWindowSize( SCREEN_W, SCREEN_H );
glutCreateWindow( "GL 2.0 test" );
glutReshapeFunc( reshape );
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMouseFunc( mouse );
glutMotionFunc( motion );

init();

glutMainLoop();

return( 0 );
}
The Makefile that works for me under Linux:


all: psmand

%: %.cpp
g++ -o $@ $< -L/usr/X11R6/lib -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm

web
01-31-2007, 10:51 AM
another question:
i have download gll source code. it includes a *.vert and *.frag file.

http://developer.3dlabs.com/downloads/glsldemo/

is it possible to run this files without the GLSLdemo Windows installer?

can someone create me a visual studio project file for this?

pleease i need it so badly.
thx

Zengar
01-31-2007, 11:52 AM
May I ask you what and why are you actually studying? :-/

ferrari2k
01-31-2007, 01:28 PM
Originally posted by gigadude:
Much text
Thanks für that code, unfortunately I can not get it to work under Windows with MS Visual Studio 2003.
We (web and me) learned just Java in university and now we have to program a GPU so we have to get familiar with C/C++/Cg and MS Visual Studio as quickly as possible. Can you please point me how I can get that code compiled? Thanks in advance :)
Oh I forgot about the errors, could be useful ;)
I included the line "#include <windows.h>" on top of the file and during linking I get the following error messages:
"Nicht aufgelöstes externes Symbol" is german for "Nonresolved external symbol" (I hope I got that right ;) )
http://ferrari2k.dyndns.org/~schepker/gpu.jpg

web
01-31-2007, 02:43 PM
@Brian Paul:
thanlk but have u any idea how can i get the extfuncs.h?
;-)

Flavious
02-01-2007, 06:39 AM
You can find the extension registry and links to the headers here (glext.h and so forth):
http://www.opengl.org/registry/

Cheers

web
02-01-2007, 07:25 AM
yes but not this one...or?

Flavious
02-01-2007, 07:35 AM
I'm sorry, but I don't understand what you're asking.

If you're confused about how to load extensions, you might want to look at one of the extension loaders (glew/glee), which you can read about in the sticky wiki.

Cheers

maxphil
02-02-2007, 02:28 AM
Reedbeta has a mandelbrot (opengl) avaiable for download WITH source-code.

http://pages.pomona.edu/~nrr02004/opengl.html