I'm currently working with OpenGL and GLUT frameworks to play with particles.
However, I can seem to get my logic working correctly for the rotations/translations.
Pseudo code of my current situation:
void display() {
drawEnvironment();
for each particle 'part' in the array {
glPushMatrix(); // pushes the matrix for the current transformations? i.e. this particle?
glRotatef(part.angles); // rotate this matrix based of it's own angles (constantly changing)
drawParticle(part); // draws at origin
glTranslatef(part.positon); // translate to the position
glPopMatrix();
}
}
What I think I'm doing here is as follows:
Pushing the transformation matrix I need from the stack (for the current particle)
Rotating said matrix (glRotatef rotates around the origin (0,0,0) )
Drawing the particle at origin so it rotates on spot
Translate the particle to it's position now that it's been rotated
Pop the transformation matrix back onto the stack
I've also tried translating -> rotating -> drawing, and a few other mixes.
Hard to explain what's going wrong without a quick video:
https://www.youtube.com/watch?v=G0ouhCKKcIM
Looks like it's rotating after it's being translated, so since it rotates around the origin it follows that larger circle, rather than spinning on it's own axis.
The transformations should be applied in this order:
Push the matrix from stack
Translate to position
Rotate it
Draw it
Pop the matrix
This is because OpenGL works by pre-multiplication. The first operation is performed last.
Related
I'm making a game in OpenGL, using freeglut.
I have a car, which I am able to move back and forward using keys and the camera follows it. Now, when I turn the car(glRotate in xz plane), I want the camera to change the Camera position(using gluLookAt) so it always points to the back of the car.
Any suggestions how do I do that?
For camera follow I use the object transform matrix
get object transform matrix
camera=object
use glGetMatrix or whatever for that
shift rotate the position so Z axis is directing where you want to look
I use object aligned to forward on Z axis, but not all mesh models are like this so rotate by (+/-)90 deg around x,y or z to match this:
Z-axis is forward (or backward depends on your projection matrix and depth function)
X-axis is Right
Y-axis is Up
with respect to your camera/screen coordinate system (projection matrix). Then translate to behind position
apply POV rotation (optional)
if you can slightly rotate camera view from forward direction (mouse look) then do it at this step
camera*=rotation_POV
convert matrix to camera
camera matrix is usually inverse of the coordinate system matrix it represents so:
camera=Inverse(camera)
For more info look here understanding transform matrices the OpenGL inverse matrix computation in C++ is included there.
I am using WPF 3D, but I think this question should apply to any 3d texture mapping.
Suppose I have a model of a cow, and I want to draw a circular spot on the cow (and I want to do this dynamically -- supposed I don't know the location of the spot until run-time). I could do this by coloring the vertexes (vertexes are assigned a color based on their distance from the center of the spot), but if the model is fairly low-poly, that will give a pretty jagged-edged circle.
I could do it using a pixel shader, where the shader colors each pixel based on its distance from the center of the spot. But suppose I don't have access to pixel shaders (since I don't in WPF).
So, it seems that what I want to do is dynamically create a texture with the circle pattern on it, and texture the cow with it.
The question is: As I'm drawing that texture, how can I know what 3d coordinate in model space a given xy coordinate on the texture image corresponds to?
That is, suppose I have already textured my model with a plain white texture -- I've set up texture coordinates, done texture mapping, but don't have the texture image yet. So I have this 1000x1000 (or whatever) pixel image that gets draped nicely over the cow according to some nice texture coordinates that have been set up on the model beforehand. I understand that when the 3D hardware goes to draw a given triangle, it uses the texture coordinates of the vertexes of the triangle to find the corresponding triangular region of the image, and then interpolates across the surface of the triangle to fill displayed model pixels with colors from that triangular region of the image.
How do I go the other way? How do I say, for this given xy point on my texture image, and given the texture coordinates that have already been set up on the model, what's the 3d coordinate in model space that this image pixel is going to correspond to once texture mapping happens?
If I had such a function, I could color my texture map image such that all the points (in 3d space) within a certain distance of the circle center point on the cow would get one color, and all points outside that distance would get another color, and I'd end up with a nice, crisp circular spot on the cow, even with a relatively low-poly model. Does that sound right?
I do understand that given the texture coordinates for the vertexes of each triangle, I can step through the triangles in my model, find the corresponding triangle on the texture image, and do my own interpolation, across the texture pixels in that triangle, by interpolating across the 3d plane determined by the vertex points. And that doesn't sound too hard. But I'm just trying to understand if there is some standard 3d concept/function where I can just call a ready-made function to give me the model space coordinates for a given texture xy.
I did end up getting this working. I walk every point on the texture (1024 x 1024 points). Using the model's texture coordinates, I determine which polygon face, if any, the given u,v point is inside of. If it's inside of a face, I get the model coordinates for each point on that face. I then do a barycentric interpolation as described here: http://paulbourke.net/texture_colour/interpolation/
That is, for each u,v point on the texture, I use an inside-polygon check to determine which quad it's in on the 2D texture sheet and then I use an interpolation on that same 2D geometry as described in the link above, but instead of interpolating colors or normals I'm interpolating 3D coordinates.
I can then use the 3D coordinate to color the point on the texture (e.g., to color a circular spot on the cow based on how far in model space the given texture point is from the spot center point). And then I can apply the texture to the model, and it works.
Again, it seems like this must be a standard procedure with a name...
One issue is that the result is very sensitive to the quality of the the texturing as set up by the modeler. For instance, if a relatively large quad on the cow corresponds to a small quad on the texture image, there just aren't enough pixels to work with to get a smooth curve within that model quad once the texture is applied. You can of course use a higher-res texture, such as 2048x2048, but then your loop time is 4x.
It's actually a rasterization process if I didn't misunderstand your question. In lightmapping, one may also need to find the corresponding positions and normals in world space for each texel in the lightmap space and then baking irradiance. (which seems similar to your goal)
You can use standard Graphics API to do this task instead of writing your own implementation. Let:
Size of texture -> Size of G-buffers
UVs of each mesh triangle -> Vertex positions vec3(u, v, 0) of the input stage
Indices of each mesh triangle -> Indices of the input stage
Positions (and normals, etc.) of each mesh triangle -> Attributes of the input stage
After the rasterizer stage of the graphics pipeline, all fragments that lie within the UV triangle are generated, and the attributes that have been supplied are interpolated automatically. You can do whatever you want now in pixel shader!
I have installed GLUT and Visual Studio 2010 and found some tutorials on OpenGL basics (www.opengl-tutorial.org) and 2D graphics programming. I have advanced knowledge in C but no expirience with graphics programming...
For project (astronomy - time scales) , i must create one object in center of window and make other 5 objects (circles,dots...) to rotate around centered object with respect to some equations (i can implement them and solve). Equations is for calculating coordinates of that 5 objects and all of equations have parameter t (as time). For creating animation i will vary parameter t from 0 to 2pi with some step and get coordinates in different moments. If task was to print new coordinates of objects it would be easy to me but problem is how to make animation of graphics. Can i use some functions of OpenGL for rotation/translation ? How to make an object to move to desired location with coordinates determined by equation? Or i can redraw object in new coordinates every millisecond? First thing i thought was to draw all objects, calculate new coordinates, clear screen and draw all objects in new coordinates and repeat that infinitely..(it would be primitive but will work?)
Here is screen shot of that objects - http://i.snag.gy/ht7tG.jpg . My question is how to make animation by calculating new coordinates of objects each step and moving them to new location. Can i do that with basics in OpenGL and good knowledge of C and geometry? Any ideas from what to start? Thanks
Or i can redraw object in new coordinates every millisecond? First
thing i thought was to draw all objects, calculate new coordinates,
clear screen and draw all objects in new coordinates and repeat that
infinitely..
This is indeed the way to go. I would further suggest that you don't bother with shaders and vertex buffers as is the OpenGL 3/4 way. What would be easiest is called "immediate mode", deprecated by OpenGL 3/4 but available in 1/2/3. It's easy:
glPushMatrix(); //save modelview matrix
glTranslatef(obj->x, obj->y, obj->z); //move origin to object center
glBegin(GL_TRIANGLES); //start drawing triangles
glColor3f(1.0f, 0.0f, 0.0f); //a nice red one
glVertex3f(0.0, +0.6f, 0.0f);
glVertex3f(-0.4f, 0.0f, 0.0f);
glVertex3f(+0.4f, 0.0f, 0.0f); //almost equilateral
glEnd();
glPopMatrix(); //restore modelview matrix/origin
Do look into helper libraries glu (useful for setting up the camera / the projection matrix) and glut (should make it very easy to set up a window and basic controls and drawing).
It would probably take you longer to set it up (display a rotating triangle) than to figure out how to use it. In fact, here's some code to help you get started. Your first challenge could be to set up a 2D orthogonal projection matrix that projects along the Z-axis, so you can use the 2D functions (glVertex2).
First thing i thought was to draw all objects, calculate new coordinates, clear screen and draw all objects in new coordinates and repeat that infinitely..(it would be primitive but will work?)
That's exactly how it works. With GLUT, you set a display function that gets called when GLUT thinks it's time to draw a new frame. In this function, clear the screen, draw the objects and flush it to the screen. Then just instruct GLUT to draw another frame, and you're animating!
Might want to keep track of the time inbetween frames so you can animate things smoothly, but I'm sure you can figure that part out.
OpenGL is really just a drawing library. It doesn't do animation, that's up to you to implement. Clear/draw/flush is the commonly used approach for it though.
Note: with 'flush' I mean glFlush(), although GLUT in multi-buffer mode requires glutSwapBuffers()
The red book explains the proper way to draw models that can first be translated, rotated, scaled and so on: http://www.glprogramming.com/red/chapter03.html
Basically, you load the identity, perform transforms/rotations/scales (which one you want first matters - again the book explains it), draw the model as though it was at the origin at normal scale and it'll be placed in its new position. Then you can load identity and proceed with the next one. Every frame of an animation, you glClear() and recalculate/redraw everything. (It sounds expensive, but there's usually not much you can cache between draws).
I want to know whether glRotate rotates the camera, the world axis, or the object. Explain how they are different with examples.
the camera
There is no camera in OpenGL.
the world axis
There is no world in OpenGL.
or the object.
There are no objects in OpenGL.
Confused?
OpenGL is a drawing system, that operates with points, lines and triangles. There is no concept of a scene or a world in OpenGL. All there is are vertices of which each has a set of attributes and there is the state of OpenGL which determines how vertices are turned into pixels.
The very first stage of this process is getting the vertex positions within the viewport. In the fixed function pipeline (i.e. without shaders), to get those, each vertex position if first multiplied with the so called "modelview" matrix, the intermediary result is used for lighting calculations and then multiplied with the "projection" matrix. After that clipping and then normalization into viewport coordinates are applied.
Those two matrices I mentioned save two purposes. The first one "modelview" is used to apply some transformation on the incoming vertices so that those end up in the desired spot relative to the origin. There is no difference in first moving geometry to some place in the world, and then moving the viewpoint within the world. Or keeping the viewpoint at the origin and move the whole world in the opposite. All this can be described by the modelview matrix.
The second one "projection" works together with the normalization process to behave like a kind of "lens", so to speak. With this you set the field of view (and a few other parameters, like shift, which you need for certain applications – don't worry about it).
The interesting thing about matrices is, that they're non-commutative, i.e. for two given matrices N, M
M * N =/= N * M ; for most M, N
This ultimately means, that you can compose a series of transformations A, B, C, D... into one single compound transformation matrix T by multiplying the primitive transformations onto each other in the right order.
The OpenGL matrix manipulation functions (they're obsolete BTW), do just that. You have a matrix selected for manipulation (the matrix mode) for example the modelview M. Then glRotate effectively does this:
M *= R(angle,axis)
i.e. the active matrix gets multiplied on a rotation matrix constructed from the given parameters. Similar for scale and translate.
If this happens to appear to behave like a camera or placing a object depends entirely on how and in which order those manipulations are combined.
But for OpenGL there are just numbers/vectors (vertex attributes), which somehow translate into 2-dimensional viewport coordinates, that get drawn as points for filled inbetween as line or a triangle.
glRotate works on the current matrix. So it depend if the matrix is the camera one or a world trasformation one. To know more about the current matrix have a look at glMatrixMode().
Finding example is just googling: I found this one that in order to me should help you to figure out what's happening.
By (5, 5) I mean exactly the fifth row and fifth column.
I found it very hard to draw things using screen coordinates, all the coordinates in OpenGL is relative, and usually ranging from -1.0 to 1.0. Why it is so serious to prevent programmers from using screen coordinates / window coordinates?
The simplest way is probably to set the projection to match the pixel dimensions of the rendering space via glOrtho. Then vertices can be in pixel coordinates. The downside is that resizing the window could cause problems and you're mostly wasting the accelerated transforms.
Assuming a window that is 640x480:
// You can reverse the 0,480 arguments depending on you Y-axis
// direction preference
glOrtho(0, 640, 0, 480, -1, 1);
Frame buffer objects and textures are another avenue but you'll have to create your own rasterization routines (draw line, circle, bitmap, etc). There are problaby libs for this.
#dandan78 OpenGL is not a Vector Graphics renderer. Is a Rasterizer. And in a more precise way is a Standard described by means of a C language interface. A rasterizer, maps objects represented in 3D coordinated spaces (a car, a tree, a sphere, a dragon) into 2D coordinated spaces (say a plane, your app window or your display), these 2d coordinates belong to a discrete coordinated plane. The counter rendering method of rasterization is Ray Tracing.
Vector graphics is a way to represent by means of mathematical functions a set of curves, lines or similar geometrical primitives, in a nondiscrete way. So Vector graphics is in the "model representation" field rather than "rendering" field.
You can just change the "camera" to make 3D coordinates match screen coordinates by setting the modelview matrix to identity and the projection to an orthographic projection (see my answer on this question). Then you can just draw a single point primitive at the required screen coordinates.
You can also set the raster position with glWindowPos (which works in screen coordinates, unlike glRasterPos) and then just use glDrawPixels to draw a 1x1 pixel image.
glEnable( GL_SCISSOR_TEST );
glScissor( 5, 5, 1, 1 ); /// position of pixel
glClearColor( 1.0f, 1.0f, 1.0f, 0.0f ); /// color of pixel
glClear( GL_COLOR_BUFFER_BIT );
glDisable( GL_SCISSOR_TEST );
By changing last 2 arguments of glScissor you can also draw pixel perfect rectangle.
I did a bit of 3D programming several years back and, while I'm far from an expert, I think you are overlooking a very important difference between classical bitmapped DrawPixel(x, y) graphics and the type of graphics done with Direct3D and OpenGL.
Back in the days before 3D, computer graphics was mostly about bitmaps, which is to say collections of colored dots. These dots had a 1:1 relationship with the pixels on your monitor.
However, that had numerous drawbacks, including making 3D very difficult and requiring bitmaps of different sizes for different display resolutions.
In OpenGL/D3D, you are dealing with vector graphics. Lines are defined by points in a 3-dimensional coordinate space, shapes are defined by lines and so on. Surfaces can have textures, lights can be added, as can various types of lighting effects etc. This entire scene, or a part of it, can then be viewed through a virtual camera.
What you 'see' though this virtual camera is a projection of the scene onto a 2D surface. We're still dealing with vector graphics at this point. However, since computer displays consist of discrete pixels, this vector image has to be rasterized, which transforms the vector into a bitmap with actual pixels.
To summarize, you can't use screen/window coordinates because OpenGL is based on vector graphics.
I know I'm very late to the party, but just in case someone has this question in the future. I converted screen coordinates to OpenGL matrix coordinates using these:
double converterX (double x, int window_width) {
return 2 * (x / window_width) - 1;
}
double converterY (double y, int window_height) {
return -2 * (y / window_height) + 1;
}
Which are basically re-scaling methods.