00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _FRACTAL_GL_H_
00022 #define _FRACTAL_GL_H_
00023
00024 #include "../fractal.h"
00025
00026 #include <QtOpenGL/QGLPixelBuffer>
00027 #include <QtOpenGL/QGLShaderProgram>
00028
00029 static QGLPixelBuffer* s_pixel_buffer = NULL;
00030 static QGLShaderProgram* s_shader_program = NULL;
00031 static GLuint s_texture_id;
00032
00033
00038 class Fractal_GL_Mother : public Fractal
00039 {
00040 public:
00041 Fractal_GL_Mother( const FractalParameters& _fractal_parameters )
00042 : Fractal( _fractal_parameters )
00043 {
00044 if( s_pixel_buffer != NULL ) delete s_pixel_buffer;
00045 if( s_shader_program != NULL ) delete s_shader_program;
00046 s_pixel_buffer = new QGLPixelBuffer( m_fractal_parameters.imageSize() );
00047 s_shader_program = new QGLShaderProgram();
00048 s_pixel_buffer->makeCurrent();
00049
00050
00051 glMatrixMode( GL_PROJECTION );
00052 glLoadIdentity();
00053 #ifdef QT_OPENGL_ES
00054 glOrthof(0.0, +1.0, 0.0, +1.0, -90.0, +90.0);
00055 #else
00056 glOrtho(0.0, +1.0, 0.0, +1.0, -90.0, +90.0);
00057 #endif
00058 glMatrixMode(GL_MODELVIEW);
00059
00060 glEnable( GL_TEXTURE_1D );
00061 glGenTextures( 1, &s_texture_id );
00062 glBindTexture( GL_TEXTURE_1D, s_texture_id);
00063 glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
00064 glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
00065 glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT );
00066 }
00067
00068 virtual qreal progress() const
00069 {
00070 return 1.0;
00071 }
00072
00073 virtual QImage toImage( const Palette& _palette ) const
00074 {
00075 s_pixel_buffer->makeCurrent();;
00076
00077 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, QGLWidget::convertToGLFormat( _palette.generateImage( 256, 1 ) ).bits() );
00078
00079 s_shader_program->bind();
00080 s_shader_program->setUniformValue( "sequence_max", (GLfloat)m_fractal_parameters.sequenceMax() );
00081
00082 glBegin( GL_QUADS );
00083
00084 glTexCoord2f( m_fractal_parameters.zone().x() , m_fractal_parameters.zone().y() + m_fractal_parameters.zone().height() );
00085 glVertex3f( 0.0f, 0.0f, 0.0f );
00086 glTexCoord2f( m_fractal_parameters.zone().x() , m_fractal_parameters.zone().y() );
00087 glVertex3f( 0.0f, 1.0f, 0.0f );
00088 glTexCoord2f( m_fractal_parameters.zone().x() + m_fractal_parameters.zone().width() , m_fractal_parameters.zone().y() );
00089 glVertex3f( 1.0f, 1.0f, 0.0f );
00090 glTexCoord2f( m_fractal_parameters.zone().x() + m_fractal_parameters.zone().width() , m_fractal_parameters.zone().y() + m_fractal_parameters.zone().height() );
00091 glVertex3f( 1.0f, 0.0f, 0.0f );
00092
00093 glEnd();
00094
00095 return s_pixel_buffer->toImage();
00096 }
00097
00098 virtual int load( QFile& )
00099 {
00100 return -1;
00101 }
00102 virtual int save( QFile& ) const
00103 {
00104 return -1;
00105 }
00106
00107 protected:
00108 virtual void run()
00109 {
00110 quit();
00111 }
00112 };
00113
00114
00120 template< typename TSequence >
00121 class Fractal_GL : public Fractal_GL_Mother
00122 {
00123 public:
00124 Fractal_GL( const FractalParameters& _fractal_parameters )
00125 : Fractal_GL_Mother( _fractal_parameters )
00126 {
00127 m_is_valid = false;
00128 }
00129 };
00130
00131
00137 template< >
00138 class Fractal_GL< Mandelbrot > : public Fractal_GL_Mother
00139 {
00140 public:
00141 Fractal_GL( const FractalParameters& _fractal_parameters )
00142 : Fractal_GL_Mother( _fractal_parameters )
00143 {
00144 s_shader_program->addShaderFromSourceFile( QGLShader::Fragment, "shaders/mandelbrot.fsl" );
00145 s_shader_program->link();
00146 }
00147 };
00148
00149
00150 #endif //_FRACTAL_GL_H_