I have a quad and I would like to use the gradient it produces as a texture for another polygon.
glPushMatrix();
glTranslatef(250,250,0);
glBegin(GL_POLYGON);
glColor3f(255,0,0);
glVertex2f(10,0);
glVertex2f(100,0);
glVertex2f(100,100);
glVertex2f(50,50);
glVertex2f(0,100);
glEnd(); //End quadrilateral coordinates
glPopMatrix();
glBegin(GL_QUADS); //Begin quadrilateral coordinates
glVertex2f(0,0);
glColor3f(0,255,0);
glVertex2f(150,0);
glVertex2f(150,150);
glColor3f(255,0,0);
glVertex2f(0,150);
glEnd(); //End quadrilateral coordinates
My goal is to make the 5 vertex polygon have the gradient of the quad (maybe a texture is not the best bet)
Thanks
Keep it simple!
It is very simple to create a gradient texture in code, e.g.:
// gradient white -> black
GLubyte gradient[2*3] = { 255,255,255, 0,0,0 };
// WARNING: check documentation, I am not quite sure about syntax and order:
glTexture1D( GL_TEXTURE_1D, 0,3, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, gradient );
// setup texture parameters, draw your polygon etc.
The graphics hardware and/or the GL will create a sweet looking gradient from color one to color two for you (remember: that's one of the basic advantages of having hardware accelerated polygon drawing, you don't have to do interpolation work in software).
Your real problem is: which texture coordinates do you use on the 5 vertex polygon. But that was not your question... ;-)
To do that, you'd have to do a render-to-texture. While this is commonplace and supported by practically every board, it's typically used for quite elaborate effects (e.g. mirrors).
If it's really just a gradient, I'd try to create the gradient in am app like Paint.Net. If you really need to create them at run-time, use a pixel shader to implement render-to-texture. However, I'm afraid explaining pixel shaders in a few words is a bit tough - there are lots of tutorials on this on the net, however.
With the pixel shader, you gain a lot of control over the graphic card. This allows you to render your scene to a temporary buffer and then apply that buffer as a texture quite easily, plus a lot more functionality.
Related
Consider the following image:
It has both the mesh surface and the polygon edges visualized. What's more, even though the edges and the faces should have the same z-coordinates on the places where they are drawn and cause z-fighting, in this image, the polygon edges are always visible as long as they are not covered by a (non-adjacent) polygon, and there is no visible z-fighting. How can this be achieved in OpenGL?
I usually just enable some MSAA on the frame buffer I'm rendering to, and then just do:
glDepthFunc(GL_LESS);
drawShadededMesh();
glDepthFunc(GL_LEQUAL);
drawWireMesh();
That usually works well enough in most cases. Failing that(as mentioned in the comments) you can experiment with glPolygonOffset.
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0); ///< may need adjustment for your use case
glDepthFunc(GL_LESS);
drawShadededMesh();
glDisable(GL_POLYGON_OFFSET_FILL);
glDepthFunc(GL_LEQUAL);
drawWireMesh();
When drawing a quad, it vanishes when rotation brings in a position perpendicular to the screen. Ideally what I'd like to see is (b) but I get nothing
Is there something wrong with my code ? (warning old openGL code following)
void draw_rect(double vector[4][3], int rgb[3], double transp)
{
GLint is_depth, is_blend, blend_src, blend_dst;
glGetIntegerv(GL_DEPTH_WRITEMASK, &is_depth);
glGetIntegerv(GL_BLEND, &is_blend);
glGetIntegerv(GL_BLEND_SRC, &blend_src);
glGetIntegerv(GL_BLEND_DST, &blend_dst);
glEnable(GL_BLEND);
glDepthMask(0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// code to set the color ...
glBegin(GL_POLYGON);
glVertex3v(&vector[0][0]);
glVertex3v(&vector[1][0]);
glVertex3v(&vector[2][0]);
glVertex3v(&vector[3][0]);
glEnd();
if (!is_blend){ glDisable(GL_BLEND); }
glDepthMask(is_depth);
glBlendFunc(blend_src, blend_dst);
}
A quad (assuming it is defined by coplanar faces, as in this case) is by definition infinitely thin. It is correct behavior for it to be invisible when perpendicular to the camera.
The "correct" solution is to make a box rather than a single quad.
See Drawing cube 3D using Opengl for an example using a cube. You'll need to tweak the vertex positions to make the cube smaller along one dimension (probably Z), but it'll give you the effect that you're looking for.
Also, stop using the fixed function stuff (glVertex, etc.). It's been deprecated for years. Shaders aren't that difficult, and examples are easy to find via your favorite search engine.
try making it a line of some definite width when the quad is perpendicular to the screen
I have a problem when rendering cubes in OpenGL.I am drawing two cubes, one is a wire cube and is centered around the origin, while the other is offset from the origin and is solid. I have mapped some keys to rotate the objects by some degrees wrt to the origin, so the whole scene can rotate around the origin.
The problem is, when I render the scene, when the wire cube is supposed to be infront of the other solid cube, it does not display itself correctly.
In the image above, the colored cube is supposed to be behind the wire cube. i.e. the green wire cube should be on top.
Also the cube is not behaving properly.
After I rotate it a little bit around the x axis (current horizontal line).
The cube has missing faces and is not rendering correctly.
What am I doing wrong?
I have coded the following
Note that rotateX,rotateY,rotateZ are mapped to keys, and are my global rotation variables.
//The Initialize function, called once:
void Init(){
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Depth Buffer Setup // Enables Depth Testing
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_LIGHTING);
}
void draw(){
//The main draw function
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45, 640/480.0, .5, 100);
glMatrixMode(GL_MODELVIEW); //select the modelview matrix.
glLoadIdentity ();
gluLookAt(0,0,5,
0,0,0,
0,1,0);
glRotatef(rotateX,1,0,0);
glRotatef(rotateY,0,1,0);
glRotatef(rotateZ,0,0,1);
drawScene(); // this just draws the main axis lines,
glutWireCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(-2,1,0);
drawNiceCube();
glPopMatrix();
glutSwapBuffers();
}
The code for the drawNiceCube() is just using GL_QUADS, while the drawWireCube is built in in GLUT.
EDIT:
I have posted the full code at http://pastebin.com/p1kwPjEM, sorry if it is not well documented.
Did you also request a window with a depth buffer?
glutInitDisplayMode( ... | GLUT_DEPTH | ...);
Update:
Did you somewhere enable face culling?
glEnable(GL_CULL_FACE);
This is may be cause of clockwise
10.090 How does face culling work? Why doesn't it use the surface normal?
OpenGL face culling calculates the signed area of the filled primitive in window coordinate space. The signed area is positive when the window coordinates are in a counter-clockwise order and negative when clockwise. An app can use glFrontFace() to specify the ordering, counter-clockwise or clockwise, to be interpreted as a front-facing or back-facing primitive. An application can specify culling either front or back faces by calling glCullFace(). Finally, face culling must be enabled with a call to glEnable(GL_CULL_FACE); .
OpenGL uses your primitive's window space projection to determine face culling for two reasons. To create interesting lighting effects, it's often desirable to specify normals that aren't orthogonal to the surface being approximated. If these normals were used for face culling, it might cause some primitives to be culled erroneously. Also, a dot-product culling scheme could require a matrix inversion, which isn't always possible (i.e., in the case where the matrix is singular), whereas the signed area in DC space is always defined.
However, some OpenGL implementations support the GL_EXT_ cull_vertex extension. If this extension is present, an application may specify a homogeneous eye position in object space. Vertices are flagged as culled, based on the dot product of the current normal with a vector from the vertex to the eye. If all vertices of a primitive are culled, the primitive isn't rendered. In many circumstances, using this extension
from here
Also you can read here
datenwolf solved my problem. I quote him:
"#JonathanSimbahan: Parts of your code are redundant, but something is missing: You forgot to call Init(); after creating your GLUT window, hence depth testing and all the other state never get enabled. I for one suggest you don't use Init at all and move it's code into the drawing code, where it actually belongs."
I need to know how can I make the skybox appears as it's in the infinity??
I know that it's something related to depth, but I don't know the exact thing to disable or to enable??
First, turn off depth writes/testing (you don't need to bother with turning off depth testing if you draw the skybox first and clear your depth buffer):
glDisable(GL_DEPTH_TEST);
glDepthMask(false);
Then, move the camera to the origin and rotate it the inverse of the modelview matrix:
// assume we're working with the modelview
glPushMatrix();
// inverseModelView is a 4x4 matrix with no translation and a transposed
// upper 3x3 portion from the regular modelview
glLoadMatrix(&inverseModelView);
Now, draw your sky box and turn depth writes back on:
DrawSkybox();
glPopMatrix();
glDepthMask(true);
glEnable(GL_DEPTH_TEST);
You'll probably want to use glPush/PopAttrib() to ensure your other states get correctly set after you draw the skybox too (make sure to turn off things like lighting or blending if necessary).
You should do this before drawing anything so all color buffer writes happen on top of your sky box.
First, Clear the buffer.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Then, save your current modelview matrix and load the identity.
glPushMatrix();
glLoadIdentity();
Then render your skybox.
Skybox.render();
Then, clear the depth buffer and continue normally with rendering
glClear(GL_DEPTH_BUFFER_BIT);
OtherStuff.render();
glutSwapBuffers();
The only problem with drawing the sky box is first is that your pixel shader will execute for every pixel in the sky box. Just to be overwritten by other object in your world later on. Your best bet is to render all opaque object first then render your sky box. That way the pixel shader for the sky box only gets executed for the pixel who pass the z buffer test.
There is no infinity. A skybox is just a textured box, with normaly 0,0,0 in the middle.
Here is a short tut: link text
The best approach I can think of is to draw it on a first pass(or layer), then clear only the depth buffer. After that just draw the rest of the scene in another pass. This way the skybox will always remain "behind" the scene. Just remember to use the same camera for both passes and somehow snap the skybox to the camera.
My cube isn't rendering as expected when I use GL_BLEND.
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
I'm also having a similar problem with drawing some semi-opaque vertices in front, which could well be related.
Related: Why do my semi-opaque vertices make background objects brighter in OpenGL?
Here's what it's supposed to look like:
Normal cube http://img408.imageshack.us/img408/2853/normalcube.png
And here's what it actually looks like:
Dark cube http://img7.imageshack.us/img7/7133/darkcube.png
Please see the code used to create the colored cube, and the code used to actually draw the cube.
The cube is being drawn like so:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glLoadIdentity();
// ... do some translation, rotation, etc ...
drawCube();
glPopMatrix();
// ... swap the buffers ...
You could try disabling all lighting before drawing the cube:
glDisable(GL_LIGHTING);
It looks like you have lighting enabled on the second one,
try with a glShadeModel( GL_FLAT ) before drawing,
This has me stomped. What it looks like is that some vertices have some alpha values that are non-opaque. However the code you posted has all 1. for alpha. So... in order to debug more, did you try to change your clear color to something non-black ? Say green ?
From the code, I doubt lighting is turned on, since no normals were specified.
Last comment, offtopic... You should really not use glBegin/glEnd (2 function calls per vertex + 2 per primitive is really not a good usage of the recent developments in OpenGL). Try glDrawElements with QUAD_LIST, or even better, TRIANGLE_LIST. You already have the data nicely laid out for that.