I was finding the relationship between glActiveTexture(...) and glBindTexture(...) and I found an awesome answer here, the very top answer(the author/user Alfonse) gives us a pseudocode for how the both functions behave, and I understood most of it. But, in it he mentions in calls such as this:
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_2D, object);
glTexImage2D(GL_TEXTURE_2D, ...);
but one often binds a texture to the context just to upload some data or to modify it. It doesn’t matter at that point which texture unit you bind it to, so there’s no need to set the current texture unit. glTexImage2D doesn’t care if the current active texture is 0, 1, 40, or whatever.
So my problem is:
when generating two texture we do something like this:
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//some more code
//inside the render loop
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glDrawElements(...); glSwapBuffers();
//end of render loop
Notice, in the code before the render loop, I have used two texture glBindTexture(...) without calling glActiveTexture(...). Since, the default active texture unit is: GL_TEXTURE0, does this mean the parameters set for texture1 is overwritten by texture2?
No, texture parameters (set by glTexParameter) are set for a specific texture (the one that's currently bound to the active texture unit), not for a texture unit (not for one of GL_TEXTUREi, that is).
Note that your use of glTextureParameteri incorrect. Rather than GL_TEXTURE_2D, it expects a handle of a texture, as returned by glGenTextures1. You're confusing it with glTexParameteri, which indeed can be called with GL_TEXTURE_2D.
1 As noted by #derhass, glGenTextures (unlike glCreateTextures) merely reserves the handle. A texture with this handle is created only when you pass it to glBindTexture. It doesn't matter if you use glTexParameter, but if you want to use glTextureParameteri and other functions that operate directly on texture handles, it might be important.
Related
While learning opengl, one bit of confusion is whether it is necessary to bind buffers like VAO
or texture IDs multiple times without unbinding them?
With reference to the above link and the full source code , I have come across 2 scenerios a bit distinct from each other.
First, the author creates a VAO(outside the maindraw loop) and binds the VAO using the glBindVertexArray(VAO) then he doesn't unbind it using glBindVertexArray(0); , but he binds it again in the maindraw loop. My confusion, Is this really necessary? Isn't the currently bound VAO already ... bound? Why bind it when it is already the active VAO?
And,
Second, the author creates texture ID using:
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
//some more code
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
outside the main draw loop , but does this again *inside the main draw loop: *
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
Two things that I don't understand in what he does is:
Why does he bind the texture ID again in the mainloop when he has
done it outside of the mainloop?(This one is similar to VAO but I
don't know yet if unbinding is possible in here)
Why does he select the active texture unit (using glActiveTexture)
inside the loop? Couldn't it be done outside the main draw loop?
glBindTexture binds a texture to specified target and the current texture unit. The current texture unit is set by glActiveTexture. The current texture unit is a global state, and glBindTexture considers that state.
That meas when you do
glBindTexture(GL_TEXTURE_2D, texture1);
glBindTexture(GL_TEXTURE_2D, texture2);
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1);
after that texture2 is bound to the current texture unit (GL_TEXTURE0 by default) and the current texture unit is GL_TEXTURE1. Note texture1
is just bound for a short moment, but the binding is lost, when texture2 is bound.
In compare, when you do
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
The current texture unit is explicitly set to GL_TEXTURE0 and texture1 is bound to texture texture unit 0. After that the current texture unit is switched to GL_TEXTURE1 and texture2 is bound to texture unit 1 (because it is current at this moment).
Note, with the use of Direct State Access and glBindTextureUnit (since OpenGL 4.5) a texture can be bound to a texture unit directly. e.g.:
glBindTextureUnit(GL_TEXTURE0, texture1);
glBindTextureUnit(GL_TEXTURE1, texture2);
I have recently implemented Awesomium into a OpenGL application.
When I load Awesomium in to a texture OpenGL includes it in its shading process regardless of whether I draw the texture onto a surface or not.
I am trying to trace down the line of code that is processing the texture into the shaders, is there a specific function OpenGL uses to access all textures or a way to tell OpenGL to ignore the texture?
Update texture block
glBindTexture(GL_TEXTURE_2D, SkypeHUD);
glTexImage2D(GL_TEXTURE_2D, 0, 4, AwesomiumW, AwesomiumH, 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->buffer());
Create texture block
glBindTexture(GL_TEXTURE_2D, SkypeHUD);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glBindTexture(GL_TEXTURE_2D, 0);
Drawing the scene without the texture being loaded: http://puu.sh/2bVTV
Drawing the scene after I have loaded the texture: http://puu.sh/2bVUb
You can see it blending the google texture in over the others.
Texture enable/disable should be controlled by the shader code, not some client binding state. Anyway, you most likely use several texture units (glActiveTexture); the texture binding is individual to each unit, so you'll have to do some leg work and unbind textures from each unit if you want to go this route.
I'm finding a way to understand why glActiveTexture is needed. I have the code below:
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
If I imagine that the GL_TEXTURE_2D is a picture's frame hanging on the wall and textureId is the real picture, the glBindTexture is the only command for assigning a real picture to the frame, so, what are GL_TEXTURE0 and glActiveTexture?
Will my code below work fine?
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glActiveTexture(GL_TEXTURE1);
glTexImage2D(GL_TEXTURE_2D, .....)
glTexParameteri(GL_TEXTURE_2D, ...)
I'm currently working with OpenGL2.1.
If I imagine that the GL_TEXTURE_2D is a picture's frame hangging on the wall and textureId is the real picture,
Actually a very good analogy :)
so, what GL_TEXTURE0 and glActiveTexture are?
Think about a wall with multiple picture frames, the first frame being labeled GL_TEXTURE0, the second GL_TEXTURE1 and so on.
OpenGL introduced multitexturing at some point (which is basically using more than one texture on one geometry pass); in order to keep older code working, they couldn't just add additional parameter to all the functions. That's why you have to explicitly specify which texture unit you are addressing.
I am looking to bind a new texture to an existing FBO. But at the moment it decreases my speed significantly.
int holdTextureId = glGenTextures();
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, panoramaModelsFboId);
glBindTexture(GL_TEXTURE_2D, holdTextureId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SAVE_WIDTH, SAVE_HEIGHT, 0,GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, holdTextureId, 0);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, panoramaModelsDepthRenderBufferId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, SAVE_WIDTH, SAVE_HEIGHT);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, panoramaModelsDepthRenderBufferId);
//Rendering starts here..
// After which I unbind the FBO and use the texture
I have a feeling glTexImage2D is the perpetrator, so perhaps creating the textures before this process starts is an idea?
Also, I probably don't need to create the renderbuffer each time, but you can save me some time and tell me if it is needed :)
The performance hit lies in the call glTexImage2D which is a very expensive call. If you just want to bind a already existing texture, you don't have to create a new texture object, and also don't need to re-initialize it.
Just calling glFramebufferTexture2D is enough. No need to bind the texture in advance; in fact the texture must not be bound to be used as a framebuffer target.
I want to get the current depth buffer to a texture, to access it in a shader. For various reasons I can't do a separate depth pass, but would need to copy the already-rendered depth.
glReadPixels would involve the CPU and potentially kill performance, and as far as I know glBlitFramebuffer can't blit depth-to-color, only depth-to-depth.
How to do this on the GPU?
The modern way of doing this would be to use a FBO. Attach a color and depth texture to it, render, then disable the FBO and use the textures as inputs to a shader that will render to the default framebuffer.
All the details you need about FBO can be found here.
Copying the depth buffer to a texture is pretty simple. If you have created a new texture that you haven't called glTexImage* on, you can use glCopyTexImage2D. This will copy pixels from the framebuffer to the texture. To copy depth pixels, you use a GL_DEPTH_COMPONENT format. I'd suggest GL_DEPTH_COMPONENT24.
If you have previously created a texture with a depth component format (ie: anytime after the first frame), then you can copy directly into this image data with glCopyTexSubImage2D.
It also seems as though you're having trouble accessing depth component textures in your shader, since you want to copy depth-to-color (which is not allowed). If you are, then that is a problem you should get fixed.
In any case, copying should be the method of last resort. You should use framebuffer objects whenever possible. Just render directly to your texture.
Best way would be using FBOs, for better performance and some coding style issues whatsoever.
If you are not interested take a look at this code. It is from the days when I was much younger!(and didn't know FBOs exist)
int shadowMapWidth = 512;
int shadowMapHeight = 512;
glGenTextures(1, &m_depthTexture);
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512,512);