07-16-2006, 03:30 AM
This program requires OpenGL 2.0(GLSL) and the GL_VERTEX_PROGRAM_POINT_SIZE_ARB extension to run. You can toggle the shader on/off using the spacebar. It's just a basic example, but hopefully it will get some people started using OpenGL shaders! It's what the big dogs in the industry use, ya know?
Alot more of the program could be done using shaders, but it requires a fragment shader, and that's a little out of the scope of this... tutorial, if you will.
EDIT: program fixed! :lol:
Alot more of the program could be done using shaders, but it requires a fragment shader, and that's a little out of the scope of this... tutorial, if you will.
Code:
Option Explicit
Randomize Timer
'$Static
'$INCLUDE: "\gl\gl.bi"
'$INCLUDE: "\gl\glu.bi"
'$INCLUDE: "\gl\glext.bi"
'$INCLUDE: "\gl\glfw.bi"
Const As Integer True = -1, False = Not True
Type DisplayMode
W As Uinteger
H As Uinteger
R_BITS As Uinteger
G_BITS As Uinteger
B_BITS As Uinteger
A_BITS As Uinteger
D_BITS As Uinteger
S_BITS As Uinteger
MODE As Uinteger
GlVer As Zstring Ptr
As Single FOVy, Aspect, zNear, zFar
End Type
Type Balls
As Single R, G, B
As Single x, Dx, y, Dy, Rad
End Type
Declare Sub Init_GL_Window( Display As DisplayMode )
Declare Sub Set_Ortho( Display As DisplayMode )
Declare Sub Drop_Ortho( Display As DisplayMode )
Declare Sub Init_Balls( Ball() As Balls, Display As DisplayMode)
Const MAX_BALLS As Integer = 25
Dim As Integer Use_Shader = True
Dim Ball(1 To Max_Balls) As Balls
Dim Display As DisplayMode
Init_GL_Window Display
#Define Midx (Display.w \ 2)
#Define Midy (Display.h \ 2)
Dim glCreateShaderObjectARB As PFNglCreateShaderObjectARBPROC = Cptr(PFNGLCREATESHADEROBJECTARBPROC, glfwGetProcAddress( "glCreateShaderObjectARB" ))
Dim glShaderSourceARB As PFNglShaderSourceARBPROC = Cptr(PFNGLSHADERSOURCEARBPROC, glfwGetProcAddress( "glShaderSourceARB" ))
Dim glGetShaderSourceARB As PFNglGetShaderSourceARBPROC = Cptr(PFNGLGetSHADERSOURCEARBPROC, glfwGetProcAddress( "glGetShaderSourceARB" ))
Dim glCompileShaderARB As PFNGLCompileShaderARBPROC = Cptr(PFNglCompileShaderARBPROC, glfwGetProcAddress( "glCompileShaderARB" ))
Dim glDeleteObjectARB As PFNGLDeleteObjectARBPROC = Cptr(PFNglDeleteObjectARBPROC, glfwGetProcAddress( "glDeleteObjectARB" ))
Dim glCreateProgramObjectARB As PFNglCreateProgramObjectARBPROC = Cptr(PFNglCreateProgramObjectARBPROC, glfwGetProcAddress( "glCreateProgramObjectARB" ))
Dim glAttachObjectARB As PFNglAttachObjectARBPROC = Cptr(PFNglAttachObjectARBPROC, glfwGetProcAddress( "glAttachObjectARB" ))
Dim glUseProgramObjectARB As PFNglUseProgramObjectARBPROC = Cptr(PFNglUseProgramObjectARBPROC, glfwGetProcAddress( "glUseProgramObjectARB" ))
Dim glLinkProgramARB As PFNglLinkProgramARBPROC = Cptr(PFNglLinkProgramARBPROC, glfwGetProcAddress( "glLinkProgramARB" ))
Dim glValidateProgramARB As PFNglValidateProgramARBPROC = Cptr(PFNglValidateProgramARBPROC, glfwGetProcAddress( "glValidateProgramARB" ))
Dim glGetObjectParameterivARB As PFNglGetObjectParameterivARBPROC = Cptr(PFNglGetObjectParameterivARBPROC, glfwGetProcAddress( "glGetObjectParameterivARB" ))
Dim glGetInfoLogARB As PFNglGetInfoLogARBPROC = Cptr(PFNglGetInfoLogARBPROC, glfwGetProcAddress( "glGetInfoLogARB" ))
If glfwExtensionSupported( "GL_ARB_shader_objects" ) = 0 Then
Print "Error: ARB shader objects extension not supported."
Sleep 1000
End -1
End If
If( glCreateShaderObjectARB = 0 ) Then
Print "Error: glCreateShaderObjectARB not present."
Sleep 1000
End -1
End If
If( glCreateProgramObjectARB = 0 ) Then
Print "Error: glCreateProgramObjectARB not present."
Sleep 1000
End -1
End If
If( glShaderSourceARB = 0 ) Then
Print "Error: glShaderSourceARB not present."
Sleep 1000
End -1
End If
If( GL_ARB_shading_language_100 = 0 ) Then
Print "Error: This program required GL_ARB_shading_language_100."
Sleep 1000
End -1
End If
Dim As Integer Line_Cnt
Dim As String Shader_Text, tString
Dim As Integer i, x, y, Scale = 8
Dim As Integer Dist
Dim As GlHandleARB Vertex_Shader, Shader_Program
Dim As Gluint Shader_Compile_Success
Read Line_Cnt
For i = 1 To Line_Cnt
Read tString
Shader_Text + = tString + Chr( 13, 10 )
Next
Dim As GLcharARB Ptr table(0) => { Strptr( Shader_Text ) }
Vertex_Shader = glCreateShaderObjectARB( GL_VERTEX_SHADER )
glShaderSourceARB( Vertex_Shader, 1, @table(0), 0 )
glCompileShaderARB( Vertex_Shader )
glGetObjectParameterivARB(Vertex_Shader, GL_OBJECT_COMPILE_STATUS_ARB, @Shader_Compile_Success )
If Shader_Compile_Success = 0 Then
Dim As Gluint infologsize
glGetObjectParameterivARB( Vertex_Shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, @infoLogSize)
Dim As GlByte infolog(InfoLogSize)
glGetInfoLogARB(Vertex_Shader, InfoLogSize, 0, @infoLog(0))
tString=""
For i = 0 To InfoLogSize-1
tString+=Chr(InfoLog(i))
Next
Print "Vertex Shader Infolog error message:"
Print tString
End If
Shader_Program = GlCreateProgramObjectARB()
glAttachObjectARB( Shader_Program, Vertex_Shader )
glLinkProgramARB( Shader_Program )
GlValidateProgramARB( Shader_Program )
glGetObjectParameterivARB( Shader_Program, GL_OBJECT_VALIDATE_STATUS_ARB, @Shader_Compile_Success )
If Shader_Compile_Success = 0 Then
Beep
Print "GLSL program failed to compile!"
Sleep 1000
End If
If GL_VERTEX_PROGRAM_POINT_SIZE_ARB = 0 Then
Beep
Print "GL_VERTEX_PROGRAM_POINT_SIZE_ARB required for program to run correctly!"
Else
GLEnable GL_VERTEX_PROGRAM_POINT_SIZE_ARB
End If
Set_Ortho( Display )
'Drop_Ortho( Display )
Init_Balls( Ball(), Display )
Do
If GlfwGetKey(GLFW_KEY_SPACE) Then
Use_Shader Xor = True
Do While GlfwGetKey(GLFW_KEY_SPACE)
GlfwPollEvents()
Loop
End If
If Use_Shader Then
glUseProgramObjectARB( Shader_Program )
Else
glUseProgramObjectARB( False )
End If
GlClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
For i = 1 To MAX_BALLS
Ball(i).x += Ball(i).dx
Ball(i).y += Ball(i).dy
If Ball(i).x>360 Then
Ball(i).dx -= (1+Rnd*.5)
End If
If Ball(i).x<280 Then
Ball(i).dx += (1+Rnd*.5)
End If
If Ball(i).y>280 Then
Ball(i).dy -= (1+Rnd*.5)
End If
If Ball(i).y<200 Then
Ball(i).dy += (1+Rnd*.5)
End If
Next
GlBegin GL_QUADS
For y = Display.h To Scale Step -Scale
For x = Scale To Display.w Step Scale
Dim As Single R,G,B
Dim As Integer Hits
For i = 1 To MAX_BALLS
Dist = ((y-Ball(i).y)^2 + (x-Ball(i).x)^2)/Ball(i).Rad
If Dist<= Ball(i).Rad Then
R += (Ball(i).Rad-Dist)/Ball(i).R
G += (Ball(i).Rad-Dist)/Ball(i).G
B += (Ball(i).Rad-Dist)/Ball(i).B
Hits-=1
End If
Next
If Hits>0 Then
R/=Hits
G/=Hits
B/=Hits
End If
GlEnable GL_BLEND
GlBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
GlColor4F R, G, B, 0
GlVertex3f X, Y, -Y / 500
GlColor4F R, G, B, 0
GlVertex3f X-Scale, Y, -Y / 500
GlColor4F R, G, B, 0
GlVertex3f X-Scale, Y-Scale, -( Y - Scale ) / 500
GlColor4F R, G, B, 0
GlVertex3f X, Y-Scale, -( Y - Scale ) / 500
Next
Next
GlEnd
GlfwSwapBuffers
Loop Until glfwGetKey( GLFW_KEY_ESC )
GlDeleteObjectArb( Vertex_Shader )
GlDeleteObjectArb( Shader_Program )
GlfwTerminate()
End
Sub Init_Balls( Ball() As Balls, Display As DisplayMode)
Dim As Integer i
For i = 1 To MAX_BALLS
Ball(i).x = 320+Rnd*250
Ball(i).y = 240+Rnd*150
Ball(i).dx = 1+Rnd*10
Ball(i).dy = 1+Rnd*10
If Int(Rnd*10) = 5 Then
Ball(i).dx = -Ball(i).dx
If Int(Rnd*2) = 1 Then Ball(i).dy = -Ball(i).dy
End If
Ball(i).Rad = 64+Rnd*64
Ball(i).R = 64+Int(Rnd*255)
Ball(i).G = 64+Int(Rnd*255)
Ball(i).B = 64+Int(Rnd*255)
Next
End Sub
Sub Set_Ortho( Display As DisplayMode )
GlMatrixMode( Gl_Projection )
GlPushMatrix
GlLoadIdentity
GlMatrixMode( Gl_Modelview )
GlPushMatrix
GlLoadIdentity
GlOrtho( 0, Display.W, 0, Display.H, -1, 1 )
End Sub
Sub Drop_Ortho( Display As DisplayMode )
GlMatrixMode( Gl_Projection )
GlPopMatrix
GlMatrixMode( Gl_Modelview )
GlPopMatrix
End Sub
Sub Init_GL_Window( Display As DisplayMode )
Display.W = 640
Display.H = 480
Display.R_BITS= 8
Display.G_BITS= 8
Display.B_BITS= 8
Display.A_BITS= 8
Display.D_BITS= 24
Display.S_BITS= 8
Display.MODE = GLFW_WINDOW
If glfwInit() Then
'Successful!
Else
Print "Failed to initialize GLFW!"
Sleep 1000
End
End If
If glfwOpenWindow( _
Display.W , _
Display.H , _
Display.R_BITS, _
Display.G_BITS, _
Display.B_BITS, _
Display.A_BITS, _
Display.D_BITS, _
Display.S_BITS, _
Display.MODE ) _
Then
GlfwSwapInterval 1
Display.GlVer = glGetString(GL_VERSION)
Else
GlfwTerminate()
End
End If
'To check, use... glfwGetWindowParam()
' OpenGL specific stuff...
glViewport 0, 0, Display.W, Display.H
glMatrixMode GL_PROJECTION
glLoadIdentity
Display.FOVy = 45.0
Display.Aspect = Display.W / Display.H
Display.znear = 1
Display.zfar = 1000
gluPerspective Display.FOVy, Display.Aspect, Display.zNear, Display.zFar
glShadeModel GL_SMOOTH
glClearColor 0.0, 0.0, 0.0, 0.0
glClearDepth 1.0
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
glEnable GL_COLOR_MATERIAL
glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
glPolygonMode GL_FRONT_AND_BACK, GL_POINT
glEnable GL_CULL_FACE
End Sub
Data 13
Data "void main(void)"
Data "{"
Data "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
Data "vec4 V = gl_ModelViewMatrix * gl_Vertex;"
Data "gl_FrontColor = gl_Color;"
Data "float ptSize = length(V);"
Data "ptSize *= ptSize;"
Data "gl_PointSize = (gl_Color * 10.0);"
Data "if (gl_PointSize || 0 )"
Data "{"
Data "gl_FrontColor = gl_Color * (gl_PointSize/64);"
Data "}"
Data "}"
EDIT: program fixed! :lol: