VB6 + Pointers + OpenGL

Hello, first i shall explain my circumstances. First, i know that visual basic 6 isn’t the best choice for openGL :stuck_out_tongue: but this is my software design and development major project (in year 12) and the teacher said -only- visual basic 6 may be used. I wanted to show off and do something good, Neverwinter nights, one of my favourite games i hear was written in openGL. Also, another contributing factor to me choosing openGL is that one of my other friends choose to do his in directx, i couldn’t use the same thing he did of course . Anyway, back to the problem, i’ve so far been able to get everything to work - spent alot of time on graphics/forms/rotating and character models for my project. It all looks quite nice.
Then, i decided to finally get around to object selection, this seemed abit advanced at first, and there weren’t any tutorals out there for visual basic 6 (i was using nehe at the time mainly though). Slapping this off at people just prefuring C/C++ over VB6 for the more advanced stuff i got the C code and converted it accross to VB6 and into my current application. it was this bit of code that didn’t work mainly…

glSelectBuffer 32, selectbuffer
glGetIntegerv glgViewport, ViewPortCoords

glselectbuffer “size as glsizei, buffer as gluint”.

where selectbuffer is an array of size 1 to 32 (code strait from tutorial but in VB6 format). The syntax which pops up automatically once you type glselectbuffer is “size as glsizei, buffer as gluint”. From everything i have read, buffer is a pointer to an array which it will store information in. Unforunatly VB6 doesn’t support pointers AT ALL. ViewPortCoords is also an array of size 1 to 4 and is suposed to be used for the same purpose (it stores the top/bottom/right/left co-ordinates of the viewing area)
now of course i didn’t just run strait to these sorts of forums to ask help of everyone i researched it alot on the net in an attempt to find out how to do it. there are 2 ways i have thought of as to how to get around this. First, borrow the pointer function from a .dll (say c++'s one, use its pointer function) and then subsitute that for the point where its needed. I took a look at how MSDN explained this and was utterly confused, way to high level for me .
2nd way i thought of was to declare the 4 seperate variables that glGetIntegerv obtains seperately, and then use those to determine the new matrix’s size (if this is possible, only a theory). As for the selectbuffer for this idea…don’t know heh.
My original code was tested in my first creation, a menu screen, just to begin with i attempted to get the ‘exit’ button on the menu to actually exit the program.
Its really urgent that i get this problem fixed up as the project will be due soon and i hope those who do try might enjoy the challange!

Sum Up Needs:
Must use VB6
creation of buffer or
use of pointer

if i’ve left anything out, please tell me! need help, will do anything within my power (i don’t want to scrap all those hours of work)

i mentioned NEHE visit this link… http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06 , go to the bottom of the screen and download the ‘visual basic code’ one, this’ll have the library in it.

EDIT: oops, this was original a post in another forum (its hard trying to find solution to this) and i basically copy/pasted it, but the ‘attachment’ bit makes no sense :stuck_out_tongue: anyway, check out this website for the code + Library.

trust me, help on VB6 and opengl is misreble out ther. but once u get a hang of it, its not that bad. anywayz, addressin ur problem

u need to pass just the first element in ur array.

suppose intViewport(3) is ur array, then u need to say intViewport(0), whereever a pointer is needed.

Mithun, i tried as you said heh, and it didn’t seem to work still…everything just froze when i clicked the button and then VB crashed on me :slight_smile: Lol

anyway, it might just be errors in the code instead, reckon you could have a quick look at it? (or someone else), the main section i’m looking at is under ‘retrieveobjectid’ function.

oh yea and sorry about the horrible amount of variables -_-’ i was trying a bunch of stuff and didn’t clean it up much.

EDIT: well, i read what you said agian and tried it properly this time :stuck_out_tongue: didn’t do it right last time…sure it clicks fine, but the area which it seems to be taking out to confine where it looks isn’t working, it should pick up ‘chicken’(the id) when clicking on the button

Ok, i finally found time to post the actual code i want looekd at, figured you people would find that abit easier then downloading that file an’ all, anyway.

 Public Function RetrieveObjectID(x As Single, y As Single, ByVal Width As GLsizei, ByVal Height As GLsizei) As GLuint
Dim ObjectsFound As Integer
Dim ViewPortCoords(1 To 4) As GLint
Dim selectbuffer(1 To 32) As GLuint
Dim selectedObject As GLuint
Dim i As Integer
Dim lowestdepth As Integer

ObjectsFound = 0

glSelectBuffer 32, selectbuffer(1)
glGetIntegerv glgViewport, ViewPortCoords(1)

glRenderMode GL_SELECT
gluPickMatrix x, ViewPortCoords(3) - y, 2, 2, ViewPortCoords(1)
gluPerspective 45#, Width / Height, 0.1, 100#
ObjectsFound = glRenderMode(GL_RENDER)
glMatrixMode (GL_PROJECTION)


If ObjectsFound > 0 Then
    lowestdepth = selectbuffer(1)
    selectedObject = selectbuffer(3)
    For i = 1 To ObjectsFound
        If (selectbuffer((i * 4) + 1) < lowestdepth) Then
         lowestdepth = selectbuffer((i * 4) + 1)
         selectedObject = selectbuffer((i * 4) + 3)
     End If
    Next i
    RetrieveObjectID = selectedObject
End If

End Function 

thats the function which is called when the mouse is clicked, it makes a box around where it was clicked and finds what objects names are in that box, then makes selectedobject equal to the name (this is my interpretation :stuck_out_tongue: ) next is the mouse down stuff

 Private Sub Form_MouseDown(button As Integer, shift As Integer, x As Single, y As Single)
Dim objectID As GLuint
objectID = RetrieveObjectID(x, y, ScaleWidth, ScaleHeight)
If objectID = chicken Then
Unload FrmMain
End If
End Sub

‘chicken’ is my default variable i write in when testing stuff, lol. anyway, unloading the form also kills the gl window, so yea…don’t know why this isn’t working. Its making the ‘box’ mentioned above encompase the entire screen AND Unload FrmMain doesn’t work at all.

im sorry, but i do not have the time to go over ur code now, but herez my code which works fine for me :

Private Function OpenGLSelect(ByVal dblX As Double, ByVal dblY As Double, ByVal dblXDist As Double, ByVal dblYDist As Double, ByVal intK As Integer, ByVal blnMultiple As Boolean) As Integer

        Dim shtHits As Integer
        Dim lngNameNum As Long
        Dim dblDist As Double
        Dim intI As Integer, intJ As Integer
        Dim intSelectbuffer() As GLint
        Dim viewport(4) As GLint        ' array for viewport
        Dim shtBUFSIZE As Integer
        Dim lngLayerNo As Long
        Dim strShapeName As String
        Dim temp As Boolean

        shtHits = 0
        ReDim intSelectbuffer(1000 * intK)

        'ensure drawing to correct window by setting context
        wglMakeCurrent mlngPic1hDC, mlngWindowcontext

        shtBUFSIZE = UBound(intSelectbuffer)

        glGetIntegerv glgViewport, viewport(0)
        glSelectBuffer shtBUFSIZE, intSelectbuffer(0)

        glRenderMode (GL_SELECT)

        glPushName 0 'intializing the name stack

        'setting the same geomety as for normal view
        glMatrixMode (GL_PROJECTION)
        glPushMatrix 'saving the original matrix


        gluPickMatrix dblX, viewport(3) - dblY, dblXDist, dblYDist, viewport(0)

        'set Camera view, the same for picking as for viewing
        gluPerspective msngFieldOfView, msngAspectRatio, mdblNearField, mdblFarField
        glMatrixMode (GL_MODELVIEW)

        glTranslated 0, 0, -mdblNearField - mdblYmax
        glRotatef msngRoll, 0, 0, 1
        glRotatef msngPitch, 0, 1, 0
        glRotatef msngHeading, 1, 0, 0
        glRotated 90, 1, 0, 0
        'translate to origin
        glTranslated -mdblActualXMin + mdblXmin, -mdblActualYMin + mdblYmin, mdblZmin + (mdblZmax - mdblZmin) / 2
[b] all my drawings are here[/b]

       glMatrixMode (GL_PROJECTION)
       glPopMatrix 'restoring the original matrix
        shtHits = glRenderMode(GL_RENDER)   'hits = objects in hit
       If shtHits < 0 Then
            MsgBox "OVERFLOW!!!!!"
        End If
        If shtHits > 0 Then

            lngNameNum = 0
            dblDist = 4294967295#

            For intI = 0 To shtHits - 1

                    'find nearest
                    If (intSelectbuffer((intI) * 4 + 1) < dblDist) Then
                        dblDist = intSelectbuffer((intI) * 4 + 1)
                        lngNameNum = intSelectbuffer((intI) * 4 + 3)
                    End If

            Next intI
        End If
        If lngNameNum <> 0 Then
            lngLayerNo = Int(lngNameNum / 100001)
            MsgBox mvarLayers.Item(lngLayerNo).Shapes.Item(lngNameNum - lngLayerNo * 100001).Name

        End If
        OpenGLSelect = shtHits

End Function

um, unforunatly i couldn’t take much from that code for me to use in my program. i.e. i didn’t know when to call it, how it returns stuff liek that, still relatively at VB6 newb i supose.

also, with the ‘on mouse down’ sub, it takes the coordinates of the click as single? but in the retrieve object it uses doubles - how do i go about A) getting around this or B) changing it to single?

Private Sub picOpengl_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim intI As Integer

If mblnSelection = True Then
    intI = OpenGLSelect(CDbl(msngMouseX), CDbl(msngMouseY), 5, 5, 1, False)
    mblnSceneChanged = True
End If

End Sub