OpenGL 3.2 2D rendering issues - c++

rendering artifact http://byte-werx.com/rendering-artifact.png
When I create two sprite batches and attempt to draw twice on the same frame half of my screen (or thereabouts) gets "lost"; this happens regardless of the position of the little campfire sprite.
When rendering in wireframe mode the same results occur so it does not appear that a giant black polygon is getting drawn and overriding the under laying tilemap.
This is the code used to initialize OpenGL:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnableClientState(GL_VERTEX_ARRAY);
glActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE0);
glDepthRange(0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDepthFunc(GL_LEQUAL);
glDisable(GL_DITHER);
glClearDepth(1.0f);
glEnable(GL_CW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
I have uploaded the relevant code here: download
SDL2 is used for window creation and context management, however I do not use anything else from SDL.

Resolved the issue, I was not unbinding the array/element buffers after calling glDrawElements.
Had to put this after glDrawElements:
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Related

OpenGL blending with skybox

I'm trying to render a semi-transparent object inside of a skybox. However with my current implementation the textures are blended with the background color instead of the skybox (if there is no other object in the way).
Here are some milestones in my implementation I thought would be useful to share:
init:
[...]
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
[...]
render:
[...]
[render scene]
[...]
glUseProgram(program_skybox);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_FALSE);
[bind view & projection matrices]
[draw skybox]
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
What should I change to make my skybox blend?
I suppose the problem is with the depth buffer?

How do I create a triangular stencil with OpenGL?

I started out working on an OpenGL program written in C that loads a 3D model from the user's filesystem with ASSIMP and renders it into the center of a window created with GLUT. So far I've gotten that basic rendering step working just fine. Now I want to render that same model into an OpenGL stencil in the shape of a triangle, but I haven't been able to figure it out. I have included an image representing the desired effect:
To elaborate, I want to make a triangle shaped stencil over my model as demonstrated below:
My code is pretty basic, all I do is enable GL_STENCIL_TEST, setup the stencil function, draw my triangle, and then draw the model.
glEnable(GL_STENCIL_TEST);
// Fill stencil buffer with 0's
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
// Write 1's into stencil buffer where the hole will be
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glStencilFunc(GL_ALWAYS, 1, ~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
// Draw the triangle hole shape
glBegin(GL_TRIANGLES);
glVertex2f(-0.3f, -0.3f);
glVertex2f(0.f, 0.3f);
glVertex2f(0.3f, -0.3f);
glEnd();
// Draw scene, keeping fragments with 1's in the stencil buffer
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glStencilFunc(GL_EQUAL, 1, ~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// Renders the model
drawTheModel();
glDisable(GL_STENCIL_TEST);
My GLUT display mode is as follows:
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
When I run the above code, all I get is an empty window. I've read the documentation and checked loads of examples, but I can't seem to figure out what I'm doing wrong.
Any ideas?
UPDATE: I downloaded and compiled this stencil example and added my triangle stencil. My triangle stencil seemingly draws into the depth buffer - investigating. How my stencil looks on the example:

Using openGL's glBindFramebuffer seems to have no effect

I am getting into FBOs (Framebuffer Objects) in openGL. Right now, I'm simply trying to render something to an FBO, then use the texture associated with it to render that image to the screen. I have been working on this problem for hours today and yesterday. I've tried copying as closely as I can two different examples, and yet I still have the same problem. I am absolutely stuck.
It seems like what is happening is that the framebuffer object is not actually being binded. In the code, I have two sets of glClear() and glClearColor() commands: the first for drawing to the framebuffer, and the second for drawing to the screen. However, when I comment out the second set, the first set is clearly affecting the screen. If the FBO is binded, shouldn't it receive those commands, and not affect the actual output to the screen directly?
To begin, I use glewInit(), and then I create an FBO, and then a Renderbuffer object and a texture to associate with it, and do all of the necessary steps to put it all together:
glewInit();
int width=512,height=512;
glGenFramebuffers(1, &fbo);
glGenRenderbuffers(1, &rbo);
glGenTextures(1, &fboTex);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindTexture(GL_TEXTURE_2D, fboTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(status==GL_FRAMEBUFFER_COMPLETE);
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
Then, I draw to the framebuffer object.
glClearColor(0.5,0.5,0.5,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor4f(1.0,0,0,1);
glBegin(GL_QUADS);
glVertex2f(100,100);
glVertex2f(200,100);
glVertex2f(200,250);
glVertex2f(100,200);
glEnd();
I then unbind each of the following three objects:
glBindFramebuffer(GL_FRAMEBUFFER,0);
glBindRenderbuffer(GL_RENDERBUFFER,0);
glBindTexture(GL_TEXTURE_2D,0);
Then I attempt to draw the texture to the window:
glEnable(GL_TEXTURE_2D);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTextureEXT(GL_TEXTURE_2D, fboTex);
glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex3f(-.5,-.5,0);
glTexCoord2f(1,0);glVertex3f(.5,-.5,0);
glTexCoord2f(1,1);glVertex3f(.5,.5,0);
glTexCoord2f(0,1);glVertex3f(-.5,.5,0);
glEnd();
glDisable(GL_TEXTURE_2D);
glFlush();
This has got to be either some really simple mistake or misunderstanding that somehow evaded eradication when I retyped all this twice, or a driver issue? My driver is supposed to be able to run version 3.2 of openGL...
Any help on this frustrating issue would be great.
EDIT: I found out what I was ultimately doing wrong. I didn't realize that glColor commands affected any drawing done, regardless of whether you have a framebuffer binded at the time or not. I needed to change the glColor back to (1,1,1) after drawing to the FBO, in order to render the FBO's texture later with all of its color.
Without a full code example it's difficult to see what's wrong. For kickstarting your FBO endeavors I provide https://github.com/datenwolf/codesamples/tree/master/samples/OpenGL/minimalfbo

OpenGl texture mapping blocking colours on FreeType?

I'm using FreeType in order to allow fonts to be used in OpenGL. However, I'm having a problem where I cannot change the font colour whenever I do texture mapping. No matter what I select using glColor3f it will just come out white. The texture works fine.
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(0.5,0.0,0.5);
glPushMatrix();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, texName);
glBegin(GL_POLYGON);
glTexCoord2f(0,1); glVertex2f(-16,-16);
glTexCoord2f(0,0); glVertex2f(-16,16);
glTexCoord2f(1,0); glVertex2f(16,16);
glTexCoord2f(1,1); glVertex2f(16,-16);
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glPopMatrix();
glColor3f(1,0,0);
print(our_font, -300+screenWidth/2.0, screenHeight/2.0, "fifty two - %7.2f", spin);
This is the problem code, I can confirm that drawing a polygon beneath this code will indeed make it red. The text is not changing to red though which it should; if you remove the texture mapping above it will turn red again, I can only think it is a problem with enabling and disabling and I've forgotten to do something...?
Fixed it. Just after I disabled texturing I forgot to set the environment back to modulate:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
adding this after disabling texture/blending fixes the problem.

render transparent textures

I have one texture that has some portions which are transparent transparent I want to apply over an object whose faces are some opaque material (or colour if it's simpler) but the final object gets transparent. I want the final object to be totally opaque.
Here is my code:
First I set the material:
glDisable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
glColor4f(0.00, 0.00, 0.00, 1.00);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glColor4f(0.80, 0.80, 0.80, 1.00);
glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
glColor4f(0.01, 0.01, 0.01, 1.00);
glEnable(GL_COLOR_MATERIAL);
Then I setup the VBOs
glBindTexture(GL_TEXTURE_2D, object->texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindBuffer(GL_ARRAY_BUFFER, object->object);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), ver_offset);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), tex_offset);
glNormalPointer(GL_FLOAT, sizeof(Vertex), nor_offset);
And finally I draw the object
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE, GL_ZERO);
glDrawArrays(GL_TRIANGLES, 0, object->num_faces);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLES, 0, object->num_faces);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
I tried passing different arguments to glBlendFunc() with no prevail. I've uploaded the source here: http://dpaste.com/83559/
UPDATE
I get this, but I want this (or without texture this).
The 2nd and the 3rd picture are produces with glm. I studied the sources, but since my knowledge of OpenGL is limited I didn't understand much.
If you're trying to apply two textures to your object you really want to set two textures and use multitexturing to achieve this look. Your method is drawing the geometry twice which is a huge waste of performance.
Multitexturing will just sample from two texture units while only drawing the geometry once. You can do this with shaders (the way things really should be done) or you can still used the fixed function pipeline (see: http://bluevoid.com/opengl/sig00/advanced00/notes/node62.html)
AFAIK the blend function takes fragment colors (opposed to texture colors). So if you draw the object a second time with blending, the triangles become transparent.
What you want to accomplish could be done using multitexturing.
This is just a wild guess, as you have failed to provide any screenshots of what the actual problem is, but why do you disable the depth test? Surely you want to enable depth testing on the first pass with a standard GL_LESS and then do the second pass with GL_EQUAL?
Edit:
ie
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST); // ie do not disable
glDepthFunc( GL_LESS ); // only pass polys have a z value less than ones already in the z-buffer (ie are in front of any previous pixels)
glDisable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE, GL_ZERO);
glDrawArrays(GL_TRIANGLES, 0, object->num_faces);
// for the second pass we only want to blend pixels where they occupy the same position
// as in the previous pass. Therefore set to equal and only pixels that match the
// previous pass will be blended together.
glDepthFunc( GL_EQUAL );
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLES, 0, object->num_faces);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
Try disabling blending and drawing a single pass with your texture function set to GL_DECAL instead of GL_MODULATE. This will blend between the vertex color and the texture color based on the texture’s alpha channel, but leave the alpha channel set to the vertex color.
Note that this will ignore any lighting applied to the vertex color anywhere the texture was opaque, but this sounds like the intended effect, based on your description.
It will be much simpler with pixel shaders. otherwise I think you need multi-passes rendering or more than one texture.
You can find comprehensive details here :http://www.opengl.org/resources/faq/technical/transparency.htm