Getting the GLuint handle from an ofxVolumetrics instance?

Coming from this thread Texture3D usable in Fragment Shader I have a question (that I ask here, because maybe its too off topic for asking it there): Is it possible, to get the GLuint handle from an ofxVolumetrics instance?

And another basic question for a better understanding: Is the handle of a texture the same as the ID of a texture?

I need the GLuint handle for glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, x, 0, 0, 256, 256); for copying a texture2D into a texture3D (an ofTexture into ofxVolumetrics).

@TimChi explained to me in the other thread how to get the handle if the texture is created in pure openGL and from a regular ofTexture I guess I get the handle like this: texture.getTextureData()?
But how to get a handle from an ofxVolumetrics instance? ofxTexture3d is part of ofxVolumetrics and it has ofxTextureData3d(which holds the texture ID), but not sure how to access it.

Maybe I do not understand something, because I am quite new to pure openGL.

Here is an example that works, but without use of the handle: ofEmscriptenExamples/ofxVolumetricsGPUCopyExample at main · Jonathhhan/ofEmscriptenExamples · GitHub

Hey @Jona I had a peek and the GLunit handle is (probably?) acquired in ofxTexture3d.h, line 29 (from the ofxVolumetrics GitHub page)

glGenTextures(1, (GLuint*)&texData.textureID);

texData is an instance of ofxTextureData3d, which inherits from ofTextureData, which resides in ofTexture.h. ofTextureData I think is all of the stuff that describes an ofTexture, which can be accessed by reference with ofTexture::getTextureData(). Line 29 would store the GLunit for the texture at the address of texData.textureID.

So, maybe try calling .getTextureData().textureID on whatever texture you want to get the uint handle for.

We’re all learning openGL together! So fun! This ofxTexture3d class looks like its worth studying and is probably more complete than what I had posted on the other thread. Hope this helps and post back if it works.

Edit: I think it would be really awesome if you could eventually write another version of ofxTexture3d::loadData() that loads a texture (slice) into the 3d texture without having to get it into an ofPixels object first.

1 Like

Hey @TimChi thanks a lot for your help. I am getting closer.
Of course I will post the result, when I have it (or at least, some progress). Yeah, updating the addon for loading data without pixels would be great. I will think about a solution.

Btw.: Here is an example of an earlier version of my 3D game of live app (that I want to rebuild in a more efficient way): gol 3d 1 - YouTube

Edit: I had another look at the addon, and if I am right I need to modify the ofxVolumetrics class a little, to get the handle from the texture3D that is assigned to the ofxVolumetrics instance.

I made a ofxVolumetrics fork for loading textures (I am sure it can be optimized, but it works - and no need to get the handle anymore): https://github.com/Jonathhhan/ofxVolumetrics/tree/loadTexture

Bind a texture with something like fbo.begin() load it into the volume like
myVolume.updateTexture(0, 0, z, 0, 0, fbo.getWidth(), fbo.getHeight()) and unbind the texture like fbo.end(): https://github.com/Jonathhhan/ofxVolumetrics/blob/loadTexture/ofxVolumetricsGPUCopyExample/src/ofApp.cpp

1 Like

Hey this looks great! I like how you added to the fork, without modifying it (re-writing it) too intensely. I played around with glCopyTexSubImage3D() and the slitscan from the prior thread. Its significantly more efficient. And using an ofFbo is awesome because you can do other stuff at the same time, like draw iteratively, or quickly resize an image, or apply a shader, etc.

ofxTexture3d seems to closely resemble ofTexture, except with different targets and gl calls. But its nice that its usage and design are so similar, especially how it uses ofTextureData to store the handle, target, etc.

I added another method getTextureData() to my ofxVolumetrics fork.
I needed that for setting the texture ID in the shaders.
Its kind of a 3d cellular automata, here is an example video: ofGol3d - YouTube
And here is the code: ofEmscriptenExamples/ofGameOfLife3d at main · Jonathhhan/ofEmscriptenExamples · GitHub
This part of the code is kind of a ping pong buffer for 3d textures (I guess), and was the hardest to figure out (std::swap does not seem to work with a texture3d). The shaderGameOfLifeSlice shader just copies the textures back into the original texture3d:

		fboCellsCopy.begin();
		ofSetRectMode(OF_RECTMODE_CENTER);
		for (int x = 0; x < texture3d.getVolumeDepth(); x++) {
			shaderGameOfLife.begin(); 
			shaderGameOfLife.setUniformTexture("Tex0", GL_TEXTURE_3D, texture3d.getTextureData().textureID, 0);
			shaderGameOfLife.setUniform3f("resolution", texture3d.getVolumeWidth(), texture3d.getVolumeHeight(), texture3d.getVolumeDepth());
			shaderGameOfLife.setUniform2fv("cells", cells, 54);
			shaderGameOfLife.setUniform1i("zCount", x);
			ofClear(0);
			ofDrawRectangle(0, 0, fboCells.getWidth(), fboCells.getHeight());
			texture3dCopy.updateTexture(0, 0, x, 0, 0, fboCells.getWidth(), fboCells.getHeight());
			shaderGameOfLife.end();
		}
		for (int x = 0; x < texture3d.getVolumeDepth(); x++) {
			shaderGameOfLifeSlice.begin();
			shaderGameOfLifeSlice.setUniformTexture("Tex0", GL_TEXTURE_3D, texture3dCopy.getTextureData().textureID, 0);
			shaderGameOfLifeSlice.setUniform3f("resolution", texture3d.getVolumeWidth(), texture3d.getVolumeHeight(), texture3d.getVolumeDepth());
			shaderGameOfLifeSlice.setUniform1i("zCount", x);
			ofClear(0);
			ofDrawRectangle(0, 0, fboCells.getWidth(), fboCells.getHeight());
			texture3d.updateTexture(0, 0, x, 0, 0, fboCells.getWidth(), fboCells.getHeight());
			shaderGameOfLifeSlice.end();
		}
		fboCellsCopy.end();

Here is it with a video mapped to it: ofGol3d 2 - YouTube
ofEmscriptenExamples/ofGameOfLife3d2 at main · Jonathhhan/ofEmscriptenExamples · GitHub

1 Like