Processing: Creating two 3D boxes and rotating - opengl

I need to create two Boxes, which should both be rotating with the same speed in the same way, only their position should be different. All i got is this:
http://i.stack.imgur.com/JMua9.png
I have used the following code:
float rotatevalue;
void setup()
{
rotatevalue = 0;
size(500, 500, OPENGL);
if (frame != null) {
frame.setResizable(true);
}
}
void draw()
{
background(245, 238, 184);
fill(246, 225, 65);
rotatevalue = rotatevalue + 2;
pushMatrix();
translate(width/4, height/4);
rotateX(radians(rotatevalue));
rotateY(radians(rotatevalue));
box(50);
popMatrix();
pushMatrix();
translate(3*width/4, height/4);
rotateX(radians(rotatevalue));
rotateY(radians(rotatevalue));
box(50);
popMatrix();
}
What is wrong that makes them to rotate differently?

I'm not used to using the OpenGL matrix stack, so this may be a little off-base. I calculate my own model matrices to pass to the vertex shader. When I do this, I do the rotations first before the translation.

If you want draw 3D object inside 2D sketch you must use some type of projection same as your eye is projecting real world. For more information you should study more about perspective and projection.
So your boxes are rotating in the same way! I will try to demonstrate it on this basic example. Here you can see 5 boxes around middle of sketch:
void setup(){
size(500, 500, OPENGL);
fill(246, 225, 65);
//ortho();
}
void draw(){
background(245, 238, 184);
translate(width/2, height/2);
draw_box(0);
draw_box(1);
draw_box(2);
draw_box(3);
draw_box(4);
}
void draw_box(int pos){
pushMatrix();
switch(pos){
case 0: translate( 0, 0); break;
case 1: translate( 0,-100); break;
case 2: translate( 0, 100); break;
case 3: translate( 100, 0); break;
case 4: translate(-100, 0); break;
}
box(50);
popMatrix();
}
There is no rotation so they should be same? NO! It is same as railway tracks = they are parallel but in long distance you can almost see them touching (img)
You can try orthographic projection to get more similar boxes for more info see ortho. Also you should be more centric if you want better results.

Related

DrawPolygon works, but FillPolygon doesn't using the same set of points

I have a vector of points where each point represents the vertices of a polygon. If I use the vector of points in the DrawPolygon method, the polygon is drawn as expected. However, If I use the same vector with FillPolygon, nothing happens.
Here is how I am successfully drawing the outline of a polygon:
void CBurstSign::Draw(Gdiplus::Graphics* graphics)
{
Pen pen(Color(255, 255, 0, 0));
graphics->DrawPolygon(&pen, &mPoints[0], mPoints.size());
}
This works. Making a couple of minor adjustments, I thought the following changes would draw a filled polygon:
void CBurstSign::Draw(Gdiplus::Graphics* graphics)
{
SolidBrush backgroundBrush(Color(255, 255, 0, 0));
graphics->FillPolygon(&backgroundBrush, &mPoints[0], mPoints.size());
}
When this code is ran, nothing is drawn.
I even tried using an array of points instead of a vector like the documentation shows, but this fails as well:
void CBurstSign::Draw(Gdiplus::Graphics* graphics)
{
Gdiplus::PointF points[65] = {};
SolidBrush backgroundBrush(Color(255, 255, 0, 0));
int i = 0;
for (PointF point : mPoints)
{
points[i] = point;
i++;
}
PointF* pPoints = points;
graphics->FillPolygon(&backgroundBrush, pPoints, mPoints.size());
}
I cannot see what I'm missing here. The array of points is the same in either case, so I'm not sure why DrawPolygon would work but FillPolygon wouldn't.

(each call to glTranslate is cumulative on the modelview matrix) what does it mean and how to disable this feature?

Studying the book OpenGL SuperBible fram Addison-Wesley, I read:
each call to glTranslate is cumulative on the modelview matrix
what does it mean?
Does it mean that for example this code:
glTranslatef(2.0,3.0,0);
glTranslatef(4.0,5.0,0);
first moves an object that is on the origin to the point (2,3,0) and then translates it from the (2,3,0) to (2+4,3+5,0+0) = (6,8,0) not from the origin again?
Is this true about glScalef and glRotatef too?
for example this code:
glScalef(2.0,3.0,4.0);
glScalef(3.0,4.0,5.0);
first turn a 1x1x1 cuboid to a 2x3x4 cubic rectangle and then turns this cubic rectangle to a 6x12x20 one?
And at last, Does this code mean that a total 75 degrees rotation around the x-axis?
glRotatef(30.0,1,0,0);
glRotatef(45.0,1,0,0);
the most importantant: Does calling glLoadIdentity() before each call of these functions cancels these feature?
I mean Do you think this code assures that each time translates will be done from the origin? , scale changes will be done from the initial state?
void COpenGLControl::ZoomToFullExtent()
{
float zoom1 = (float)oglWindowWidth/(float)ImageWidth;
float zoom2 = (float)oglWindowHeight/(float)ImageHeight;
m_fZoom = min(zoom1,zoom2);
m_fZoomInverse = 1/m_fZoom;
m_fPosX = 0;
m_fPosY = 0;
OnDraw(NULL);
}
void COpenGLControl::FixedZoomIn()
{
m_fZoom = 2*m_fZoom;
m_fZoomInverse = 1/m_fZoom;
OnDraw(NULL);
}
void COpenGLControl::FixedZoomOut()
{
m_fZoom = 0.5*m_fZoom;
m_fZoomInverse = 1/m_fZoom;
OnDraw(NULL);
}
void COpenGLControl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (WantToPan)
{
if (m_fLastX < 0.0f && m_fLastY < 0.0f)
{
m_fLastX = (float)point.x;
m_fLastY = (float)point.y;
}
diffX = (int)(point.x - m_fLastX);
diffY = (int)(point.y - m_fLastY);
m_fLastX = (float)point.x;
m_fLastY = (float)point.y;
if (nFlags & MK_MBUTTON)
{
m_fPosX += (float)0.2f*m_fZoomInverse*diffX;
m_fPosY += (float)0.2f*m_fZoomInverse*diffY;
}
OnDraw(NULL);
}
CWnd::OnMouseMove(nFlags, point);
}
void COpenGLControl::OnDraw(CDC *pDC)
{
// TODO: Camera controls
wglMakeCurrent(hdc,hrc);
glLoadIdentity();
gluLookAt(0,0,1,0,0,0,0,1,0);
glScalef(m_fZoom,m_fZoom,1.0);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
wglMakeCurrent(NULL, NULL);
}
glTranslate, glScale, glRotate don't act on "objects" (whatever a object is. OpenGL doesn't know what a "object" is, it only knows points, lines and triangles).
In old fixed function OpenGL you have a couple of matrix stacks. A stack is a data structure similar to a list, with two operations push and pop. You can in fact derive it from a list:
stack : list;
void stack::push() {
this->append( copy(this->last_element) );
}
void stack::pop() {
this->drop( this->last_element );
}
Projection and modelview are the most oftenly used ones. There's always one particular matrix stack active for manipulation. glMatrixMode selects which one; think of it as a reference.
stack<mat4x4> modelview;
stack<mat4x4> projection;
stack<mat4x4> *M;
void glMatrixMode(mode) {
switch(mode) {
case GL_MODELVIEW:
M = &modelview; break;
case GL_PROJECTION:
M = &projection; break;
}
}
void glPushMatrix() {
M->push();
}
void glPopMatrix() {
M->pop();
}
The OpenGL fixed function matrix manipulation functions act in place on top element of the active matrix stack (M).
void glLoadIdentity() {
M->last_element = identity_matrix;
}
void glTranslate(x,y,z) {
/* make a translation matrix and R-multiply in place */
mat4x4 T = translate_matrix(x,y,z);
M->last_element = M->last_element * T;
}
void glScale(x,y,z) {
/* make a scaling matrix and R-multiply in place */
mat4x4 S = scaling_matrix(x,y,z);
M->last_element = M->last_element * S;
}
void glRotate(a,x,y,z) {
/* make a rotation matrix and R-multiply in place */
mat4x4 R = rotation_matrix(a,x,y,z);
M->last_element = M->last_element * R;
}
And that's all that's happening behind the curtain when calling those functions.
OpenGl keeps a modelView matrix which multiply the coordinates of your vertices. Every call to translate, rotate, scale etc will multiply this matrix by the right. So if you have:
glLoadIdentity();
glTranslatef(2.0,3.0,0);
glTranslatef(4.0,5.0,0);
The result will be first translating your vertices by 4,5,0 and then by 2,3,0. Internally, this will work as follows:
1. the modelView matrix will be the identity.
2. the current modelView matrix (the identity) will be right multiplied by the translation matrix with values ( 4, 5, 0) for more details see (http://en.wikipedia.org/wiki/Translation_%28geometry%29)
3. the current modelViewmatrix (the one of step 2) will be right multiplied by the second translation matrix.
In your example of scaling:
glScalef(2.0,3.0,4.0);
glScalef(3.0,4.0,5.0);
It will be equivalent to first turn the 1x1x1 cuboid into a 3x4x5 cuboid and then into a 6x12x20.
In the roation case, first rotate 45 degrees and then 30.
To your question about the use of glLoadIdentity(), the modelView matrix will be the identity independently from the previous value of the matrix.
You may also be interested in checking the transformation stack system of opengl.
Pay special attention to OpenGL API functions that include the description: "does ... to the current ...".
OpenGL is a glorified state machine, and things like bound objects and matrices (in legacy OpenGL) retain their state. When you make a call to glTranslatef (...) it multiplies the current matrix (defined by the matrix mode and the top of your matrix stack). Unless you issue glLoadMatrixf (...), glLoadIdentity (...) or modify the matrix stack, glTranslatef (...) will simply accumulate everytime you call it.
glLoadIdentity (...) will replace the current matrix with its identity:
1, 0, 0, 0
0, 1, 0, 0
0, 0, 1, 0
0, 0, 0, 1
If you setup your transform matrices every frame, it is generally required that you do this. Otherwise, all of your transformations will be relative to the previous state (though this is sometimes desired).

OpenGL strange Rendering behaviour (flickering faces)

PRE: I'm using Assimp (Open Asset Import) library to import a .3ds file. Meshes are rendered with normals and materials. Using Qt. Drivers up to date on all the computers we tried.
POST: When I rotate around the objects,using camera,I can see that some mesh' faces flickering.
The same happens using Assimp' render() method (sample code downloaded from A. wsite).
1)The strange thing is that it usually happens with small size .3ds,while never happens with big ones.
2)If I am really close there are no artifacts.The furthest I am,the more artifacts I see.
Is it a .3ds problem or mine?
Example of big .3ds (20MB)
Example of small .3ds (3MB)
I paste here my Draw() function (uses glLists but i can't get rid of them):
void Preview::BuildObjectsLists(Scene *sc,GLenum mode){
QHash<QString, SceneObject*>& hash=sc->getObj();
int counter =0;
for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
glNewList(index-counter, GL_COMPILE);
Mesh* p = dynamic_cast<Mesh*>(i.value());
if(p){
Matrix4x4& a=p->getTrasformation();
a.transpose();
if(mode==GL_SELECT){
glPushName(counter);
}
glPushMatrix();
glMultMatrixf((float*) &(a.values));
applyMaterial(p->getMat());
QList<Face>& faccie=p->getFaces();
int numerofacce=faccie.count();
QList<Vector3D>& normals =p->getNormals();
bool hasNormals=(!(normals.isEmpty()));
if(hasNormals) glEnable(GL_LIGHTING);
else glDisable(GL_LIGHTING);
for (int t = 0; t < numerofacce; ++t) {
Face& f = faccie[t];
GLenum face_mode;
Vector3D* lista=f.arrayVertici;
int* listaNorm=f.normalIndex;
switch(f.numVertici) {
case 1:
face_mode = GL_POINTS;
glBegin(face_mode);
if(hasNormals)
glNormal3fv(&((normals[listaNorm[0]]).pos[0]));
glVertex3fv(&lista[0].pos[0]);
break;
case 2:
face_mode = GL_LINES;
glBegin(face_mode);
if(hasNormals){
glNormal3fv(&((normals[(f.normalIndex)[0]]).pos[0]));
glVertex3fv(&lista[0].pos[0]);
glNormal3fv(&((normals[(f.normalIndex)[1]]).pos[0]));
glVertex3fv(&lista[1].pos[0]);
}
else{
glVertex3fv(&lista[0].pos[0]);
glVertex3fv(&lista[1].pos[0]);
}
break;
case 3:
face_mode = GL_TRIANGLES;
glBegin(face_mode);
if(hasNormals){
glNormal3fv(&normals[(f.normalIndex)[0]].pos[0]);
glVertex3fv(&lista[0].pos[0]);
glNormal3fv(&normals[(f.normalIndex)[1]].pos[0]);
glVertex3fv(&lista[1].pos[0]);
glNormal3fv(&normals[(f.normalIndex)[2]].pos[0]);
glVertex3fv(&lista[2].pos[0]);
}
else{
glVertex3fv(&lista[0].pos[0]);
glVertex3fv(&lista[1].pos[0]);
glVertex3fv(&lista[2].pos[0]);
}
break;
default: face_mode = GL_POLYGON; break;
}
glEnd();
}
glPopMatrix();
}
if(mode==GL_SELECT) glPopName();
glEndList();
counter++;
}
}
12.040 Depth buffering seems to work, but polygons seem to bleed through polygons that are in front of them. What's going on?
You may have configured your zNear and zFar clipping planes in a way that severely limits your depth buffer precision. Generally, this is caused by a zNear clipping plane value that's too close to 0.0.
http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm

First view perspective: rotation is driving me crazy

I would like to implement a simple example in OpenGL just to test the first perspective view (without using lookAt facility), but it is driving me crazy!
I made a little prototype using Processing (that for this stuff is quite similar to OpenGL), but I got strange behavior when camera start to move!
It's not clear to me which it is the order of transformation (I have already tried all combination ;-))!
I was thinking that it should be simple and a possible solution could be:
Translate to the position of the camera
Rotate by angle of the camera
Translate each object in its position
In my simple example I positioned a box and a grid in the (0, 0, -400), but it doesn't work as expected. When I move camera along the X or Z axis the rotation around Y axis seems to rotate around a wrong center! I'd like to simulate a rotation of the camera around its own Y axis, just like a classic FPS game.
Here my sample code where user can move the camera and rotate (just around Y axis), you can test with Processing or using OpenProcessing.
Only the first few lines are relevant to the problem... So it's a very little test!
float cameraXPos = 0;
float cameraYPos = 0;
float cameraZPos = 0;
float cameraYAngle = 0;
float moveIncrement = 5;
float angleIncrement = 5;
// Keys:
// W
// ^
// |
// A <- -> D
// |
// V
// S
//
// F and R for Z+/Z-
// O and P for rotation around Y axis
void setup()
{
size(640, 480, OPENGL);
resetCameraPos();
}
// Reset camera
void resetCameraPos()
{
cameraXPos = width / 2;
cameraYPos = height / 2;
cameraZPos = (height /2 ) / tan(PI/6);
cameraYAngle = 0;
}
void draw()
{
// Clear screen
background(0);
// View transform
translate(cameraXPos, cameraYPos, cameraZPos);
rotateY(radians(cameraYAngle));
// World transform
translate(0, 0, -400);
// Draw a red box and a grid in the center
stroke(255, 0, 0);
noFill();
box(100);
drawGrid();
// Check if user is pressing some key and update the camera position
updateCameraPos();
}
/////////////////////////////////////////////////////////////////////
// The following part is not so relevant to the problem (I hope! ;-))
/////////////////////////////////////////////////////////////////////
void drawGrid()
{
// Draw a white grid (not so important thing here!)
stroke(255, 255, 255);
float cellSize = 40;
int gridSize = 10;
float cY = 100;
for(int z = 0; z < gridSize; z++)
{
float cZ = (gridSize / 2 - z) * cellSize;
for(int x = 0; x < gridSize; x++)
{
float cX = (x - gridSize / 2) * cellSize;
beginShape();
vertex(cX, cY, cZ);
vertex(cX + cellSize, cY, cZ);
vertex(cX + cellSize, cY, cZ - cellSize);
vertex(cX, cY, cZ - cellSize);
vertex(cX, cY, cZ);
endShape();
}
}
}
// Just update camera position and angle rotation
// according to the pressed key on the keyboard
void updateCameraPos()
{
if (keyPressed)
{
switch(this.key)
{
case 'w': // Y++
cameraYPos += moveIncrement;
break;
case 's': // Y--
cameraYPos -= moveIncrement;
break;
case 'a': // X--
cameraXPos += moveIncrement;
break;
case 'd': // X++
cameraXPos -= moveIncrement;
break;
case 'r': // Z++
cameraZPos += moveIncrement;
break;
case 'f': // Z--
cameraZPos -= moveIncrement;
break;
case ' ': // RESET
resetCameraPos();
break;
case 'o': // Angle++
cameraYAngle += angleIncrement;
break;
case 'p': // Angle--
cameraYAngle -= angleIncrement;
break;
}
}
}
Your comment above seems to indicate that you want your cameraYAngle to rotate the camera about its current position. If so, you want to do your camera rotation first; try this:
// View transform
rotateY(radians(cameraYAngle));
translate(cameraXPos, cameraYPos, cameraZPos);
// World transform
translate(0, 0, -400);
Note that the above does nothing to keep you looking at the origin -- that is, it doesn't do anything like lookAt. Also recall that your camera starts out looking down the Z axis...
Here's where I guess you went wrong. Even though your camera and object poses are comparable, you need to generate your "View transform" and "World transform" differently: your camera pose must be inverted to generate your "View transform".
If you're chaining raw transforms (as in your example code), this means that your camera pose transforms need to be in reverse order relative to your object transforms, as well as in the reverse direction (that is, you must negate both translation vectors and rotation angles for the camera transforms).
To be more explicit, suppose both your camera and your object have comparable pose parameters: a position vector and 3 rotations about X, Y, and Z in that order. Then, your transformation sequence might be something like:
// View transform
rotateZ(radians(-cameraZAngle));
rotateY(radians(-cameraYAngle));
rotateX(radians(-cameraXAngle));
translate(-cameraXPos, -cameraYPos, -cameraZPos);
// Model transform
translate(objectXPos, objectYPos, objectZPos);
rotateX(radians(objectXAngle));
rotateY(radians(objectYAngle));
rotateZ(radians(objectZAngle));
As a conceptual check, suppose that your camera is exactly following your object, so that all position and location variables are exactly the same for camera and object. You'd expect the same view as if they were both sitting at the origin with no rotations.
Then note that, if cameraXPos==objectXPos, cameraYPos==objectYPos and so forth, the transforms in the above transform sequence all cancel out in pairs, starting at the center -- so that the end result is the same view as if they were both sitting at the origin with no rotations.
I've tried to port the same example on C and OpenGL, and... It works!
To be precise it works after I inverted the sequence of rotation and translation (as suggested by #comingstorm and as I formerly already tried).
So I come back to Processing and try to figure out why this problem happens. I had already noticed that the default camera position is in:
(width/2, height/2, (height/2) / (PI/6))
So in my code I was moving the camera off by the same distance (in opposite direction) in order to center the camera to my objects, but it didn't work. I also try to leave the camera where it was and then move manually (using the keyboard keys) to reach my objects, but it didn't work either.
So I noticed that in the draw() method there isn't any initialization of the transformation matrix.
In all examples I've seen none does this initialization, and I'm pretty sure to have read somewhere that is automatically initialized. So I was thinking/sure that it wasn't necessary.
Anyway I've tried to put as first statement of draw() method:
resetMatrix(); // Same as glLoadIdentity in OpenGL
...And now everything is working!
(For the record I noticed the same problem also in openFramework library.)
To be honest I don't understand why they (these libraries) don't put camera in the origin and above all I was expecting that if the transformation matrix is not clear at each execution of draw method the camera should be translated automatically (summing the old matrix with the new one), so it would move fast in some direction (or spinning around Y axis).
It's not clear to me the pipeline implemented in these libraries (and I can't find a good document where it is shown), but by now it is important that this problem has been fixed.

OpenGL glViewport() (resetting coordinates)

I have a problem with glViewport. In my liitle programm i have two viewports. I can draw a form (with the motionfunc) in one of those viewports and in the other a line is automatically drawn.
So far so good..
When i try to draw something with mousefunc the viewport is in a total different place. And it is very difficult to find the new correct coordinates for that viewport.
Is there a possibility to reset the coordinates..
I cant use glLoadIdentity in mouse or motion because then nothing is displayed.
I hope you understand what i mean. It is a bit difficult to explain.
OK here a codesnippet....
void mouse (int button, int state, int mx, int my)
{
if (modus == 0 && button==GLUT_LEFT_BUTTON && state != GLUT_DOWN)
{
...
}
else if (modus == 1 && button==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
**glViewport(10,10 , sw_w1, sw_h1);**
//the drawing is much higher than in the first viewport in motion.
//But it should be the same viewport like the first in motion.
glBegin()...glEnd()
glFlush();
}
}
void motion(int mousex,int mousey)
{
GLdouble h=12;
GLdouble winkel=360/h;
Line liste[num];
liste[++last].x =(mousex)-((sw_w1+2*GAP)/2);
liste[last].y =(mousey)-((sw_h1+2*GAP)/2);
if (modus==0 && gruppe == 0) {
if (last>=1)
{
glViewport(10, 10, sw_w1, sw_h1); //works fine
glColor3d(R, G, B);
for(h+1;h>0;h--){
glRotated(winkel, 0, 0, 1);
glBegin(GL_LINE_STRIP);
for(int i=last-1;i<=last;i++){
glVertex2i(liste[i].x,liste[i].y);
}
glEnd();
}
glLineWidth(linewidth+0.5);
glColor3f(1, 0, 0);
glBegin(GL_LINE_STRIP);
for(int i=last-1;i<=last;i++){
glVertex2i(liste[i].x,liste[i].y);
}
glEnd();
glViewport(1020,10 , sw_w2, sw_h2); //works fine
glColor3f(1, 0, 0);
glBegin(GL_LINE_STRIP);
for(int i=last-1;i<=last;i++){
glVertex2i(liste[i].x,liste[i].y);
}
glEnd();
}
glFlush();
}
}
The second and third viewport works fine. The first one is the same as the second but the picture is displayed much higher.Why is that so?
And how could i change it so that i get the same viewport like the second one.
I hope you now understand what i mean.
You should check your modelview/projection matrices and see if they are what you expect them to be in each function.
Also, as Christian's commented, it is not necessary, nor recommended, to draw in the motion func. Update your application state per the input and call glutPostRedisplay to signal that you want to redraw your window. That way, your application will have a cleaner design and it will be easier to make it behave consistently.
(added my comment as answer since that was the problem, and added Christian's comment, since that is the proper solution. Don't draw in motionfunc!.)