2D map render in opengl - opengl

I use some small chip picture to make up a map.
When it's static, it's all ok.But when I use the glTranslated to move it.
It always has some small shiver.
I use this to init
glEnable(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER , 0.5);
I use this in display function.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslated(-_viewpos.x, _viewpos.y, 0);
if(_displayFunc)
{
_displayFunc(this, time0);
}
glPopMatrix();
and this to render a picture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _texture);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0);glVertex2d(p1.x, p1.y);
glTexCoord2d(0.0, 1.0);glVertex2d(p2.x, p2.y);
glTexCoord2d(1.0, 1.0);glVertex2d(p3.x, p3.y);
glTexCoord2d(1.0, 0.0);glVertex2d(p4.x, p4.y);
glDisable(GL_TEXTURE_2D);
glEnd();
I think the problem maybe is that when i change the coordinate from int to double,
It may have a pixel offset?
How to solve it?

Related

Colors disappear after drawing image

I am trying to draw a sphere and a cube at the same time on my screen. But the colors of my cube(which gets drawn first) dissapear. I don't understand why.
the sphere on the right is fine. But my cube on the left isn't.
I added texture to both:
I can perfectly draw both of them seperately, but when I try to draw both of them on one widget something goes wrong.
I tought the popping and pushing would solve this issue, but it doesn't.
code:
void MyGLWidget::drawCube()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(position,0.5,-0.1,-0.5,-0.5,0,0,0,1);
glTranslatef( 0.5, 0, 0.0);
glRotatef(getCubeAngle(), 1.0f, 0.0f, 0.0f);
glTranslatef(0, 0, 0);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
//back
glTexCoord2f(0.0, 1.0); glVertex3f(-0.1, 0.1,-0.1 );
glTexCoord2f(1.0, 1.0); glVertex3f(0.1, 0.1,-0.1);
glTexCoord2f(1.0, 0.0); glVertex3f(0.1,-0.1,-0.1);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.1,-0.1,-0.1);
/*rest of cube gets drawn*/
glEnd();
glFlush();
glPopMatrix();
}
void MyGLWidget::drawSun()
{
glPushMatrix();
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texturePlanet[0]);
glPushMatrix();
glScalef(1,1,1);
glLoadIdentity();
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricTexture(quadric, GLU_TRUE);
gluQuadricNormals(quadric, GLU_SMOOTH);
glEnable(GL_TEXTURE_2D); //
glBindTexture(GL_TEXTURE_2D,texturePlanet[0]);//
gluSphere(quadric, 0.25, 360,360);
glDisable(GL_TEXTURE_2D);//
gluDeleteQuadric(quadric);
glPopMatrix();
}
void MyGLWidget::paintGL()
{
drawCube();
drawSun();
}
It is because In your cube drawing, you didn't enable texturing.
glEnable(GL_TEXTURE_2D); //ADD THIS TO ENABLE TEXTURING
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
//back
glTexCoord2f(0.0, 1.0); glVertex3f(-0.1, 0.1,-0.1 );
glTexCoord2f(1.0, 1.0); glVertex3f(0.1, 0.1,-0.1);
glTexCoord2f(1.0, 0.0); glVertex3f(0.1,-0.1,-0.1);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.1,-0.1,-0.1);
/*rest of cube gets drawn*/
glEnd();
glFlush();
glPopMatrix();
glDisable(GL_TEXTURE_2D); // ADD THIS TO DISABLE TEXTURING

OpenGL texture with transparency (alpha)

I'm trying to render a texture with part opaque color and other part with transparency.
This is my draw function for the object:
void drawHighGrass(){
glDisable(GL_LIGHTING);
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor4f(1.0, 1.0, 1.0, 1.0);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texturas[HIGH_GRASS]);
glPushMatrix();
//glTranslatef(1000, 0, 1000);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0, 0, 0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(100, 0, 0);
glTexCoord2f(1.0f, 1.0f); glVertex3f(100, 40, 0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0, 40, 0);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
}
The problem is that in the transparent part it's showing solid white. I can make the texture transparent by using glColor4f(1.0, 1.0, 1.0, 0.5) but that's not what I want because it makes the entire texture transparent and not only the transparent part.
I've checked, my texture files is a PNG with transparency.
Restating the solution here so others can find it easily.
Your rendering code seems to be correct, so what seems to have been the problem was the texture loading code. When loading a texture, you must be sure that you are passing in the correct flags for the internal texture pixel format (GL_RGBA8, GL_RGBA16, etc.) as well as the source image pixel format (GL_RGBA or GL_BGRA, etc.).

fastest way to set every pixel

I have programmed a little raytracer in c++,
and want to show the raytraced image in a window.
I tried using a pixel buffer object in opengl,
then map the buffer into memory and manipulate the pixels one by one,
but at fullscreen resolution 1920x1080, I only get 4 fps
without raytracing and without changing the pixels colors
just the mapping and unmapping!
so i'm basically looking for the fastest way to display a raytraced image in a window.
i'm currently doing this way:
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 4, 0, GL_STREAM_DRAW_ARB);
if (pixels = (uint*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB))
{
//modify pixels
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
}
else
return;
//copy from pbo to texture
glBindTexture(GL_TEXTURE_2D, pbo_texture);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//draw image
glColor4f(1.0, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, pbo_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 0.0);
glEnd();
glutSwapBuffers();
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glBindTexture(GL_TEXTURE_2D, 0);
Check the memory traversal if you use loops. You should traverse your buffer in the right order, otherwise you may have cache miss at each iteration. If you use nested loops sometimes you only have to switch the x/y iteration order.
Also, don't read data from graphic memory. It tends to be slow. Only write to PBO.
It looks like a syncro issue. I'm not sure you need to map pbo at every frame. Check this link on OpenGL Pixel Buffer Object (PBO). There's also a workaround for stalls which could improve things

opengl stencil buffer multiple simultaneous uses

I've managed to successfully use OpenGL's stencil buffer for a single instance in a scene. However, I'm unsure of how to use it in two different places in the same scene. Defining two stencil shapes in sequence prevents either from working, and my attempts to nest one use inside of the other didn't work either. I've seen examples of multiple uses of stencil buffer in the same scene, but I was not able to understand or adapt the code. Here is what I've been able to get working so far.
void display(void) {
// store floor shape in stencil buffer
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glStencilMask(1);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
floor->draw();
glBegin(GL_QUADS); //
glVertex3f(0.0, 0.0, 0.0); //
glVertex3f(0.0, 100.0, 0.0); //
glVertex3f(0.0, 100.0, 100.0); //
glVertex3f(0.0, 0.0, 100.0); //
glEnd(); //
// draw scene outside floor
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
scene();
// draw reflection of scene in floor
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glPushMatrix();
glScalef(1.0, 1.0, -1.0);
scene();
glPopMatrix();
glDisable(GL_STENCIL_TEST);
// draw translucent floor
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, 0.7);
floor->draw();
//windowHole();
glDisable(GL_BLEND);
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}

Opengl: 2d HUD over 3D

I have looked at some questions posted here on the matter and still cant work out why my 2d HUD appears but makes my 3d Rendered world disappear.
EDIT: It seems that the 2d scene is taking control of the entire screen so every now and then I can see the 3d scene glitching through the 2d scene. So even though I its only ment to be rendering a quad thats 10 x 10 pixels it renders this then blanks out the rest of the screen.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0,(GLdouble)x/(GLdouble)y,0.5,20.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,x,y);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0,-0.5,-6.0);
glPushMatrix();
..Draw some 3d stuff...
glPopMatrix();
// Start 2d
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(0.0f, 255.0f, 1.0f);
glBegin(GL_QUADS);
glVertex2f(0.0, 0.0);
glVertex2f(10.0, 0.0);
glVertex2f(10.0, 10.0);
glVertex2f(0.0, 10.0);
glEnd();
Then I swap buffers
Here is the order of my code. Its like it makes the 3d space then makes the 2d space which in turn cancels out the 3d space.
Took a little while to figure it out, so just in case others have the same issues:
...After Drawing 3d Stuff...
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0, -1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
//glPushMatrix(); ----Not sure if I need this
glLoadIdentity();
glDisable(GL_CULL_FACE);
glClear(GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0);
glVertex2f(0.0, 0.0);
glVertex2f(10.0, 0.0);
glVertex2f(10.0, 10.0);
glVertex2f(0.0, 10.0);
glEnd();
// Making sure we can render 3d again
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
//glPopMatrix(); ----and this?
...Then swap buffers...
:)
If you're overlaying a 2D ortho projection over 3D, you generally want to get the depth buffer out of the equation:
glDepthMask(GL_FALSE); // disable writes to Z-Buffer
glDisable(GL_DEPTH_TEST); // disable depth-testing
Of course, you'll want to reset these to their original values before doing your next 3D pass.
glViewport(0, 0, x, y); //You need to do this only once on viewport resize
//Setup for 3D
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(40.0, (GLdouble)x/(GLdouble)y, 0.5, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BIT);
// ... Render 3D ...
//Setup for 2D
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BIT);
// ... Render 2D ...
SwapBuffers;
Note that there's no need to handle Push/Pop of matrixes if you render 2D completely on top of 3D.