|
|
作者:Canbitwell
注:vb6的oop太难用,要用也用.net(vb6的结构体不让定义operator,算一个反射公式 R= 2*(-I dot N)*N + I 麻烦死……)
无素材,用小球代替
无引擎引用
Structure vec3
Public x, y, z As Double
Public Sub New(ByVal newX As Double, ByVal newY As Double, ByVal newZ As Double)
x = newX
y = newY
z = newZ
End Sub
Public Shared Operator *(ByVal a As vec3, ByVal b As vec3) As Double
Return a.x * b.x + a.y * b.y + a.z * b.z
End Operator
Public Shared Operator *(ByVal a As vec3, ByVal b As Double) As vec3
Dim ret As vec3
ret.x = a.x * b
ret.y = a.y * b
ret.z = a.z * b
Return ret
End Operator
Public Shared Operator +(ByVal a As vec3, ByVal b As vec3) As vec3
Dim ret As vec3
ret.x = a.x + b.x
ret.y = a.y + b.y
ret.z = a.z + b.z
Return ret
End Operator
Public Shared Operator -(ByVal a As vec3) As vec3
a.x = -a.x
a.y = -a.y
a.z = -a.z
Return a
End Operator
Public Function GetNorm() As vec3
Dim l As Double = Math.Sqrt(x * x + y * y + z * z)
Dim ret As vec3
ret.x = x / l
ret.y = y / l
ret.z = z / l
Return ret
End Function
End Structure
Structure MP
Public x, y, z As Double
Public spd As vec3
Public 这是游戏之家 As Boolean
Public fMass As Double
End Structure
Dim hDC As Integer
Dim hRc As Integer
Dim pos As MP
Dim AmbLight(0 To 3), DiffuseLight(0 To 3), SpclLight(0 To 3), spotDir(0 To 2) As Single
Dim aLightPos(0 To 3) As Single
Dim fogColor(0 To 3) As Single
Const g As Double = -9.8
Dim wind As vec3
Const fMax As Integer = 350
Dim stat As Integer
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
WGL.wglMakeCurrent(hDC, hRc)
WGL.wglDeleteContext(hRc)
WGL.ReleaseDC(Handle.ToInt32, hDC)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AmbLight(0) = 0.4 : AmbLight(1) = 0.4 : AmbLight(2) = 0.4 : AmbLight(3) = 1
DiffuseLight(0) = 0.7 : DiffuseLight(1) = 0.7 : DiffuseLight(2) = 0.7 : DiffuseLight(3) = 1
SpclLight(0) = 1 : SpclLight(1) = 1 : SpclLight(2) = 1 : SpclLight(3) = 1
aLightPos(0) = -50 : aLightPos(2) = 200 : aLightPos(3) = 50 : aLightPos(3) = 1
hDC = WGL.GetDC(Me.Handle.ToInt32)
wglSwapBuffers(hDC)
Dim pfd As PIXELFORMATDESCRIPTOR
pfd.nVersion = 1
pfd.dwFlags = (PFD_DRAW_TO_WINDOW Or PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER)
pfd.iPixelType = (PFD_TYPE_RGBA)
pfd.cColorBits = 32
pfd.cDepthBits = 32
pfd.iLayerType = (PFD_MAIN_PLANE)
pfd.nSize = 40 'Len(pfd)
Dim pm As Integer
Dim ret As UInteger
pm = ChoosePixelFormat(hDC, pfd)
If pm <> 0 Then
If SetPixelFormat(hDC, pm, pfd) <> 0 Then
hRc = wglCreateContext(hDC)
ret = wglMakeCurrent(hDC, hRc)
End If
End If
glShadeModel(GL_SMOOTH)
glClearColor(0.0F, 0.0F, 0.0F, 0.5F)
glClearDepth(1.0F)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glEnable(GL_LIGHTING)
glEnable(GL_FOG)
glEnable(GL_LIGHT0)
GL.glFogf(GL.GL_FOG_DENSITY, 0.003)
GL.glFogi(GL.GL_FOG_MODE, GL.GL_EXP)
GL.glFogfv(GL.GL_FOG_COLOR, fogColor)
pos.y = 5
pos.fMass = 1
pos.这是游戏之家 = True
Dim s As System.Drawing.Size
s = Me.ClientSize
glViewport(0, 0, Size.Width, Size.Height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(50.0, s.Width / s.Height, 0.1, 2500.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
wind.x = -0.02
End Sub
Private Sub SetLights()
'设置0号光源
glLightfv(GL_LIGHT0, GL_AMBIENT, AmbLight) '环境光
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight) '设置漫射光成分
glLightfv(GL_LIGHT0, GL_SPECULAR, SpclLight) '设置镜面光成分
glLightfv(GL_LIGHT0, GL_POSITION, aLightPos) '设置光源的位置
End Sub
Private Sub Phy()
If pos.这是游戏之家 Then
If pos.spd.y < -1 Then pos.spd.y = -1
End If
If pos.y < -4 Then
'pos.spd = (normal * -2) * (spd * normal) + spd
pos.spd = ((New vec3(0, -2, 0)) * (pos.spd * (New vec3(0, 1, 0))) + pos.spd) * 0.5
pos.y = -4
pos.spd.x = 0
pos.spd.z = 0
Else
pos.spd.x += wind.x
pos.spd.x += wind.y
pos.spd.x += wind.y
End If
pos.spd.y += g * 0.02
pos.x += pos.spd.x * 0.02
pos.y += pos.spd.y * 0.02
pos.z += pos.spd.z * 0.02
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
stat += 1
If stat > fMax Then
stat = 0
pos.spd.x = 0
pos.spd.y = 0
pos.spd.z = 0
pos.x = 0
pos.z = 0
pos.y = 5
pos.fMass = 1
pos.这是游戏之家 = Not pos.这是游戏之家
If pos.这是游戏之家 Then
Me.Text = "有降落伞"
Else
Me.Text = "无降落伞"
End If
End If
Phy()
glLoadIdentity()
glClear(Convert.ToUInt32(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT))
glTranslated(0, 0, -25)
glRotated(15, 1, 0, 0)
SetLights()
glPushMatrix()
glTranslated(pos.x, pos.y, pos.z)
DrawSphere(1)
If pos.这是游戏之家 Then
Dim p As vec3
p = -pos.spd.GetNorm * 1.5
p.x = -p.x
p.z = -p.z
glTranslated(p.x, p.y, p.z)
DrawSphere(0.25)
End If
glPopMatrix()
glBegin(GL_QUADS)
glNormal3d(0, 1, 0)
glVertex3d(-9, -5, -9)
glVertex3d(-9, -5, 9)
glVertex3d(9, -5, 9)
glVertex3d(9, -5, -9)
glEnd()
wglSwapBuffers(hDC)
End Sub
Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
Dim s As System.Drawing.Size
s = Me.ClientSize
glViewport(0, 0, Size.Width, Size.Height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(50.0, s.Width / s.Height, 0.1, 2500.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
End Sub
Public Shared Sub DrawSphere(ByVal R As Double)
Dim SpObj As GLUquadric
SpObj = gluNewQuadric()
gluQuadricNormals(SpObj, GLU.GLU_SMOOTH)
gluQuadricTexture(SpObj, GL.GL_TRUE)
gluQuadricOrientation(SpObj, GLU.GLU_OUTSIDE)
gluSphere(SpObj, R, 25, 25)
gluDeleteQuadric(SpObj)
End Sub
程序不停演示两种情况,有/ 无降落伞。
可以看到,有降落伞时由于风力,水平方向加速运动……
注:有降落伞时,大球旁的小球为降落伞位置和方向。
MP结构体的公有bool字段“这是游戏之家”决定降落伞
----------------------------------------------------------------------------------------------------
其他:需要的类(不完全,只把部分OpenGL Api放入):
<Serializable()> _
Public Class GL
Private Const OGLLib As String = "OPENGL32.DLL"
<DllImport(OGLLib)> _
Public Shared Sub glBegin(ByVal mode As UInt32)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glClear(ByVal mask As UInt32)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glClearColor(ByVal red As Single, ByVal green As Single, ByVal blue As Single, ByVal alpha As Single)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glClearDepth(ByVal depth As Double)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glColor3d(ByVal red As Double, ByVal green As Double, ByVal blue As Double)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glDepthFunc(ByVal func As UInt32)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glEnable(ByVal cap As UInt32)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glEnd()
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glFogf(ByVal pname As UInt32, ByVal param As Single)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glFogi(ByVal pname As UInt32, ByVal param As Integer)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glLightf(ByVal light As UInt32, ByVal pname As UInt32, ByVal param As Single)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glLoadIdentity()
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glMatrixMode(ByVal mode As UInt32)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glNormal3d(ByVal nx As Double, ByVal ny As Double, ByVal nz As Double)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glPopMatrix()
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glPushMatrix()
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glRotated(ByVal angle As Double, ByVal x As Double, ByVal y As Double, ByVal z As Double)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glShadeModel(ByVal mode As UInt32)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glTranslated(ByVal x As Double, ByVal y As Double, ByVal z As Double)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glVertex3d(ByVal x As Double, ByVal y As Double, ByVal z As Double)
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glViewport(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer)
End Sub
Public Const GL_AMBIENT As UInt32 = 4608
Public Const GL_COLOR_BUFFER_BIT As UInt32 = 16384
Public Const GL_DEPTH_BUFFER_BIT As UInt32 = 256
Public Const GL_DEPTH_FUNC As UInt32 = 2932
Public Const GL_DEPTH_TEST As UInt32 = 2929
Public Const GL_DIFFUSE As UInt32 = 4609
Public Const GL_EXP As UInt32 = 2048
Public Const GL_FOG As UInt32 = 2912
Public Const GL_FOG_COLOR As UInt32 = 2918
Public Const GL_FOG_DENSITY As UInt32 = 2914
Public Const GL_FOG_MODE As UInt32 = 2917
Public Const GL_LEQUAL As UInt32 = 515
Public Const GL_LIGHT0 As UInt32 = 16384
Public Const GL_LIGHTING As UInt32 = 2896
Public Const GL_MODELVIEW As UInt32 = 5888
Public Const GL_POSITION As UInt32 = 4611
Public Const GL_PROJECTION As UInt32 = 5889
Public Const GL_QUADS As UInt32 = 7
Public Const GL_SMOOTH As UInt32 = 7425
Public Const GL_SPECULAR As UInt32 = 4610
Public Const GL_TRUE As UInt32 = 1
<DllImport(OGLLib)> _
Public Shared Sub glFogfv(ByVal pname As UInt32, ByVal someParams As Single())
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glLightfv(ByVal light As UInt32, ByVal pname As UInt32, ByVal someParams As Single())
End Sub
<DllImport(OGLLib)> _
Public Shared Sub glLightiv(ByVal light As UInt32, ByVal pname As UInt32, ByVal someParams As Integer())
End Sub
End Class
Public Class WGL
Public Const PFD_TYPE_RGBA As UInteger = 0
Public Const PFD_MAIN_PLANE As UInteger = 0
Public Const PFD_DOUBLEBUFFER As UInteger = &H1
Public Const PFD_DRAW_TO_WINDOW As UInteger = &H4
Public Const PFD_SUPPORT_OPENGL As UInteger = &H20
Public Structure PIXELFORMATDESCRIPTOR
Public nSize As UShort
Public nVersion As UShort
Public dwFlags As UInteger
Public iPixelType As Byte
Public cColorBits As Byte
Public cRedBits As Byte
Public cRedShift As Byte
Public cGreenBits As Byte
Public cGreenShift As Byte
Public cBlueBits As Byte
Public cBlueShift As Byte
Public cAlphaBits As Byte
Public cAlphaShift As Byte
Public cAccumBits As Byte
Public cAccumRedBits As Byte
Public cAccumGreenBits As Byte
Public cAccumBlueBits As Byte
Public cAccumAlphaBits As Byte
Public cDepthBits As Byte
Public cStencilBits As Byte
Public cAuxBuffers As Byte
Public iLayerType As Byte
Public bReserved As Byte
Public dwLayerMask As UInteger
Public dwVisibleMask As UInteger
Public dwDamageMask As UInteger
' 40 bytes total
End Structure
Public Declare Function ChoosePixelFormat Lib "gdi32" (ByVal hdc As Integer, ByRef pfd As PIXELFORMATDESCRIPTOR) As Integer
Public Declare Function SetPixelFormat Lib "gdi32" (ByVal hdc As Integer, ByVal pm As Integer, ByRef pfd As PIXELFORMATDESCRIPTOR) As Integer
Public Declare Function wglCreateContext Lib "opengl32" (ByVal dc As Integer) As Integer
Public Declare Function wglMakeCurrent Lib "opengl32" (ByVal hdc As Integer, ByVal hglrc As Integer) As UInteger
Public Declare Function wglDeleteContext Lib "opengl32" (ByVal hglrc As Integer) As Integer
Public Declare Function wglSwapBuffers Lib "opengl32" (ByVal hdc As Integer) As Integer
Public Declare Function GetDC Lib "user32" (ByVal hwnd As Integer) As Integer
Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Integer, ByVal hDC As Integer) As Integer
End Class
Public Class GLU
Const GLULib As String = "GLU32.DLL"
Public Structure GLUquadric
Public data As IntPtr
End Structure
<DllImport(GLULib)> _
Public Shared Function gluNewQuadric() As GLUquadric
End Function
<DllImport(GLULib)> _
Public Shared Sub gluPerspective(ByVal fovy As Double, ByVal aspect As Double, ByVal zNear As Double, ByVal zFar As Double)
End Sub
<DllImport(GLULib)> _
Public Shared Sub gluDeleteQuadric(ByVal quad As GLUquadric)
End Sub
<DllImport(GLULib)> _
Public Shared Sub gluQuadricNormals(ByVal quad As GLUquadric, ByVal normal As UInt32)
End Sub
<DllImport(GLULib)> _
Public Shared Sub gluQuadricOrientation(ByVal quad As GLUquadric, ByVal orientation As UInt32)
End Sub
<DllImport(GLULib)> _
Public Shared Sub gluQuadricTexture(ByVal quad As GLUquadric, ByVal texture As Byte)
End Sub
<DllImport(GLULib)> _
Public Shared Sub gluSphere(ByVal quad As GLUquadric, ByVal radius As Double, ByVal slices As Integer, ByVal stacks As Integer)
End Sub
Public Const GLU_OUTSIDE As UInt32 = 100020
Public Const GLU_SMOOTH As UInt32 = 100000
End Class
|
|