Jump to content
  • Advertisement
Sign in to follow this  
vivendi

OpenGL rendering image in memory only

This topic is 2514 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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;
}

Share this post


Link to post
Share on other sites
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...??

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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 :-(

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!