可以借助DirectX來(lái)編程。免費(fèi)3D引擎可不好找,一般來(lái)說(shuō)速度比不上硬件加速后的DX,尤其令人頭疼的是一般都沒(méi)有針對(duì)VB的文檔,LZ有這方面理想的話(huà),自己寫(xiě)一個(gè)吧……
創(chuàng)新互聯(lián)專(zhuān)注于企業(yè)成都營(yíng)銷(xiāo)網(wǎng)站建設(shè)、網(wǎng)站重做改版、政和網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5場(chǎng)景定制、商城系統(tǒng)網(wǎng)站開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性?xún)r(jià)比高,為政和等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
我不得不承認(rèn)在VB上寫(xiě)DirectX的教程相當(dāng)難找!如果LZ想深入研究三維圖形問(wèn)題,C++一定要學(xué),就算不能用C++編程,起碼要能把C++程序翻譯成VB程序。
我自己學(xué)會(huì)DX編程花了兩三個(gè)月(很淺)。編這樣一個(gè)程序難度是有點(diǎn)大的。
工具:DirectX9和其針對(duì)VB的庫(kù)(項(xiàng)目-添加引用。.NET庫(kù)里DX庫(kù)一般都有),VB不知道現(xiàn)在支不支持DX10以上的版本,不過(guò)9絕對(duì)夠用了。
思路:一切3D圖形都是由三角形拼成的。矩形挖掉一個(gè)圓孔可不是一個(gè)方便畫(huà)的圖形,我估計(jì)至少得有24個(gè)三角形。你需要記錄這些點(diǎn)的坐標(biāo),或者干脆把它們寫(xiě)在文件里,到時(shí)讀出來(lái)。
這是我的一個(gè)老DX程序的不完全的代碼(顯示一個(gè)黑乎乎的平面),不一定能編譯,可以參考一下。
Imports Microsoft.DirectX '一定要~
Public Class FormMain
'Direct3D Startup
Dim d3dpp As New Direct3D.PresentParameters 'DX基本參數(shù),例如全屏還是窗口等
Public MyDevice As Direct3D.Device ‘DX基本設(shè)備,畫(huà)圖就靠它。
'Matrices
Dim matWorld, matView, matProj As Matrix '世界位置矩陣,攝像機(jī)位置矩陣和透視矩陣,數(shù)學(xué)要學(xué)好啊。
'mesh
Public MyPlane as Direct3D.Mesh ’我們的物體
Public VBPlane(3) As Direct3D.CustomVertex.PositionNormalTextured '存放頂點(diǎn)位置的數(shù)組
#Region "DX Core"
Public Sub InitDeviceObjects()
With d3dpp ‘以下請(qǐng)照抄。
.Windowed = True ‘不全屏。
.SwapEffect = Direct3D.SwapEffect.Discard ’雙緩沖交換效果。請(qǐng)百度“雙緩沖”
.BackBufferFormat = Direct3D.Format.Unknown
.EnableAutoDepthStencil = True ’讓DX自動(dòng)管理深度緩沖
.AutoDepthStencilFormat = Direct3D.DepthFormat.D16
End With
MyDevice = New Direct3D.Device(0, Direct3D.DeviceType.Hardware, Me.Handle, Direct3D.CreateFlags.HardwareVertexProcessing, d3dpp) '創(chuàng)建DX設(shè)備啦!以下兩句請(qǐng)照抄。
MyDevice.SetRenderState(Direct3D.RenderStates.ZEnable, True) ‘Z緩沖
MyDevice.SetRenderState(Direct3D.RenderStates.NormalizeNormals, True)'法線(xiàn)歸一化,請(qǐng)看相關(guān)數(shù)學(xué)書(shū)籍。
End Sub
Public Sub RestoreDeviceObjects()
Dim PlaneIB() As Short = {0, 1, 3, 0, 2, 3} ’頂點(diǎn)索引信息。
Dim AttrTable(1) As Direct3D.AttributeRange ‘頂點(diǎn)分組屬性表
AttrTable(0).AttributeId = 0
AttrTable(0).FaceStart = 0
AttrTable(0).FaceCount = 2 ’有兩個(gè)三角形
AttrTable(0).VertexStart = 0
AttrTable(0).VertexCount = 4 ‘四個(gè)點(diǎn)
‘頂點(diǎn)坐標(biāo)信息。
VBPlane(0) = New Direct3D.CustomVertex.PositionNormalTextured(-500, -500, 0, 0, 0, 1, 0, 0)
VBPlane(1) = New Direct3D.CustomVertex.PositionNormalTextured(500, -500, 0, 0, 0, 1, 1, 0)
VBPlane(2) = New Direct3D.CustomVertex.PositionNormalTextured(-500, 500, 0, 0, 0, 1, 0, 1)
VBPlane(3) = New Direct3D.CustomVertex.PositionNormalTextured(500, 500, 0, 0, 0, 1, 1, 1)
MyPlane = New Direct3D.Mesh(2, 4, Direct3D.MeshFlags.Managed, Direct3D.VertexFormats.Position + Direct3D.VertexFormats.Normal + Direct3D.VertexFormats.Texture1, MyDevice) ’創(chuàng)建物體
MyPlane.SetVertexBufferData(VBPlane, Direct3D.LockFlags.None) ‘輸入頂點(diǎn)坐標(biāo)數(shù)據(jù)
MyPlane.SetIndexBufferData(PlaneIB, Direct3D.LockFlags.None) ‘輸入索引數(shù)據(jù)
MyPlane.SetAttributeTable(AttrTable) ‘輸入頂點(diǎn)分組屬性表
End Sub
Public Sub Render() ‘調(diào)用它畫(huà)圖
Dim vlook As New Vector3(1, 0, 0)
Dim vPos As New Vector3(0,0,0)
Dim vUp As New Vector3(0, 0, 1)
MatView = Matrix.LookAtLH(vPos, vlook, vUp) ‘計(jì)算攝像機(jī)位置矩陣
Device.SetTransform(Direct3D.TransformType.View, MatView) ‘設(shè)置當(dāng)前攝像機(jī)位置矩陣為MatView。
Dim fAspect As Single = Me.Width / Me.Height ’窗口長(zhǎng)寬比
matProj = Matrix.PerspectiveFovLH(Math.PI / 4, fAspect, 1.0F, 10001) ‘計(jì)算透視矩陣MatProj。
MyDevice.SetTransform(Direct3D.TransformType.Projection, matProj) ‘設(shè)置當(dāng)前透視矩陣為MatProj。
MyDevice.Clear(Direct3D.ClearFlags.Target + Direct3D.ClearFlags.ZBuffer, Color.Blue, 1.0F, 0) ’先刷藍(lán)屏
MyDevice.BeginScene() ‘開(kāi)始畫(huà)
MatWorld = Matrix.Identity ’物體位于原點(diǎn),不旋轉(zhuǎn)
Device.SetTransform(Direct3D.TransformType.World, MatWorld) ’設(shè)置物體位置
Me.Mesh.DrawSubset(0) ‘畫(huà)物體
MyDevice.EndScene() ’結(jié)束
MyDevice.Present() ‘顯示在屏幕上
End Sub
Public Sub DeleteDeviceObjects() ’結(jié)束程序時(shí)放掉資源
MyPlane.Dispose()
MyDevice.Dispose()
End Sub
#End Region
Private Sub FormMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
DeleteDeviceObjects()
Windows.Forms.Cursor.Show()
End Sub
Private Sub FormMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
InitDeviceObjects()
RestoreDeviceObjects()
Windows.Forms.Cursor.Hide()
Render()
End Sub
End Class
VB.net與VB不同。
VB.net已經(jīng)有專(zhuān)門(mén)繪圖的類(lèi)。
可以定義筆刷然后用Drawing類(lèi)中的方法繪制。
Private Sub DrawEllipse()
Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Red)
Dim formGraphics as System.Drawing.Graphics
formGraphics = Me.CreateGraphics()
formGraphics.DrawEllipse(myPen, New Rectangle(0,0,200,300))
myPen.Dispose()
formGraphics.Dispose()
End Sub
Private Sub DrawRectangle()
Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Red)
Dim formGraphics as System.Drawing.Graphics
formGraphics = Me.CreateGraphics()
formGraphics.DrawRectangle(myPen, New Rectangle(0,0,200,300))
myPen.Dispose()
formGraphics.Dispose()
End Sub
VB的作用是方便、快捷、簡(jiǎn)單,但是它對(duì)數(shù)據(jù)庫(kù)編程不夠好,需要用到很復(fù)雜的控件,所以適合用來(lái)做小游戲、小軟件。
VB能做幾乎所有類(lèi)型的軟件。
學(xué)校用到的人事管理、師資管理、學(xué)生資料、成績(jī)統(tǒng)計(jì)、考試系統(tǒng)方面的軟件,VB都可以勝任。
繼承(Inherits)控件就可以重寫(xiě)它的屬性和方法,圖標(biāo)可以在paint中重繪,用gdi,工具主要在drawing和drawing2d中。
combobox彈出的框增加圖標(biāo)嗎?個(gè)人看法可能需要得到那個(gè)句柄,才可以重繪,但那個(gè)好像是一體的,不知道能不能弄到句柄。
textbox可以自定義高度。只是以行高度為單位,改變字體大小即可,沒(méi)必要重寫(xiě)吧。
我也自學(xué),感覺(jué)基礎(chǔ)容易學(xué),進(jìn)階資料少。循序漸進(jìn)也沒(méi)序可循,基本是在摸索。
都是想到什么問(wèn)題,就立下一個(gè)目標(biāo),然后攻破他,結(jié)果可能是嘗試幾天后,發(fā)現(xiàn)目標(biāo)超出能力范圍。
晦澀是相對(duì)的,實(shí)踐出真知,多動(dòng)手,基礎(chǔ)就好了。