I have the code for a room provided to me, I need to add a sphere in the room. It goes like this:
PushMatrix();
//draw floor,walls,ceilings
PushMatrix();
//draw some boxes on front wall
PopMatrix();
PushMatrix();
//drawing sphere;
glLoadIdentity();
glColor3f(1, 0, 0);
glTranslatef(0, ypos, 0);
glutSolidSphere(2, 20, 20);
PopMatrix();
PopMatrix();
But all the walls etc turn red (and no sphere) when I do this. Why does that happen even after pushing another matrix?
Calling glColor*() sets the current color. This color doesn't change before you call glColor*() again. In other words glPushMatrix() and glPopMatrix() has no effect on the current color.
Thus if you in //draw some boxes on front wall don't call glColor*(). Then due to you setting the color to red by calling glColor3f(1, 0, 0) then everything is going to be red from that point on.
Considering:
glMatrixMode(GL_PROJECTION);
gluPerspective(40, 1, 1, 40);
glMatrixMode(GL_MODELVIEW);
Then:
glPushMatrix();
glTranslatef(0, 0, -10);
glColor3f(1, 0, 0);
glutSolidSphere(2, 20, 20);
glPopMatrix();
By doing the above you should see a sphere.
Thus if you before didn't see the sphere at all. Then it's probably due to ypos being outside your view. If you were referring to the whole screen being red, then I'm assuming ypos to be around 0, which means that it would be filling the whole screen (Again assuming you don't translate the view in any other way).
Related
I currently have some heat-map data in a database. I was successful in creating painting a heat-map using the same data [using some vertex shading] onto a plane. Example:
Heat-Map Image example for openGL
Name: Capture.jpg
Views: 0
Size: 8.5 KB
ID: 2667
Now, the problem is that I am currently using something like :
glBegin(GL_QUADS);
glColor4ub(point1.color.red(), point1.color.green(), point1.color.blue(), transparency);
glVertex3d(point1.xCood - 750, point1.yCood - 750, 0);
glColor4ub(point2.color.red(), point2.color.green(), point2.color.blue(), transparency);
glVertex3d(point2.xCood - 750, point2.yCood - 750, 0);
glColor4ub(point3.color.red(), point3.color.green(), point3.color.blue(), transparency);
glVertex3d(point3.xCood - 750, point3.yCood - 750, 0);
glColor4ub(point4.color.red(), point4.color.green(), point4.color.blue(), transparency);
glVertex3d(point4.xCood - 750, point4.yCood - 750, 0);
glEnd();
And what this does [at least in my theory] is that it creates another layer over the existing plane. This causes code on clicking the plane below to be rendered useless. Changing the existing code too much is not an option right now as I do not have access to edit it. I found that if I draw a texture (rather than color a plane) on the old plane, the code stays working.
Example(texture tile just defines number of repetitions required, value is 1 in this case):
glBegin(GL_QUADS);
glTexCoord2d(0.0, textureTile);
glVertex3d(gridRect.left(), gridRect.top(), 0.0);
glTexCoord2d(0.0, 0.0);
glVertex3d(gridRect.left(), gridRect.bottom(), 0.0);
glTexCoord2d(textureTile, 0.0);
glVertex3d(gridRect.right(), gridRect.bottom(), 0.0);
glTexCoord2d(textureTile, textureTile);
glVertex3d(gridRect.right(), gridRect.top(), 0.0);
glEnd();
That said, I was only successful in loading a texture from an image I made. Since the image is suppose to be calculated and painted during run time, I tried making an image from the data to load as a texture.
I used the Qt API functionality for achieving the same. I failed to recreate the same image. Might I be suggested a way to create a texture image from data owned.
Thanks
Sorry for the late answering(in case someone else wanted the answer).
I found the answer to be the use of QOpenGLFramebufferObject.
Final code looks something like:
glViewport(0, 0, VIEW_PORT_SIZE, VIEW_PORT_SIZE);
QOpenGLFramebufferObject fbObject(VIEW_PORT_SIZE, VIEW_PORT_SIZE);
fbObject.bind();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//Switch to Ortho Mode
glMatrixMode(GL_PROJECTION); // Select Projection
glPushMatrix(); // Push The Matrix
glLoadIdentity(); // Reset The Matrix
glOrtho(left, right, bottom, top, -100, 100); // Select Ortho Mode
glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
glPushMatrix(); // Push The Matrix
glLoadIdentity(); // Reset The Matrix
//Initialize variables
SPointData point1, point2, point3, point4;
//Paint on buffer
//.................<some painting task>................
//Switch to perspective mode
glMatrixMode(GL_PROJECTION); // Select Projection
glPopMatrix(); // Pop The Matrix
glMatrixMode(GL_MODELVIEW); // Select Modelview
glPopMatrix(); // Pop The Matrix
fbObject.release();
return fbObject.toImage();
I'm attempting to draw an eclipse-shaped object so I used a sphere and scaled it as necessary. I'm attempting to rotate this eclipse-shaped object with the following code but it won't budge (or at least it doesn't look like it's budging). I've tested by simply changing to another 3D shape and it rotates. Is there something I'm doing wrong? What's so different about a glutSolidSphere?
glPushMatrix();
glTranslatef(subx, suby + y, subz);
glScalef(9.0, 1.75, 1.75);
glRotatef(angle, 0, 1, 0);
glTranslatef(-subx, -suby, -subz);
glTranslatef(subx, suby, subz);
glutSolidSphere(1.0, 50, 50);
glPopMatrix();
Issue as pointed out above in comments was that I was rotating the sphere before I stretched it. Scaling and then rotating fixed the issue.
glPushMatrix();
glTranslatef(subx, suby + y, subz);
glRotatef(angle, 0, 1, 0);
glScalef(9.0, 1.75, 1.75);
glTranslatef(-subx, -suby, -subz);
glTranslatef(subx, suby, subz);
glutSolidSphere(1.0, 50, 50);
glPopMatrix();
I am rather new to programming so I may not use the correct terminology. I am trying to create a dog out of only glutwirecubes, however I cannot figure out how to define a starting position for the back legs, nor can I figure out how to close the space between my 'shoulder' and 'elbows'. I have each body part assigned to rotate by key press. I also realize that my use of glPushMatrix and glPopMatrix may not be correct as I do not fully understand how the matrix stack is saved/loaded.
glPushMatrix();
glTranslatef(-1, 0, 0);
glRotatef((GLfloat)body,1, 0, 0);//sets rotations about x,y,z axis
glTranslatef(1, 0, 0);
glPushMatrix();
glScalef(2.0, 0.4, 0.5);//sets dimensions of cube
glutWireCube(2.0);//sets scale of wire cube
glPopMatrix();
glPopMatrix();
glPushMatrix();
glTranslatef(-1, 0, 0);
glRotatef((GLfloat)shoulder, 0, 0, 1);//sets rotations about x,y,z axis
glTranslatef(1, 0, 0);
glPushMatrix();
glScalef(1.5, 0.4, 0.5);//sets dimensions of cube
glutWireCube(.75);//sets scale of wire cube
glPopMatrix();
glTranslatef(1,0,0);
glRotatef((GLfloat)elbow,0,0,1);//sets rotations about x,y,z axis
glTranslatef(1,0,0);
glPushMatrix();
glScalef(1.5,0.4,0.5);//sets dimensions of cube
glutWireCube(.75);//sets scale of wire cube
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
The picture is the position I am aiming for, however my cubes always start oriented horizontally.
with glTranslate right before, as for its friends !
For instance you might translate so that the center is now at the corner, so that your rotations rotate around this new handle.
I am trying to draw this object:
So far, I've gotten this, the first half draws the bottom section, the second half draws the top section:
glPushMatrix();
glScalef(1, length/largeWidth, 1);
glTranslatef(0, largeWidth/2, 0);
glutSolidCube(largeWidth);
glPopMatrix();
glPushMatrix();
glScalef(1, length/smallWidth, 1);
glTranslatef(0, smallWidth/2 + length, 0);
glutSolidCube(smallWidth);
glPopMatrix();
But this is giving me the wrong answer, there is a very large gap between the two sections, they don't meet, as if the top section's translation in the y direction is too large, but I dont see why.
UPDATE
See bottom for update.
I've been looking alot around the internet and I have found a few tutorials that explain what I'm trying to achieve but I can't get it to work, either the tutorial is incomplete or not applicable on my code.
I'm trying something as simple as rotating a 2D image around its origin (center).
I use xStart, xEnd, yStart and yEnd to flip the texture which are either 0 or 1.
This is what the code looks like
GameRectangle dest = destination;
Vector2 position = dest.getPosition();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, this->image);
//If the rotation isn't 0 we'll rotate it
if (rotation != 0)
{
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5, 0.5, 0);
glRotatef(rotation, 0, 0, 1);
glMatrixMode(GL_PROJECTION);
}
glBegin(GL_QUADS);
glTexCoord2d(xStart,yStart);
glVertex2f(position.x, position.y);
glTexCoord2d(xEnd,yStart);
glVertex2f(position.x + this->bounds.getWidth(), position.y);
glTexCoord2d(xEnd,yEnd);
glVertex2f(position.x + this->bounds.getWidth(), position.y + this->bounds.getHeight());
glTexCoord2d(xStart,yEnd);
glVertex2f(position.x, position.y + this->bounds.getHeight());
glEnd();
glDisable(GL_TEXTURE_2D);
//Reset the rotation so next object won't be rotated
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glRotatef(0, 0, 0, 1);
glMatrixMode(GL_PROJECTION);
This code will draw the image in it's original size and it will rotate it, but it will rotate it from the top left corner which crops the image a lot. By calling GameRectangle.getOrigin() I can easily get the center of the rectangle, but I don't know where to use it.
Bit if put:
glTranslatef(-0.5, -0.5, 0);
After I call the:
glRotatef(0.5, 0.5, 0);
It will rotate from the center, but it will strech the image if it's not a perfect 90 degrees rotation.
UPDATE
After trying pretty much everything possible, I got the result I was looking for.
But I'm not sure if this is the best approach. Please tell me if there's something wrong with my code.
As I mentioned in a comment above, I use the same image multiple times and draw it with different values, so I can't save anything to the actual image. So I must reset the values everytime after I have rendered it.
I changed my code to this:
//Store the position temporary
GameRectangle dest = destination;
Vector2 position = dest.getPosition();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, this->image);
glTranslatef(dest.getOrigin().x, dest.getOrigin().y, 0);
glRotatef(rotation, 0, 0, 1);
glBegin(GL_QUADS);
glTexCoord2d(xStart,yStart);
glVertex2f(-dest.getWidth()/2, -dest.getHeight()/2);
glTexCoord2d(xEnd,yStart);
glVertex2f(dest.getWidth()/2, -dest.getHeight()/2);
glTexCoord2d(xEnd,yEnd);
glVertex2f(dest.getWidth()/2, dest.getHeight()/2);
glTexCoord2d(xStart,yEnd);
glVertex2f(-dest.getWidth()/2, dest.getHeight()/2);
glEnd();
//Reset the rotation and translation
glRotatef(-rotation,0,0,1);
glTranslatef(-dest.getOrigin().x, -dest.getOrigin().y, 0);
glDisable(GL_TEXTURE_2D);
This rotates the texture together with the quad it's drawn in, it doesn't strech or crop. However the edges are a bit jagged if the image is filled square but I guess I can't avoid that with out antialiasing.
What you want is this:
glPushMatrix(); //Save the current matrix.
//Change the current matrix.
glTranslatef(dest.getOrigin().x, dest.getOrigin().y, 0);
glRotatef(rotation, 0, 0, 1);
glBegin(GL_QUADS);
glTexCoord2d(xStart,yStart);
glVertex2f(-dest.getWidth()/2, -dest.getHeight()/2);
glTexCoord2d(xEnd,yStart);
glVertex2f(dest.getWidth()/2, -dest.getHeight()/2);
glTexCoord2d(xEnd,yEnd);
glVertex2f(dest.getWidth()/2, dest.getHeight()/2);
glTexCoord2d(xStart,yEnd);
glVertex2f(-dest.getWidth()/2, dest.getHeight()/2);
glEnd();
//Reset the current matrix to the one that was saved.
glPopMatrix();