PDA

View Full Version : How do I use Multiple Textures in OpenGL in VB.NET???



Knight Chat X
09-24-2007, 10:40 PM
Anyone know how to do multiple textures in OpenGL using VB.Net and get this to work? All I can find right now on using multiple textures is in C++.

I'm trying to apply multiple textures to geometry and while setting active texture it gives me error:
EntryPointNotFoundException was unhandled.
Unable to find an entry point named 'glActiveTextureARB' in DLL 'opengl32.dll'.

I'm using NEHE Lesson 22 as an example:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=22

Stephen A
09-26-2007, 05:00 PM
You'll need to use a library that supports extensions. I suggest OpenTK (http://opentk.sourceforge.net) or Tao (http://taoframework.com)

Both feature automatic extension loading, so just set them up and write your texturing code as you did in C++.

Knight Chat X
09-26-2007, 10:54 PM
I'm trying to do this without using a 3rd party DLL library solution, I can only find C++ and C# source code samples when converted to VB.NET just isn't working, the function pointers are variables and seem like Delegates, I found this and tried it and not working:
http://www.codeproject.com/vb/net/Delegate.asp

The delegate (function pointer) is supposed to have the function address passed off to the variable using AddressOf, in which you can then call the function/method using the variables name and passing any parameters, optionally using Invoke.

C++ TYPE DEFINITION:

typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum target);Is said to be equivilant to VB.NET's, which defines a type safe, method or function:

Public Delegate Sub PFNGLACTIVETEXTUREARBPROC(ByVal target As Int32)
C++ VARIABLE:

PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL; Is said to be equal to VB.NET's variable declaration like so:

Public Shared glActiveTextureARB As PFNGLACTIVETEXTUREARBPROC = Nothing C++ Assigning Reference to Function/Passing Function Pointer/Function Address to Invokable Variable:


glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");VB.NET Assign Addresses/References to the Function Pointers:

glActiveTextureARB = wglGetProcAddress("glActiveTextureARB") -OR-


glActiveTextureARB = AddressOf <FUNCTION POINTER> See if Multi-Texturing is supported...

If IsNothing(glActiveTextureARB) = True Then MsgBox("Your version of OpenGL does not support multitexturing...", , "Error") VB.NET's Function Usage would be:

glActiveTextureARB(GL_TEXTURE0_ARB)-OR-


glActiveTextureARB.Invoke(GL_TEXTURE0_ARB)2 Other ways to declare the function are:


<Runtime.InteropServices.DllImport("opengl.dll", EntryPoint:="glActiveTextureARB", SetLastError:=True, CharSet:=System.Runtime.InteropServices.CharSet.Un icode, ExactSpelling:=True, CallingConvention:=System.Runtime.InteropServices. CallingConvention.StdCall)> Public Shared Function glActiveTextureARB(ByVal target As Int32) As Long
End Function -OR-


Declare Auto Function glActiveTextureARB Lib "opengl.dll" (ByVal texture As Int32) As Long
One person named Fiddler mentioned
substituting this line:
glActiveTextureARB = wglGetProcAddress("glActiveTextureARB")
With


glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)Marshal.GetDelegateForF unctionPointer(wglGetProcAddress("glActiveTextureARB"), typeof(PFNGLACTIVETEXTUREARBPROC));

Stephen A
09-27-2007, 04:46 AM
That person (Fiddler) actually is me :) Both Tao and OpenTK use this code to load extensions, so it actually works.

'glActiveTextureARB' should be a delegate with the correct signature, i.e:
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;

You cannot load extensions with static DllImports (unless you are willing to post-process the resulting assembly, but that's another story). You'll have to use a delegate. You can call the delegate like this: "glActiveTextureARB(GL_TEXTURE0_ARB)", there's no need to use the Invoke() method.

You could also browse an actual C# implementation (http://opentk.svn.sourceforge.net/viewvc/opentk/trunk/Source/OpenTK/OpenGL/Bindings/) , it shouldn't be too hard to adapt for VB.Net. GLCore.cs contains the 'core' (i.e. non-extension) OpenGL functions, GLDelegates.cs declares the delegates and GL.cs provides overloads for a prettier interface.

One level up, there is a file called GLHelper.cs which does the extension loading (GL.Load() and GL.LoadAll() functions).

EDIT: You cannot use the AddressOf operator in this instance, you have to warp an *unmanaged* function pointer (obtained through wglGetProcAddress) inside a *managed* delegate, hence the need for Marshal.GetDelegateForFunctionPointer.

AFAIK, AddressOf works for *managed* pointers.

Knight Chat X
09-27-2007, 11:08 PM
Yeah I was thinking it needed to be used as a delegate, tried the Marshal.GetDelegateForFunctionPointer and it didn't work. I do notice that wglGetProcAddress, returns a value of 0 which might be the problem, but dunno why it's doing that.

I've tried converting the code over VB.NET and it's not working.

The API Function Declaration is:

Declare Auto Function wglGetProcAddress Lib "opengl32.dll" (ByVal lpcstr As String) As Int32 The PFNGLACTIVETEXTUREARBPROC Delegate:

Public Delegate Sub PFNGLACTIVETEXTUREARBPROC(ByVal texture As Int32)
When Getting the Function Pointer:

Dim glActiveTexture As PFNGLACTIVETEXTUREARBPROC = System.Runtime.InteropServices.Marshal.GetDelegate ForFunctionPointer(wglGetProcAddress("glActiveTextureARB"), GetType(PFNGLACTIVETEXTUREARBPROC))

-OR-

Dim glActiveTexture As [Delegate] = System.Runtime.InteropServices.Marshal.GetDelegate ForFunctionPointer(wglGetProcAddress("glActiveTextureARB"), GetType(PFNGLACTIVETEXTUREARBPROC))

When Used:

glActiveTextureARB(GL_TEXTURE0_ARB) glActiveTextureARB(GL_TEXTURE0_ARB) produces a no-entry point error.

And I know the extensions are supported on my machines because C++ multi-texture source code samples work fine and I run a tool called Realtech VR OpenGL Extension Viewer and shows the multitexture extension and all related functions are supported.

I'll have a look at those files thanks.

Stephen A
09-28-2007, 04:58 AM
When Getting the Function Pointer:

Dim glActiveTexture As PFNGLACTIVETEXTUREARBPROC = System.Runtime.InteropServices.Marshal.GetDelegate ForFunctionPointer(wglGetProcAddress("glActiveTextureARB"), GetType(PFNGLACTIVETEXTUREARBPROC))

-OR-

Dim glActiveTexture As [Delegate] = System.Runtime.InteropServices.Marshal.GetDelegate ForFunctionPointer(wglGetProcAddress("glActiveTextureARB"), GetType(PFNGLACTIVETEXTUREARBPROC))Something like the second one:

Public Delegate Sub PFNGLACTIVETEXTUREARBPROC(ByVal texture As Int32)
Dim glActiveTexture As PFNGLACTIVETEXTUREARBPROC = System.Runtime.InteropServices.Marshal.GetDelegate ForFunctionPointer(wglGetProcAddress("glActiveTextureARB"), GetType(PFNGLACTIVETEXTUREARBPROC))The fact that wglGetProcAddress returns 0 is a *strong* indication that you haven't created an opengl context. You will have to open a window, create a context through wgl functions, and only then will you be able to load and use extensions.

Knight Chat X
09-28-2007, 07:52 PM
The OpenGL window's created, it's rendering normally, I load some test code only during render after the render window's initialized.

I downloaded and ran the binary version of OpenTK 0.3.12 that includes the Examples.exe and ran it and selected Extensions, a list is dumped and nearly all extensions from 584/1528 say failed on the left side of each item.

I reviewed the OpenTK source code and converted the GetProcedure/GetAddress/GetDelegate, etc. and code for partial classes of the Imports/Delegates/Interface/Overides etc.., wglGetProcAddress, focusing on just the wglGetProcAddress and glActiveTextureARB function, and the Loadall and Load, I placed a MessageBox in the load to display the number of extensions successfully loaded and give the name of extension that was set for FieldInfo, it returns the name of the of glActiveTextureARB, so I assume it's loaded, so now how do I call the function?

I've tried using OpenTK.GL.ActiveTexture, and the other displayed method calls directly and that doesn't work.

Here's Picture of what OpenTK examples shows:
http://knight-technologies.us/opentkexamples.jpg

Here's what the OpenGL Extension Viewer Shows for Version Support:
http://knight-technologies.us/openglextensionviewercore.jpg

Here's what the OpenGL Extension Viewer Shows for Extension Brands Supported:
http://knight-technologies.us/openglextensionviewercore2.jpg

OpenGL Extension Viewer Shows the multitexture functionality is supported here glActiveTextureARB is available:
http://knight-technologies.us/openglextensionviewercore3.jpg

This picture shows an OBJ model mesh rendering normally with a single texture and not trying to use an extension which proves the rendering context is valid, otherwise rendering couldn't take place:
http://knight-technologies.us/objmodelmeshrender.jpg

I converted code samples I provided in previous post showing the code I've come accross that is in some samples online that's supposed to work, those samples work fine in C++ and C# but after converted to VB.NET don't seem too for some reason, I tried converting only the relevant functionality for loading extensions as is in the OpenTK even and the result the same, once I call glActiveTexture the same error is produced:
http://knight-technologies.us/entrypointdllerror.jpg

I used a tool called AnalogX TextScan to look inside the binary for function strings, I find wglGetProcAddress is located in the opengl32.dll and opengl.dll files, I looked at another computer that had opengl.dll dated 1997 and it has glActiveTexture in it but wglGetProcAddress was in opengl32.dll

And to prove multi-texturing works I ran the gametutorials.com Multi-Texturing tutorial and it shows fine here:
http://knight-technologies.us/multitexturingworks.jpg

So it seems there's a very specific process to perform in order to get it all to work right, if at all.

Here are the bare OpenTK portions I converted to VB.NET, if I missed anything please let me know, and if I need to take further steps to properly call the function, with the OpenTK class structure I'm not sure:
http://knight-technologies.us/code/GL.vb
http://knight-technologies.us/code/GLCore.vb
http://knight-technologies.us/code/GLDelegates.vb
http://knight-technologies.us/code/GLHelper.vb

Stephen A
09-29-2007, 09:47 AM
Ok, a couple of suggestions: check the output of: " GL.GetString(GL.Enums.StringName.VENDOR); (and StringName.RENDERER)"

If it says "Microsoft GDI", then you are not getting a hardware-accelerated context, and it is natural that the call to ActiveTexture fails. This is what is happening in the first picture you posted (I'll have to find out why).

It's very probable that context creation is the problem (and not the extension loading itself). Your code seems ok, but I didn't have time to check it thoroughly.

In general, you should check if the pixel format you are requesting is supported (try changing your screen to 32bit color depth, the driver might not like it otherwise). It is always a good idea to update your drivers, too. Last, check some C code that works and what is it that's it doing different when creating a context.

I'll try to investigate more when I can find some free time.

EDIT: Also, there is no need to use reflection if you plan to use only a couple of extensions. Just place the calls to Marshal.GetDelegateForFunctionPointer normally inside the GL.LoadAll() function!

Knight Chat X
10-01-2007, 01:50 AM
I had monitor set on 16-bit and changed it to 32-bit and it shows this now:
http://knight-technologies.us/opentkexamples2.jpg

Here's simple C++ example of loading extension:
http://knight-technologies.us/getopenglextensions.cpp

Here's simple VB.NET example of loading extension, but I commented out the typedef because not sure how to fully convert that over, tried both Delegate and Structure declarations, the function call's still fail showing DLL entry point error's:
http://knight-technologies.us/getopenglextensions.vb

Stephen A
10-01-2007, 05:15 AM
Ok, just a couple of changes and your code will work:


typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum target);becomes:


public delegate void PFNGLACTIVETEXTUREARBPROC(int target);and the loading looks like this:

'Get Extensions.
glActiveTextureARB = DirectCast(Marhsal.GetDelegateForFunctionPointer(w glGetProcAddress("glActiveTextureARB"), typeof(PFNGLACTIVETEXTUREARBPROC))) I am not familiar with VB.Net syntax (that DirectCast thing), but as far as I can see there's no reason why this shouldn't work.