How to Draw pixel data taken from the backbuffer back to itself? - c++

I'm working on a mobile application for Symbian 5th edition using OpenGLES.
This application is a pretty standard 2D app, and I make no use of the DepthBuffer.
I need to grab a snapshot of the display and then draw the very same snapshot back to the backbuffer.
I'm using glReadPixels((GLint)0, (GLint)0,
(GLint)nWidth-1, (GLint)nHeight-1,
GL_RGB, GL_UNSIGNED_BYTE, m_pPixelData)
in order to get the pixel data I need, but I'm rather new to OpenGLES and I don't know how to draw the data back to the backbuffer. (in OpenGL its easy using DrawPixels..)
I've read that I should generate a texture from the data, so I did.
But now I'm not sure how to draw this texture.
Do I need to draw it as a texture of a Rectangular element ? if so than how am I suppose to define this rect ? ( the coordinates just doesn't make sense to me..)
The display size is 480x640 and here is the code I want to use in order to draw the rect:
glEnable(GL_TEXTURE_2D);
//displayTex is my texture built out of the pixel data
glBindTexture(GL_TEXTURE_2D, m_pESSharedData->displayTex);
//Bottom
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-2.5f, -2.5f, 2.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(2.5f, -2.5f, 2.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(2.5f, -2.5f, -2.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-2.5f, -2.5f, -2.5f);
glEnd();
Note that above code is something I've picked up along the way, and I think this is the outline of what I'm suppose to do. feel free to take me off this track. :)
I thank you for your time.

You first need to make sure that the version of OpenGL-ES on Series60 5th edition can handle textures whose height and width aren't powers of 2.
I would advise forum nokia for that kind of query.
Shameless plug:
Quick Recipes On Symbian OS contains a whole chapter explaining the basics of OpenGL-ES on Symbian OS. The 3D code samples are here.

Related

How to use OpenGL and DevIL get user drawing pixels

I need to load an image, display the image, and let user draw some strokes on the image and get those drawing pixels.
I know OpenGL can load a texture image read by DevIL, and display it. But I am not sure how to use OpenGL to get user drawing pixels from loaded texture.
First off, note that a lot of this code is deprecated. But it is easier to understand from just code snippets. I'm not doing everything for you, but I hope to get you started by providing the basic workflow.
There are a few things you need to do to get the result you are looking for.
Firstly you have to load your texture in video memory. This is done with:
glGenTextures(1, texture_id); //generate a texture object
glBindTexture(GL_TEXTURE_2D, texture_id); //bind the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //set filters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //set filters
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, original_image_data); //create the actual texture in video ram
When this succeeds you can draw your texture with:
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//set to ortographic projection
glOrtho(0.0, window_width, 0.0, window_height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D,texture_id);
glBegin(GL_QUADS);
glTexCoord2f(0, 1); glVertex2f(-1.0f, 1.0f);
glTexCoord2f(1, 1); glVertex2f( 1.0f, 1.0f);
glTexCoord2f(1, 0); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(0, 0); glVertex2f(-1.0f, -1.0f);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
The next thing you will need to do is capture your user's mouse input. If you are on windows you can use the windowprocedure callback and look for the WM_MOUSE event. If you use a library for window management then the library will probably provide functionality for keyboard and mouse intput.
Now that you have the mouse input, you should draw a line on the screen every time a user moves the mouse while holding down the button:
glLineWidth(2.5);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex2f(mouse_x_start, mouse_y_start);
glVertex2f(mouse_x_end, mouse_y_end);
glEnd();
glColor3f(1.0, 1.0, 1.0);
When all of the above goes well, you should see your texture on the screen and a red line if you hold the mouse button and move the mouse. You are nearly there. The last thing that needs to be done is read the pixels. You can do this with glReadPixels() like this:
void glReadPixels(0, 0, window_width, window_height, GL_RGB, GL_UNSIGNED_BYTE, new_image_data);
You now have a byte array with the user's strokes on it. I would highly recommend writing your own code for this process, because the code I used is deprecated, and should only be used when targeting older platforms. The workflow should remain the same though. I hope this is enough to get you started. Good luck!
I assume you are working on a plain 2D app.
The idea is that if performance isn't your concern you may consider doing everything in software by crudely manipulating pixel data and drawing the image with your graphics library of choice. I recommend the Simple Directmedia Layer library. It has also a sublibrary called SDL_image that can load a good assortment of formats.
An approach like this works until you mess with big/multiple textures. If you need the GPU horsepower for realtime framerates then you must fight your way through FrameBuffer Objects, but beware! This basically means "do-everything-you-can-inside-the-pixel-shaders" and limit as much as you can calls like glReadPixels/glTexImage2D &co.

OpenGL Alternative for Drawing Textures with Immediate Mode?

I'm writing a simple graphics engine that draws textures on the screen using OpenGL and C++. The way that I draw the textures is using the source code below--the drawing is done in a method contained in a "Sprite" class that I wrote, which is called by the main scene's game loop.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(m_pos.x, m_pos.y);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(m_pos.x + m_size.x, m_pos.y);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(m_pos.x + m_size.x, m_pos.y + m_size.y);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(m_pos.x, m_pos.y + m_size.y);
glEnd();
glDisable(GL_TEXTURE_2D);
m_textureID is the id of the texture that was already loaded with OpenGL, and m_pos is a vector that stores the x and y position of the sprite, and m_size stores the size of the sprite.
The reason why I'm posting this is because I heard from somebody who is familiar with OpenGL that this is the wrong way to draw many different textures on the screen. Apparently, using glBegin(GL_QUADS) and glEnd() around calls to glVertex can be slow if there are many graphics on the screen at once, and that the correct way to do it is using vertex pointers.
Can anyone give me any pointers (no pun intended) on how to speed up the performance of this technique, using my implementation that I described above? Is there anything else I may be doing wrong? (I'm relatively new to OpenGL and graphics programming.)
Thanks in advance!
You are using immediate mode, which isn't used much (if at all) in serious 3D graphics programming these days. In fact, on mobile devices with OpenGL ES (1.1 and 2.0) it isn't even available.
At the very least, you should use vertex arrays, which are set up using glVertexPointer, glNormalPointer, glColorPointer and glTexCoordPointer, and then drawn using glDrawArrays or glDrawElements.
The next step is to push your vertex data into GPU memory by using vertex buffer objects (VBOs) via glGenBuffer, glBindBuffer and glBufferData. You can find example code here and here.

Scale Bitmapfont clearly with openGL (interpolation)?

I load an bitmapfont (as png image) in my openGL Application to render characters from there at a fixed size. That's working. But: If I want to scale some glyphs at a smaller size it doesnt look great. Is there a way - without using pregenerated mipmaps (I have a big bunch of several characters and need stepless sizes) to scale this more beautiful? Some way of interpolation or something?
At the moment I use something like this (C/C++ on Mac OS X):
glPopMatrix();
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, texture->getID());
glScalef(0.7f, 0.7f, 0); //scale here a size
{draw vertexes & set texcoords}
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glPushMatrix();
Any suggestion?
Did you try using Linear filtering on your textures?:
glTexParameteri(GL_TEXTURE_2D, GL_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_MAG_FILTER, GL_LINEAR);
This after binding textures.

position for texture in opengl

i have a question concerning how to declare the points for a texture on a cube
to be exactly i mean the:
glTexCoord2f(x.f, y.f);
for the front side, my declaration works:
glBegin(GL_POLYGON); //Vorderseite
glNormal3f(0.0f, 0.0f, 1.0f);//normale für vorderseite
glTexCoord2f(0.0f, -1.f);
glVertex3f(-fSeitenL/2.0f,-fSeitenL/2.0f,+fSeitenL/2.0f);
glTexCoord2f(1.f, -1.f);
glVertex3f(+fSeitenL/2.0f,-fSeitenL/2.0f,+fSeitenL/2.0f);
glTexCoord2f(1.f, 0.0f);
glVertex3f(+fSeitenL/2.0f,+fSeitenL/2.0f,+fSeitenL/2.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-fSeitenL/2.0f,+fSeitenL/2.0f,+fSeitenL/2.0f);
glEnd();
but for the right side, it doesn't work, i suggest i need other parameters, for glTexCoord2f, but i don't know witch one.
glBegin(GL_POLYGON); //Rechte Seite
glNormal3f(1.0f, 0.0f, 0.0f); //normale für rechte seite
glTexCoord2f(0.0f, -1.f);
glVertex3f(+fSeitenL/2.0f,-fSeitenL/2.0f,+fSeitenL/2.0f);
glTexCoord2f(1.0f, -1.f);
glVertex3f(+fSeitenL/2.0f,-fSeitenL/2.0f,-fSeitenL/0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(+fSeitenL/2.0f,+fSeitenL/2.0f,-fSeitenL/0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(+fSeitenL/2.0f,+fSeitenL/2.0f,+fSeitenL/0.0f);
glEnd();
after all i close the "texture-declaration with"
glDisable(GL_TEXTURE_2D);
thanks in advance
edit:
the frontside is shown with the picture, the other side isn't shown, not even the "cubeside".
for now i just use a picture that's black with some random white spaces, so the exactly position is not that much importent, despite that i'm very interessted how to set the glTexCoord2f right.
Since you're using negative texture coordinates (or really anything outside the 0..1 range) you need to make sure that your texture wrap mode is set to repeat.
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
If those are set to GL_CLAMP instead, then any value less than 0 will be set to 0 and any value greater than 1 will be set to 1. But since you say the first part of your model textures correctly, this is probably not your problem.
The next most likely issue is lighting. If you turn off lighting with glDisable(GL_LIGHTING); does the entire model show up? If so, then you need to make sure you have a light facing the problem portion of your model, or add an ambient component to your light.
How exactly does it not work?
If the texture isn't showing up or the wrong texture is applied, it means you have to set a different texture with glBindTexture().
If the texture is aligned incorrectly, you have to make sure that the vertices that are shared between the two faces have the same texture coordinate.

texture on cube-side with opengl

hello i want to use a texture on a cube (created by glutsolidcube()), how can i define where the texture is pictured at?
(for example on the "frontside" of a cube)
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);
glColor4f(0.8,0.7,0.11,1.0);
glPushMatrix();
glScalef(4, 1.2, 1.5);
glTranslatef( 0, 0.025, 0);
glutSolidCube(0.1);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
thanks
Not possible, since glutSolidCube() only generates vertexes and normals, not texture coordinates.
However, there are workarounds.
Unfortunately, using glutSolidCube is impossible, as it doesn't support texturing. What I'd suggest is a tutorial that explains the process that may help you. It's a bit outdated, but NeHe's texturing tutorial has some code that explains how to draw a cube, and the code is commented to explain which side is which for you.