I'm still trying to get a grasp of using textures and now I'm trying to use glTexCoordPointer in order to give each vertex a color specific to it's class. I've made some checks and here is the situation:
self.bufferVertices = glGenBuffersARB(1)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(vertices), ADT.voidDataPointer(vertices), GL_STATIC_DRAW_ARB)
self.vertices = vertices
self.bufferNormals = glGenBuffersARB(1)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(normals), ADT.voidDataPointer(normals), GL_STATIC_DRAW_ARB)
self.normals = normals
self.triangles = triangles
textureIndexes = []
for int in areas:
textureIndexes.append(float(int)/190.0)
print str(int) + " " + str(float(int)/190)
print str(len(self.vertices)) + str(len(textureIndexes))
self.bufferTextureIndex = glGenBuffersARB(1)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferTextureIndex)
glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(numpy.array(textureIndexes,dtype=numpy.float32)), ADT.voidDataPointer(numpy.array(textureIndexes,dtype=numpy.float32)), GL_STATIC_DRAW_ARB)
for color in textureArray:
print str(color)
self.texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_1D, self.texture)
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 190, 0, GL_RGB , GL_FLOAT, textureArray)
So I generate my VBO's for vertices, normals, triangles and textureIndexes. Now I wanted to check the value I'm getting for textureIndexes, all are from the interval [0..1] and the length of textureIndexes = length ( vertices ) / 3.
For the texture, I generate a textureArray which is a vector of 190 [x,x,x] rgb values. I've even split it in 6 equal parts. So the first 1/6 entries are one color the next another and so on just to simplify my testing.
Now for the drawing:
glEnableClientState(GL_VERTEX_ARRAY)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
glVertexPointer(3, GL_FLOAT, 0, None)
glEnableClientState(GL_NORMAL_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
glNormalPointer(GL_FLOAT, 0, None)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferTextureIndex)
glTexCoordPointer(1, GL_FLOAT, 0, None);
glBindTexture(GL_TEXTURE_1D, self.texture)
glEnable(GL_TEXTURE_1D)
glClientActiveTexture(GL_TEXTURE0);
glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, ADT.voidDataPointer(self.triangles))
But all the points are turning out the same color, corresponding to the color of the first 1/6 part of my texture. Any input would be really appreciated.
I'm surprised it is drawing anything at all. On the following line there is a mistake:
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 190, 0, GL_RGB , GL_FLOAT, textureArray)
The OpenGL spec requires that the size of the texture is a power of two. If you replace the 190 with a 256 or a 64, you may get better results.
Related
I'm new to OpenGL and I want it to display the frames that I get from my camera in the background of the window. Therefore I created a quad, converted the frame to a texture and I'm trying to set it as a texture for my quad but I can't seem to find the right way. I tried doing the same like described on opengl-tutorial.org in tutorial 5. I'm using Python => PyOpenGL and the python scripts from https://github.com/Jerdak/opengl_tutorials_python/ worked.
But when I try to combine that with the scripts from https://rdmilligan.wordpress.com/2016/04/15/display-video-using-opengl/ where he converts the camera frame to a texture, I can't make it work.
Here is my code,at the moment it would simply display a coloured cube in front of a coloured quad, but the quad should have a texture on it:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(program_id)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
...
mvp = ProjectionMatrix * ViewMatrix * ModelMatrix
glUniformMatrix4fv(cube_matrix_id, 1, GL_FALSE, mvp.data)
# 1rst attribute buffer : vertices
glEnableVertexAttribArray(0)
glBindBuffer(GL_ARRAY_BUFFER, cube_vertex_buffer)
glVertexAttribPointer(
0, # attribute 0. No particular reason for 0, but must match the layout in the shader.
3, # len(vertex_data)
GL_FLOAT, # type
GL_FALSE, # ormalized?
0, # stride
null # array buffer offset (c_type == void*)
)
# 2nd attribute buffer : colors
glEnableVertexAttribArray(1)
glBindBuffer(GL_ARRAY_BUFFER, cube_color_buffer)
glVertexAttribPointer(
1, # attribute 0. No particular reason for 0, but must match the layout in the shader.
3, # len(vertex_data)
GL_FLOAT, # type
GL_FALSE, # normalized?
0, # stride
null # array buffer offset (c_type == void*)
)
# Draw the triangles !
glDrawArrays(GL_TRIANGLES, 0, 12 * 3) # 3 indices starting at 0 -> 1 triangle
# Not strictly necessary because we only have
glDisableVertexAttribArray(0)
glDisableVertexAttribArray(1)
# ----------------------------------------------------------------------------------------------------------------
# Draw Background
array_type = GLfloat * len(background_vertex_data)
glBindBuffer(GL_ARRAY_BUFFER, background_vertex_buffer)
glBufferData(GL_ARRAY_BUFFER, len(background_vertex_data) * 4, array_type(*background_vertex_data), GL_STATIC_DRAW)
array_type = GLfloat * len(background_color_data)
glBindBuffer(GL_ARRAY_BUFFER, background_color_buffer)
glBufferData(GL_ARRAY_BUFFER, len(background_color_data) * 4, array_type(*background_color_data), GL_STATIC_DRAW)
ViewMatrix = np.identity(4)
ModelMatrix = np.identity(4)
mvp = ProjectionMatrix * ViewMatrix * ModelMatrix
glUniformMatrix4fv(background_matrix_id, 1, GL_FALSE, mvp.data)
# Turning a Videostream in a Texture --------------------------
# convert image to OpenGL texture format
tx_image = cv2.flip(left_frame, 0)
tx_image = Image.fromarray(tx_image)
ix = tx_image.size[0]
iy = tx_image.size[1]
tx_image = tx_image.tobytes('raw', 'RGBX', 0, -1) # BGRX
# tx_image = np.asarray(tx_image)
# create texture
texture_id = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture_id)
# glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
# Filtering and mipmapping of the model
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx_image)
# glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ix, iy, 0, GL_RGB, GL_UNSIGNED_BYTE, tx_image)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ix, iy, 0, GL_RGB, GL_UNSIGNED_BYTE, tx_image)
# Generate mipmaps
glGenerateMipmap(GL_TEXTURE_2D)
# glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_BGRA, GL_UNSIGNED_BYTE, tx_image)
# ----------------------------------------------------------
# 1rst attribute buffer : vertices
glEnableVertexAttribArray(0)
glBindBuffer(GL_ARRAY_BUFFER, background_vertex_buffer)
glVertexAttribPointer(
0, # attribute 0. No particular reason for 0, but must match the layout in the shader.
3, # len(vertex_data)
GL_FLOAT, # type
GL_FALSE, # ormalized?
0, # stride
null # array buffer offset (c_type == void*)
)
# 2nd attribute buffer : colors
glEnableVertexAttribArray(1)
glBindBuffer(GL_ARRAY_BUFFER, background_color_buffer)
glVertexAttribPointer(
1, # attribute 0. No particular reason for 0, but must match the layout in the shader.
2, # len(vertex_data)
GL_FLOAT, # type
GL_FALSE, # normalized?
0, # stride
null # array buffer offset (c_type == void*)
)
# Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 12 * 3) # 3 indices starting at 0 -> 1 triangle
# Not strictly necessary because we only have
glDisableVertexAttribArray(0)
glDisableVertexAttribArray(1)
# Swap front and back buffers
glfw.swap_buffers(window)
# Poll for and process events
glfw.poll_events()
I'm still a big rookie and I'd appreciate any kind of advice on
structuring the code too.
I am having an issue with implementing a frame buffer for post processing. So far I can draw everything to a textured quad and a apply a shader to change the screen, so in that respect it works.
My issue is when I move my models or camera, the model start to render incorrectly and parts of them get "cut off". See the following screen shots as it is hard to explain.
To avoid putting pages and pages of code, all the rendering works fine without the Frame Buffer and every looks fine if I don't move the camera or models.
I set up the frame buffer like this.
//Set up FBO
glGenFramebuffers(1, &m_FrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBuffer);
glActiveTexture(GL_TEXTURE2);
glGenTextures(1, &m_TexColorBuffer);
glBindTexture(GL_TEXTURE_2D, m_TexColorBuffer);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB, 1280, 720, 0, GL_RGB, GL_UNSIGNED_BYTE, 0
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TexColorBuffer, 0
);
glGenRenderbuffers(1, &m_RBODepthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, m_RBODepthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1280, 720);
glFramebufferRenderbuffer(
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_RBODepthStencil
);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_TexColorBuffer, 0);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "Frame Buffer: Contructor: Issue completing frame buffer" << std::endl;
//Set Up Shader
m_ScreenShader = new Shader("../Assets/Shaders/screen.vert", "../Assets/Shaders/screen.frag");
//Setup Quad VAO
glGenBuffers(1, &m_QuadVBO);
glBindBuffer(GL_ARRAY_BUFFER, m_QuadVBO);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), points, GL_STATIC_DRAW);
glGenVertexArrays(1, &m_QuadVAO);
glBindVertexArray(m_QuadVAO);
//glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, m_QuadVBO);
//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
GLint posAttrib = glGetAttribLocation(m_ScreenShader->getID(), "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
GLint texAttrib = glGetAttribLocation(m_ScreenShader->getID(), "texcoord");
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
I then Bind it prior to drawing the scene (skybox and models) and then draw it like this.
Unbind();
glBindVertexArray(m_QuadVAO);
glDisable(GL_DEPTH_TEST);
m_ScreenShader->enable();
m_ScreenShader->setUniform1f("time", glfwGetTime());
GLint baseImageLoc = glGetUniformLocation(m_ScreenShader->getID(), "texFramebuffer");
glUniform1i(baseImageLoc, 2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, m_TexColorBuffer);
glDrawArrays(GL_TRIANGLES, 0, 6);
Any help is appreciated!
When rendering into a framebuffer that has a depth buffer and the depth test is enabled, then the depth buffer must be cleared. The depth buffer must be cleared after binding the framebuffer and before drawing to the framebuffer:
gllBindFramebuffer( GL_FRAMEBUFFER, m_FrameBuffer );
glClear( GL_DEPTH_BUFFER_BIT );
Note, if you do not clear the deep buffer, it retains its content. This causes that the depth test may fail at positions, where the geometry has been in the past. It follows that parts are missing in the geometry, as in the image in the question.
Here is my problem : I would like to render 2 images offscreen (which come from previous rendering) and then blend them together with a special algorithm. My first image/texture is RGB and the second one is in grayscale, so I only got the luminance.
I think the best way to achieve my goal is to use Frame Buffer Object. So I create one FBO for the first image, then I associate to that FBO a new texture which will received the rendering output. The texture's format is GL_RGB and it works fine, my first FBO contains the rendering in its texture.
Then I do the same with the second image which its format is GL_LUMINANCE. But in the draw function, when I bind to this FrameBuffer and check the Status I got the error GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT. And if I change the texture to RGB it works.
But for the blending I need to access to the luminance and not the rgb component of my image.
Do you have any solutions?
I'm working with OpenGL ES 3.0 on the imx6q Freescale's SOC.
Here is my code :
1 - Creation of the Frame Buffer Object and texture
glGenFramebuffers(1, &m_uiFrameBufferObject);
glBindFramebuffer(GL_FRAMEBUFFER, m_uiFrameBufferObject);
glGenTextures(1, &m_uiTextureId[1]);
glBindTexture(GL_TEXTURE_2D, m_uiTextureId[1]);
glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, 1280, 960,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_uiTextureId[1], 0);
glDrawBuffers(1, attachments); //GL_COLOR_ATTACHMENT0
Then in the draw function :
glBindFramebuffer(GL_FRAMEBUFFER, m_uiFrameBufferObject);
if( glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT )
{
// I go there
}
glViewport(0, 0, 1280, 960);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(m_ProgCamera.GetHandle());
glVertexAttribPointer(0, 3, GL_FLOAT, 0, 0, vVertices);
glEnableVertexAttribArray(0);
// Bind the color attributes
glVertexAttribPointer(1, 3, GL_FLOAT, 0, 0, g_vertexColors);
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, 0, 0, g_vertexTexCoords);
glEnableVertexAttribArray(2);
// Select Our Texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textureCamera.GetHandle());
glDrawArrays( GL_TRIANGLES, 0, 6 );
// Cleanup
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
Thanks for your time.
GL_LUMINANCE is not a color renderable format in OpenGL ES 3.0. The specification states in Section 4.4.4 (Framebuffer Completeness):
An internal format is color-renderable if it is one of the formats from table
3.12 noted as color-renderable or if it is unsized format RGBA or RGB. No
other formats, including compressed internal formats, are color-renderable.
Since GL_LUMINANCE is not included in this list, it is impossible to render to such a texture. Depending on your needs you could, for example, use GL_R8 instead.
This is the lovely image I keep seeing gDebugger as I attempt to implement shadow maps. For reference I'm using the tutorial at http://fabiensanglard.net/shadowmapping/index.php. I've tried a couple different things with varying results, mostly either an FBO that has flat depth values(no slight variance indicating weird depth ranges) or this awesome guy. I've tried a huge amount of different things but alas, sans complete FBO failure, I mostly come back to this. For reference, here is what gDebugger spits out as my actual depth buffer:
So, with all that in mind, here's my code. Shader code is withheld because I have yet to get something in my FBO that's worth processing.
Here's how I initialize the FBO/Depth tex:
int shadow_width = 1024;
int shadow_height = 1024;
// Try to use a texture depth component
glGenTextures(1, &depth_tex);
glBindTexture(GL_TEXTURE_2D, depth_tex);
// GL_LINEAR does not make sense for depth texture. However, next tutorial shows usage of GL_LINEAR and PCF
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Remove artefact on the edges of the shadowmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
// No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24,
shadow_width, shadow_height, 0, GL_DEPTH_COMPONENT,
GL_FLOAT, 0);
// attach the texture to FBO depth attachment point
glBindTexture(GL_TEXTURE_2D, 0);
// create a framebuffer object
glGenFramebuffers(1, &fbo_id);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
// Instruct openGL that we won't bind a color texture with the currently binded FBO
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D, depth_tex, 0);
// switch back to window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
And here's my render code:
glLoadIdentity();
float lpos[4] = {0,0,0,1};
float lpos3[4] = {5000,-500,5000,1};
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL_FRAMEBUFFER,fbo_id);
glViewport(0, 0, 1024, 1024);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
setup_mats(lpos[0],lpos[1],lpos[2],lpos3[0],lpos3[1],lpos3[2]);
glCullFace(GL_FRONT);
mdlman.render_models(R_STENCIL);
mdlman.render_model(R_STENCIL,1);
set_tex_mat();
glBindFramebuffer(GL_FRAMEBUFFER,0);
glViewport( 0, 0, (GLsizei)800, (GLsizei)600 );
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
this->r_cam->return_LookAt();
gluPerspective(45,800/600,0.5f,2000.0f);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(&r_cam->getProjectionMatrix()[0][0]);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&r_cam->getViewMatrix()[0][0]);
glCullFace(GL_BACK);
mdlman.render_models(R_NORM);
And here's how I draw objects for the FBO:
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER,models.at(mdlid).t_buff);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,models.at(mdlid).i_buff);
glNormalPointer(GL_FLOAT,sizeof(vert),BUFFER_OFFSET(sizeof(GLfloat)*2));
glVertexPointer(3, GL_FLOAT,sizeof(vert),BUFFER_OFFSET(sizeof(GLfloat)*5));
glDrawElements(GL_TRIANGLES,(models.at(mdlid).f_index.size())*3,GL_UNSIGNED_INT,0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
Some closing notes: the depth buffer image from gDebugger IS from the lights POV. My camera is quaternion based and uses matrices aligned with OGL for it's lookAt function(which is used to translate to light position/view.) I can provide the code for that if need be. Everything else is pretty much carbon-copied from the tutorial to make sure that I'm not doing or setting up something stupid.
I'm trying to copy a PBO into a Texture with automipmapping enabled, but it seems only the top level texture is generated (in other words, no mipmapping is occuring).
I'm building a PBO using
//Generate a buffer ID called a PBO (Pixel Buffer Object)
glGenBuffers(1, pbo);
//Make this the current UNPACK buffer
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *pbo);
//Allocate data for the buffer. 4-channel 8-bit image
glBufferData(GL_PIXEL_UNPACK_BUFFER, size_tex_data, NULL, GL_DYNAMIC_COPY);
cudaGLRegisterBufferObject(*pbo);
and I'm buildilng a texture using
// Enable Texturing
glEnable(GL_TEXTURE_2D);
// Generate a texture identifier
glGenTextures(1,textureID);
// Make this the current texture (remember that GL is state-based)
glBindTexture( GL_TEXTURE_2D, *textureID);
// Allocate the texture memory. The last parameter is NULL since we only
// want to allocate memory, not initialize it
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA_FLOAT32_ATI, size_x, size_y, 0,
GL_RGBA, GL_FLOAT, NULL);
// Must set the filter mode, GL_LINEAR enables interpolation when scaling
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
Later in a kernel I modify the PBO using something like:
float4* aryPtr = NULL;
cudaGLMapBufferObject((void**)&aryPtr, *pbo);
//Pixel* gpuPixelsRawPtr = thrust::raw_pointer_cast(&gpuPixels[0]);
//... do some cuda stuff to aryPtr ...
//If we don't unmap the PBO then OpenGL won't be able to use it:
cudaGLUnmapBufferObject(*pbo);
Now, before I draw to the screen using the texture generated above I call:
(note that rtMipmapTex = *textureID above and rtResultPBO = *pbo above)
glEnable(GL_DEPTH);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, rtMipmapTex);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, rtResultPBO);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, canvasSize.x, canvasSize.y, GL_RGBA, GL_FLOAT, NULL);
This all works fine and correctly displays the texture. But, if I change that last line to
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, canvasSize.x, canvasSize.y, GL_RGBA, GL_FLOAT, NULL);
which, as far as I understand, should show me the first level instead of the zeroth level texture in the texture pyramid, I just get a blank white texture.
How do I copy the texture from the PBO in such a way that the auto-mipmapping is triggered?
Thanks.
I was being an idiot. The above code works perfectly, the problem was that
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, canvasSize.x, canvasSize.y, GL_RGBA, GL_FLOAT, NULL);
doesn't select the mipmap level from the texture, it selects it from the pbo, which is not mipmapped. Instead you can display the particular mipmapped level with:
glTexEnvi(GL_TEXTURE_FILTER_CONTROL,GL_TEXTURE_LOD_BIAS, 4);