rendering image in memory only

Started by
6 comments, last by vivendi 12 years, 2 months ago
I've done DirectX, but OpenGL is new to me. I need to do the following, which isn't probably really hard to do.

I need to draw a simple (white) triangle. But not on a window that can be created with Glut -> [size="2"]glutCreateWindow()

[size="2"]To draw a triangle i probably need to do something like this:
[size="2"]
[size="2"][size="2"]glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[size="2"][size="2"]glMatrixMode(GL_MODELVIEW);
[size="2"][size="2"]glLoadIdentity();

[size="2"][size="2"]glBegin(GL_TRIANGLES);

[size="2"][size="2"]glVertex3f(-0.5f, 0.5f, -5.0f);
[size="2"][size="2"]glVertex3f(-1.0f, 1.5f, -5.0f);
[size="2"][size="2"]glVertex3f(-1.5f, 0.5f, -5.0f);

[size="2"][size="2"]glEnd();
[size="2"]


[size="2"]But here's the tricky part. I want this triangle to be placed somewhere on a (black) image which is 640 x 480 in size. But i don't want to display the image on a windows form. I just need to have this data in memory only.

[size="2"]The reason for this is because i'm writing a plugin for a program and i'm gonna use the programs viewport to render my image.

[size="2"]So how can i achieve this? Drawing a triangle on a black 640x480 image, without rendering the actual result to some windows form?
Advertisement
You can render anything you want on a Frame Buffer Object, from which you can grab the data and use it however you want. This is how modern Render-to-texture operations are made.

You can then use the data in the Framebuffer (in the form of a chunk of memory containing pixels) to populate an actual image object using whatever library you have.

You can render anything you want on a Frame Buffer Object, from which you can grab the data and use it however you want. This is how modern Render-to-texture operations are made.

You can then use the data in the Framebuffer (in the form of a chunk of memory containing pixels) to populate an actual image object using whatever library you have.


Thanks for the tip. I've been doing some research about it. I think i have it all, but i'm not sure how i'm able to grab the rendered data from my frame buffer object.

I've done all the setups for the frameBufferDepth, frameBufferTexture and the frameBuffer. I also have a function in which i want to draw the a teapot. It makes use of all the Frame Buffer Objects. But i have no clue how to get the rendered data from the buffer, so i can pass it to this other library...

This is the code for the final render:


void renderTeapotScene(void)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer for rendering
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
glViewport(0, 0, window_width, window_height); // Set the size of the frame buffer view port

glClearColor (0.0f, 0.0f, 1.0f, 1.0f); // Set the clear colour
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and colour buffers
glLoadIdentity(); // Reset the modelview matrix

// TEAPOT
glTranslatef(0.0f, 0.0f, -5.0f); // Translate back 5 units
glRotatef(rotation_degree, 1.0f, 1.0f, 0.0f); // Rotate according to our rotation_degree value
glutSolidTeapot(1.0f); // Render a teapot

glPopAttrib(); // Restore our glEnable and glViewport states
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture

rotation_degree += 0.5f;
if (rotation_degree > 360.0f)
rotation_degree = 0.0f;
}
glReadPixels seems to do the job. Never used it myself, but it looks like a straightforward memory copy.
Yes
http://www.opengl.org/wiki/Framebuffer_Object_Examples#glReadPixels
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Hi, i'm having some difficulties storing the pixels read from glReadPixels. I tried to do it like this:


unsigned char pixels[1024][768][3];
for ( int y=0; y<768; y++ )
{
for ( int x=0; x<1024; x++ )
{
glReadPixels(x,y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixels[x][y]);
}
}


But this is very slow (and i'm not even sure if an unsigned char can hold that much data...).

Any ideas on what a better approach is, to store all of the pixel data...??
Had been trying a alot of thing, but i finally came to an answer.

unsigned char pixels[1024*768][3];
glReadPixels(0,0, 1024, 768, GL_RGB, GL_UNSIGNED_BYTE, pixels);


But i'm having another problem right now. The pixels are nicely copied, but all i get to see is the clear color. I'm trying to render a teapot (thats a default function in glut?), but i don't see a teapot at all. Anyone any idea what the problem could be??


glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer for rendering
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
glViewport(0, 0, window_width, window_height); // Set the size of the frame buffer view port

glClearColor (0.0f, 1.0f, 0.0f, 1.0f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and colour buffers
glLoadIdentity(); // Reset the modelview matrix

// TEAPOT
glTranslatef(0.0f, 0.0f, -50.0f); // Translate back 5 units
glRotatef(rotation_degree, 1.0f, 1.0f, 0.0f); // Rotate according to our rotation_degree value
glutSolidTeapot(1.0f); // Render a teapot
glReadPixels(0,0, 1024, 768, GL_RGB, GL_UNSIGNED_BYTE, pixels);

// FINISH
glPopAttrib(); // Restore our glEnable and glViewport states
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture

Just checked with glGetError and glCheckFramebufferStatus. The first one returns 1282 and the framebuffer status gives me 36053, which equals to GL_FRAMEBUFFER_COMPLETE. Which is good. Except for the glGetError.which gives 1282 -> GL_INVALID_OPERATION.

I'm getting this error right after this line, no idea why...

[size=2]glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth);

[size=2][color=#008000][size=2][color=#008000]// Set the render buffer of this buffer to the depth buffer

[size=2]r = glGetError(); <--- 1282


Entire function:

[size=2]
void initFrameBufferDepthBuffer(void) {
int r = glGetError();
glGenRenderbuffersEXT(1, &fbo_depth); // Generate one render buffer and store the ID in fbo_depth
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_depth); // Bind the fbo_depth render buffer
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, window_width, window_height); // Set the render buffer storage to be a depth component, with a width and height of the window


[size=2]// Error after this line
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth); // Set the render buffer of this buffer to the depth buffer
r = glGetError();
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Unbind the render buffer
}



EDIT:


Nevermind that, fixed the error. Still no teapot though :-(

This topic is closed to new replies.

Advertisement