如何用OpenGL画球体,并将一个位图纹理贴到上面,最好给出源码,并提供注释,本人是OPENGL的初学者,呵呵,谢谢

解决方案 »

  1.   

    你发错了地方吧!
    如果是 DirectX 9 ,偶倒还可以给你点代码。
    OpenGL没用过,也没有相应资料。
      

  2.   

    OpenGL没用过?应该有这个的,C++的源码多一些,VB的就少了,我想要VB的,谁有的?只要能画一个球,光源、纹理用上就行,不需要太复杂的,越简单越好
      

  3.   

    我贴段代码
    module文件:Option Explicit
    Dim hRC As LongSub EnableOpenGL(ghDC As Long)
    Dim pfd As PIXELFORMATDESCRIPTOR
        
        ZeroMemory pfd, Len(pfd)
        pfd.nSize = Len(pfd)
        pfd.nVersion = 1
        pfd.dwFlags = PFD_DRAW_TO_WINDOW Or PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER
        pfd.iPixelType = PFD_TYPE_RGBA
        pfd.cColorBits = 24
        pfd.cDepthBits = 32
        'pfd.cAlphaBits = 24
        pfd.iLayerType = PFD_MAIN_PLANE
        
        PixFormat = ChoosePixelFormat(ghDC, pfd)
        If PixFormat = 0 Then GoTo ee
        SetPixelFormat ghDC, PixFormat, pfd
        hRC = wglCreateContext(ghDC)
        wglMakeCurrent ghDC, hRC
        
    Exit Sub
    ee: MsgBox "Can't create OpenGL context!", vbCritical, "Error"
        End
    End SubSub DisableOpenGL()
        wglMakeCurrent 0, 0
        wglDeleteContext hRC
    End Sub
    Sub loadBMP(Filename As String)
        ' The file should be BMP with pictures 64x64,128x128,256x256 .....
        Dim X As Long, Y As Long, temp As Long
        Dim w As Long, h As Long
        Dim TextureImg() As GLbyte
        Dim bi24BitInfo As BITMAPINFO
        
        If Dir(Filename) = "" Then End
        
        'Loading Picture into PictureBox
        With Stage.Pict
            .Picture = LoadPicture(Filename)
            'with small modifications images can be obtained from resource too
            '.Picture = LoadResPicture(number) and parameter FileName can be removed
            .Refresh
            w = .ScaleWidth
            h = .ScaleHeight
            ' Create the array as needed for the image.
            ReDim TextureImg(2, w - 1, h - 1)
        End With
        
        'Getting data from PictureBox directly
        With bi24BitInfo.bmiHeader
            .biBitCount = 24
            .biCompression = 0 ' BI_RGB
            .biPlanes = 1
            .biSize = Len(bi24BitInfo.bmiHeader)
            .biWidth = w
            .biHeight = h
        End With
        GetDIBits Stage.Pict.hDC, Stage.Pict.Image, 0, h, TextureImg(0, 0, 0), bi24BitInfo, 0
        
        'Swap BGR->RGB
        For X = 0 To w - 1
            For Y = 0 To h - 1
            temp = TextureImg(0, X, Y)
            TextureImg(0, X, Y) = TextureImg(2, X, Y)
            TextureImg(2, X, Y) = temp
            Next Y
        Next X
        
        glPixelStorei GL_UNPACK_ALIGNMENT, 1
        glTexImage2D GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImg(0, 0, 0)
        
        Erase TextureImgEnd SubSub loadRings()
        
        Dim ringsWidth As Long
        
        Open App.Path & "\rings.dat" For Binary As #1
            
            ringsWidth = LOF(1) \ 2   'half of data is alpha info
            ReDim rings((ringsWidth * 2) - 1) As Byte
            Get #1, , rings()
        Close 1    gluBuild2DMipmaps GL_TEXTURE_2D, 4, ringsWidth, 1, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, VarPtr(rings(0))End Sub
      

  4.   

    窗体代码:
    '
    'Author        : Jan Tosovsky
    'Email         : [email protected]
    'Website       : http://nio.astronomy.cz/vb/opengl.html
    'Date          : 28 November 2004
    'Version       : 1.0
    'Description   : Saturn'Rings data were derived from images at:
    'http://www.mmedia.is/~bjj/data/saturn/rings.html'Program requires OpenGL Type Library from Patrice Scribe
    'http://is6.pacific.net.hk/~edx/tlb.htm
    'With library you needn't declare any used OpenGL functions or constants
    'Copy library to system directory and then register it:
    'regsvr32 "C:\Windows\System\vbogl.tlb" where path may vary
    'In Project>References... in VB menu check item VB OpenGL API 1.2 (ANSI)Option ExplicitPrivate Type glVertex
        U As GLfloat
        V As GLfloat
    End TypePrivate Type glCoord
        X As GLfloat
        Y As GLfloat
        Z As GLfloat
    End TypeDim angleX As GLfloat, angleY As GLfloat
    Dim startX As Integer, startY As Integer
    Dim moving As Boolean
    Dim quadObj As Long
    Dim DiskVertex() As glCoord
    Dim Texture(1) As GLuintPrivate Sub Form_Load()
        
        EnableOpenGL Stage.hDC
        'Initial rotation
        angleX = -20
        angleY = -70
        DrawInitEnd SubPrivate Sub DrawInit()
        
        'Uncoment next procedure to take material properties in account
        
        'SetMaterial  'only for demostration of possibilities, not very accurate
        
        SetLight
           
        glClearColor 0#, 0#, 0#, 0#
        glEnable GL_TEXTURE_2D
        glEnable GL_DEPTH_TEST
        glEnable GL_BLEND
        glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
       
        glGenTextures 2, Texture(0)
        glBindTexture GL_TEXTURE_2D, Texture(0)
        glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
        glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
        loadBMP App.Path & "\saturn.jpg"
        'loadBMP App.Path & "\earth.bmp"
        
        glBindTexture GL_TEXTURE_2D, Texture(1)
        glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
        glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
        loadRings
        CalculateDisk
        
        quadObj = gluNewQuadric
        gluQuadricTexture quadObj, GL_TRUEEnd SubSub Render()
        
        glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
        glLoadIdentity    glPushMatrix
            'rotate
            glRotatef angleY, 1#, 0#, 0#
            glRotatef angleX, 0#, 1#, 0#
            'draw planet
            glBindTexture GL_TEXTURE_2D, Texture(0)
            glColor3f 1#, 1#, 1#
            gluSphere quadObj, 0.601, 40#, 40#
            'draw rings
            glBindTexture GL_TEXTURE_2D, Texture(1)
            glColor3f 1#, 0.88, 0.82
            DrawDisk
        glPopMatrix
        
        DoEvents
        SwapBuffers Me.hDCEnd SubPrivate Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If Button = vbLeftButton Then
            moving = True
            startX = X
            startY = Y
        End If
    End SubPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If moving Then
            angleX = angleX + (X - startX)
            angleY = angleY + (Y - startY)
            startX = X
            startY = Y
            Render
        End If
    End SubPrivate Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If Button = vbLeftButton Then moving = False
    End SubPrivate Sub Form_Resize()
        
        Dim w As GLsizei, h As GLsizei
        If Me.WindowState = vbMinimized Then Exit Sub
        
        w = Me.ScaleWidth: h = Me.ScaleHeight
        glViewport 0, 0, w, h
        glMatrixMode GL_PROJECTION
        glLoadIdentity
        
        If w <= h Then
            glOrtho -1.5, 1.5, -1.5 * h / w, 1.5 * h / w, -10#, 10#
        Else
            glOrtho -1.5 * w / h, 1.5 * w / h, -1.5, 1.5, -10#, 10#
        End If
            
        glMatrixMode GL_MODELVIEW
        glLoadIdentity
        DoEvents
        RenderEnd SubPrivate Sub SetLight()
        
        Dim AmbientLight(3) As GLfloat
        Dim DiffuseLight(3) As GLfloat
        Dim LightPos(3) As GLfloat
        Dim SpotDirection(3) As GLfloat
        
        AmbientLight(0) = 1
        AmbientLight(1) = 0.8
        AmbientLight(2) = 0.8
        AmbientLight(3) = 1#
        
        DiffuseLight(0) = 1
        DiffuseLight(1) = 0.8
        DiffuseLight(2) = 0.8
        DiffuseLight(3) = 1#
        
        LightPos(0) = 0#
        LightPos(1) = 0#
        LightPos(2) = 50#
        LightPos(3) = 0#
        
        SpotDirection(0) = 0#
        SpotDirection(1) = -2#
        SpotDirection(2) = -1#
        SpotDirection(3) = 1#
        
        glEnable GL_LIGHT0
        glLightModeli lmTwoSide, GL_TRUE
        glLightfv GL_LIGHT0, GL_POSITION, LightPos(0)
        
        'glLightfv GL_LIGHT0, GL_SPOT_DIRECTION, SpotDirection(0)
        'glLightfv GL_LIGHT0, GL_SPOT_CUTOFF, 60#
        'glLightfv GL_LIGHT0, GL_SPOT_EXPONENT, 10
        'glLightfv GL_LIGHT0, GL_EMISSION, AmbientLight(0)
        'glLightfv GL_LIGHT0, GL_AMBIENT, AmbientLight(0)
        
        glLightfv GL_LIGHT0, GL_DIFFUSE, DiffuseLight(0)
          
        glEnable GL_LIGHTINGEnd SubPrivate Sub SetMaterial()
        
        Dim mat_specular(3) As GLfloat, mat_shininess(0) As GLfloat
        Dim mat_difuse(3) As GLfloat, mat_ambient(3) As GLfloat    mat_specular(0) = 0#
        mat_specular(1) = 0#
        mat_specular(2) = 1#
        mat_specular(3) = 1#
        
        mat_difuse(0) = 0#
        mat_difuse(1) = 0#
        mat_difuse(2) = 0.7
        mat_difuse(3) = 1#
        
        mat_ambient(0) = 0#
        mat_ambient(1) = 0#
        mat_ambient(2) = 1
        mat_ambient(3) = 1#
        
        mat_shininess(0) = 5
        
        glMaterialfv GL_FRONT, GL_SPECULAR, mat_specular(0)
        glMaterialfv GL_FRONT, GL_SHININESS, mat_shininess(0)
        glMaterialfv GL_FRONT, GL_DIFFUSE, mat_difuse(0)
        glMaterialfv GL_FRONT, GL_AMBIENT, mat_ambient(0)
        
        glEnable GL_COLOR_MATERIAL
        
        'glColorMaterial GL_FRONT, GL_AMBIENT_AND_DIFFUSE
     
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        gluDeleteQuadric quadObj
        DisableOpenGL
    End SubSub CalculateDisk()
        
        Dim angle As Long
        Dim radius1 As Double, radius2 As Double
        Dim i As Long, rads As Double
        
        ReDim DiskVertex(180) As glCoord
        
        rads = Atn(1) / 45
        radius1 = 0.744: radius2 = 1.402
        
        For angle = 0 To 360 Step 8
        
            DiskVertex(i).X = radius1 * Sin(rads * (angle - 90)) 'x position
            DiskVertex(i).Y = radius1 * Sin(rads * angle)        'y position
          
            i = i + 1
            DiskVertex(i).X = radius2 * Sin(rads * (angle - 90))
            DiskVertex(i).Y = radius2 * Sin(rads * angle)        i = i + 1
        Next angleEnd SubSub DrawDisk()
        
        Dim i
        For i = 0 To UBound(DiskVertex) - 3 Step 2
            glBegin GL_TRIANGLES
             '1st triange
             glTexCoord2f 0, 0
             glVertex3f DiskVertex(i).X, DiskVertex(i).Y, 0#
             glTexCoord2f 1, 0
             glVertex3f DiskVertex(i + 1).X, DiskVertex(i + 1).Y, 0#
             glTexCoord2f 0, 1
             glVertex3f DiskVertex(i + 2).X, DiskVertex(i + 2).Y, 0#         '2nd triangle
             glTexCoord2f 1, 1
             glVertex3f DiskVertex(i + 3).X, DiskVertex(i + 3).Y, 0#
             glTexCoord2f 0, 1
             glVertex3f DiskVertex(i + 2).X, DiskVertex(i + 2).Y, 0#
             glTexCoord2f 1, 0
             glVertex3f DiskVertex(i + 1).X, DiskVertex(i + 1).Y, 0#
           glEnd
        Next iEnd Sub
      

  5.   

    要引用VB openGL类库:
    http://download.csdn.net/source/221143
      

  6.   

    VB中利用OpenGL绘制三维图:   http://www.builder.com.cn/2007/1015/557159.shtml
      

  7.   

    VBToy:
    Stage 这是一个什么东西啊?
      

  8.   

    谢谢VBTOY了,stage是窗体,我已经知道了得到了这个画土星的源程序了。就是有谁能帮助推荐一下学习OpenGL的书籍,上面的一些函数、参数很是复杂,先在此谢谢了。
      

  9.   

    《OpenGL实用编程指南》很好的,英文版可以在网上搜到。
    http://www.opengl.org/documentation/red_book/
      

  10.   

    上传的redbook,是PDF格式的
    http://download.csdn.net/source/1222043
      

  11.   

    rings.dat 是个什么文件,内容是什么???
    谢谢
      

  12.   


    请问: stage.Pict 是个什么??
      

  13.   

    哦明白了,stage上的图片框控件Pict。文件 rings.dat 不存在,画不出图! 
      

  14.   

    上传了一份完整的源代码,可以用鼠标操作的转动的地球仪。下载地址:http://download.csdn.net/source/1222635
      

  15.   

    谢谢,要是有一本详细的函数讲解的书就好了。看到的例子大多是C++的,VB的太少,而且我想要一些比较简单的例子。从简单入手,方便学习。还有就是要画一个球,还得需要线线代数的知识,许多数学知识都已经不记得了。绘图的语言不熟悉,使用的数学知识也不熟悉,可以说是2头在外,呵呵,学习...
      

  16.   


    问题解决了,结贴吧。请为VBToy 给分!
      

  17.   

    在OpenGL的实际应用中,某种编程语言对于OpenGL来说不是关键,重要的是掌握OpenGL本身,如何利用openGL的gl和glu系列函数建立3D模型。如果掌握了这一点,无论是用C,VC或VB或.net,或其它支持openGL的编程工具都是可以做出OpenGL的应用的。上传的redbook中虽然是用C来讲的,但这并不妨碍对openGL的理解,里面的例子也没有多少C语言的东西,很容易转换成VB的。gl和glu系列函数的详细说明可以在MSDN上查询。
      

  18.   

    请大家注意,我给分了,但是下面这个网站的作者没有得到分,我很伤心。
    我是从 http://nio.astronomy.cz/vb/opengl.html 这里发现更加神奇的东西的。谢谢大家。