Doesnt require any media.
Ive been working on converting the NeHe tutorials to BMAX. Previously Ive been playing with simple 2d metaballs. Here they are combined :)
The flag is just a bunch of quads.
The 2d drawing area is a 2d array, pixels are set individually.
The "2d surface" is put on the flag pixel-by-pixel, quad-by-quad with glColor3f.
----
How do I change from windowed to fullscreen while running? Guess I could look at the NeHe tutorials for this.
Ive been working on converting the NeHe tutorials to BMAX. Previously Ive been playing with simple 2d metaballs. Here they are combined :)
The flag is just a bunch of quads.
The 2d drawing area is a 2d array, pixels are set individually.
The "2d surface" is put on the flag pixel-by-pixel, quad-by-quad with glColor3f.
----
How do I change from windowed to fullscreen while running? Guess I could look at the NeHe tutorials for this.
SuperStrict Framework BRL.GLGraphics Import Pub.GLEW Import BRL.BMPLoader Import BRL.PNGLoader Import BRL.Random Const filtering_near:Int = 0 Const filtering_linear:Int = 1 Const filtering_mipmapped:Int = 2 Const format_bmp:Int = 0 Const format_png:Int = 1 Global resX:Int = 640, resY:Int = 480 AppTitle = "NEHE 11 Flag effect + metaballs. Press SPACE to change colors" SetGraphicsDriver GLGraphicsDriver() Local neheTut:nehe = New nehe Local mbs:TMetaballSystem = TMetaballSystem.Create( neheTut ) While Not KeyHit(key_escape) mbs.updateMeta() neheTut.glDraw() If MouseDown(1) Then neheTut.xrot:+3 If KeyHit(KEY_SPACE) Then mbs.rgbColors = Not mbs.rgbColors Flip Delay 16 Wend EndGraphics() End Type NEHE Field fullscreen:Int = 0 Field flagsize:Int = 100 Field xrot:Float = 0.0 Field yrot:Float = 0.0 Field zrot:Float = 0.0 Field texture:Int[1] Field points:Float[flagsize,flagsize,3] Field wiggle_count:Int = 0 Field colorArrayRed:Float[flagsize,flagsize] Field colorArrayGreen:Float[flagsize,flagsize] Field colorArrayBlue:Float[flagsize,flagsize] Method New() Self.CreateGLWindow(False) If Not Self.InitGLContext() Notify "InitGLContext returned :(" End EndIf Self.OnSizeChange() End Method Method LoadGLTextures:Int() Local img:TPixmap = LoadPixmap("tim.bmp") If img = Null Return False glGenTextures(1, texture); ' generate texture name for 1 tex setupTexture(0, img, filtering_near, format_bmp) img = Null Return True End Method Method InitGLContext:Int() 'If Not LoadGLTextures() Then Return False glEnable(GL_TEXTURE_2D) glShadeModel(GL_SMOOTH); glClearColor (0.0, 0.0, 0.0, 0.5); glClearDepth(1.0); 'depth buffer setup glDepthFunc(GL_LEQUAL) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 'nice perspective calculations glPolygonMode( GL_BACK, GL_FILL ); 'Back Face Is Filled In glPolygonMode( GL_FRONT, GL_LINE ); 'Front Face Is Drawn With Lines Local x:Int For x = 0 Until flagsize Local y:Int For y = 0 Until flagsize points[x,y,0] =Float( (x/5.0)-4.5) points[x,y,1] =Float( (y/5.0)-4.5) 'points[x,y,2] =Float(Sin((((x/5.0)*40.0)/360.0)*3.141592654*2.0)); 'blitzmax uses degrees, not radians: points[x,y,2] =Float(Sin((((x/5.0)*40.0))*2.0)); Next Next Return True End Method Method glDraw() Local x:Int 'loop variables Local y:Int Local float_x:Float 'used to break flag into tiny quads Local float_y:Float Local float_xb:Float Local float_yb:Float glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity() glTranslatef(-7.0, -7.0, -35.0) glRotatef(xrot, 1.0, 0.0, 0.0) glRotatef(yrot, 0.0, 1.0, 0.0) glRotatef(zrot, 0.0, 0.0, 1.0) glBindTexture(GL_TEXTURE_2D, texture[0]) ' defines the texture glBegin(GL_QUADS) For x=0 Until flagsize-1 For y=0 Until flagsize-1 float_x = Float(x)/flagsize; 'Create A Floating Point X Value float_y = Float(y)/flagsize; 'Create A Floating Point Y Value float_xb = Float(x+1)/flagsize; 'Create A Floating Point Y Value+0.0227f float_yb = Float(y+1)/flagsize; 'Create A Floating Point Y Value+0.0227f 'glTexCoord2f( float_x, float_y); ' First Texture Coordinate (Bottom Left) glColor3f( colorArrayRed[x,y],colorArrayGreen[x,y],colorArrayBlue[x,y]) glVertex3f( points[x,y,0], points[x,y,1], points[x,y,2] ); 'glTexCoord2f( float_x, float_yb ); ' Second Texture Coordinate (Top Left) glVertex3f( points[x,y+1,0], points[x,y+1,1], points[x,y+1,2] ); 'glTexCoord2f( float_xb, float_yb ); ' Third Texture Coordinate (Top Right) glVertex3f( points[x+1,y+1,0], points[x+1,y+1,1], points[x+1,y+1,2] ); 'glTexCoord2f( float_xb, float_y ); ' Fourth Texture Coordinate (Bottom Right) glVertex3f( points[x+1,y,0], points[x+1,y,1], points[x+1,y,2] ) Next Next glEnd() If wiggle_count = 2 For y=0 Until flagsize-1 Local hold:Float = points[0,y,2] For x=0 Until flagsize-1 points[x,y,2] = points[x+1, y, 2] Next points[flagsize-1,y,2] = hold 'lsat value becomes the far left stored val Next wiggle_count = 0 'set counter back to zero EndIf wiggle_count:+1 End Method Method OnSizeChange() glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45.0, Double(resX)/ Double(resY), 0.1, 100.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() End Method 'textureNumber in texture name array 'image, png or bmp 'filteringMethod (near, linear, mipmapped 'imageFormat, png or bmp Method setupTexture(textureNumber:Int, image:TPixmap, filteringMethod:Int, imageFormat:Int ) 'glBindTexture(GL_TEXTURE_2D, texture[textureNumber]); 'bind named texture to texture target 'actually generate texture If imageFormat = format_bmp glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, image.pixels) Else If imageFormat = format_png glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, image.pixels) EndIf 'filter texture If filteringMethod = filtering_near glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); Else If filteringMethod = filtering_linear glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) Else If filteringMethod = filtering_mipmapped glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); If imageFormat = format_bmp gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, image.width, image.height, GL_BGR_EXT, GL_UNSIGNED_BYTE, image.pixels) Else If imageFormat = format_png gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, image.width, image.height, GL_RGB, GL_UNSIGNED_BYTE, image.pixels) EndIf EndIf End Method Function CreateGLWindow(fullscreen:Int) If fullscreen 'not done EndIf GLGraphics( resX, resY, 0, 0 ) End Function Method SetArrayColor(x:Int ,y:Int , r:Float, g:Float, b:Float) If x > flagsize-1 Or y > flagsize-1 Then Return If x < 0 Or y < 0 Then Return colorArrayRed[x,y] = r colorArrayGreen[x,y] = g colorArrayBlue[x,y] = b End Method End Type Type TMetaballSystem Field neheGraphics:NEHE Field xscreen:Int Field yscreen:Int Field squareDistance:Int = True 'if true then dist=(x*x) else dist=sqr(x*x) Field meta1x:Int = 0 'mouse position updated in main loop Field meta1y:Int = 0 Field meta2x:Float Field meta2y:Float Field meta3x:Float Field meta3y:Float Field potential1:Float = 0.00005 Field potential2:Float = 0.00005 Field potential3:Float = 0.00005 Field rgbColors:Int = True Function Create:TMetaballSystem( neheGraphics:NEHE ) Local tmp:TMetaballSystem = New TMetaballSystem tmp.neheGraphics=neheGraphics tmp.xscreen = neheGraphics.flagsize tmp.yscreen = neheGraphics.flagsize tmp.meta2x = neheGraphics.flagsize/2 tmp.meta2y = neheGraphics.flagsize/2 tmp.meta3x = neheGraphics.flagsize/2 tmp.meta3y = neheGraphics.flagsize/3 Return tmp End Function Method UpdateMeta() Local x:Int Local y:Int Local meta1x:Int = MouseX() Mod xscreen Local meta1y:Int = yscreen -MouseY() Mod yscreen Local pixelX:Int Local pixelY:Int Local threshold:Float 'for hver pixel på skjermen 'gå igjennom alle andre og beregn kraften fra dem For pixelX=0 Until xscreen+1 For pixelY=0 Until yscreen+1 Local dist1:Float Local dist2:Float Local dist3:Float If(squareDistance) dist1 =(pixelX-meta1x)*(pixelX-meta1x) + (pixelY-meta1y)*(pixelY-meta1y) dist2 =(pixelX-meta2x)*(pixelX-meta2x) + (pixelY-meta2y)*(pixelY-meta2y) dist3 =(pixelX-meta3x)*(pixelX-meta3x) + (pixelY-meta3y)*(pixelY-meta3y) Else 'real distance dist1 = Sqr( (pixelX - meta1x)*(pixelX - meta1x) + (pixelY - meta1y)*(pixelY - meta1y) ) dist2 = Sqr( (pixelX - meta2x)*(pixelX - meta2x) + (pixelY - meta2y)*(pixelY - meta2y) ) dist3 = Sqr( (pixelX - meta3x)*(pixelX - meta3x) + (pixelY - meta3y)*(pixelY - meta3y) ) EndIf If(squareDistance) threshold = 0.0000000003 Else 'real distance threshold = 0.0000003 EndIf Local force1:Float = 1/(dist1*dist1) Local force2:Float = 1/(dist2*dist2) Local force3:Float = 1/(dist3*dist3) Local sumOfForces:Float = force1*potential1 + force2*potential2 + force3*potential3 If(sumOfForces > threshold) If rgbColors neheGraphics.SetArrayColor(pixelX, pixelY, Float(dist1)/1000,Float(dist2)/1000, Float(dist3)/1000) Else neheGraphics.SetArrayColor(pixelX, pixelY, 0,1,0) EndIf Else 'If(sumOfForces < threshold*potential1) 'potential 1 is expected to be negative neheGraphics.SetArrayColor(pixelX, pixelY, .05,.05,.05) EndIf Next Next ' plot a pixel at metaballs center neheGraphics.SetArrayColor meta1x, meta1y, 1,1,1 neheGraphics.SetArrayColor meta2x, meta2y, 1,1,1 neheGraphics.SetArrayColor meta3x, meta3y, 1,1,1 meta2x :+0.5 If(meta2x > xscreen) Then meta2x = 0 meta3x :-0.5 If(meta3x < 0) Then meta3x = xscreen End Method End Type