View Full Version : VB6 + Pointers + OpenGL

06-14-2004, 04:57 PM
Hello, first i shall explain my circumstances. First, i know that visual basic 6 isn't the best choice for openGL :p 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 :p anyway, check out this website for the code + Library.

06-14-2004, 07:54 PM
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.

06-15-2004, 01:30 AM
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 :) 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 :p 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

06-16-2004, 03:04 AM
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 :p ) 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.

06-16-2004, 06:25 AM
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
all my drawings are here

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

06-21-2004, 05:37 PM
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?

06-23-2004, 09:07 AM
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