OpenGL color changing automatically and expand automatically - c++

Trying to make some effect on these 2D shapes
How do I make the quad shape change color automatically without user interactive. Like a constant cycle of color from red, yellow and green?
void changecolor() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glVertex2f(0.0, 0.8);
glVertex2f(-0.2, 0.3);
glVertex2f(0.0, 0.0);
glVertex2f(0.2, 0.3);
glEnd();
}
Trying to make the quad to slow expansion animation as i run it. Currently it just shows the final expanded result as i run.
void q4() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(15, 15, 0);
glBegin(GL_QUADS);
glColor3f(1.0, 0, 0);
glVertex2f(0.1, 0.1);
glVertex2f(0.1, -0.1);
glVertex2f(-0.1, -0.1);
glVertex2f(-0.1, 0.1);
glEnd();
}

Related

How to prevent scaling lower than defined (OpenGL)

I have a simple OpenGL object which has defined certain glScalef size. It needs glutMouseFunc to make it work as I imagined. So, this is what I've imagined:
On GLUT_LEFT_BUTTON object needs to go bigger for 0.1, so:
glScalef(scalesize+0.1,scalesize+0.1,0.0.);
polygon();
On GLUT_RIGHT_BUTTON object needs to go smaller for 0.1, so:
glScalef(scalesize-0.1,scalesize-0.1,0.0);
polygon();
This is my polygon function:
void polygon(void){
glBegin(GL_POLYGON);
glColor3f(1.0,0.0,0.0);
glVertex2f(-0.15, -0.15);
glColor3f(0.0,0.0,0.0);
glVertex2f(-0.15, 0.15);
glColor3f(0.0,0.0,1.0);
glVertex2f(0.15, 0.15);
glColor3f(0.0,1.0,0.0);
glVertex2f(0.15, -0.15);
glEnd();
glEnable (GL_LINE_STIPPLE);
glLineWidth(3.0);
glLineStipple (6, 0x1C47);
glBegin(GL_LINES);
glColor3f(0.0,0.0,0.0);
glVertex2f(-0.25, -0.25);
glVertex2f(-0.25, 0.25);
glVertex2f(0.25, 0.25);
glVertex2f(0.25, -0.25);
glVertex2f(-0.25, 0.25);
glVertex2f(0.25, 0.25);
glVertex2f(-0.25, -0.25);
glVertex2f(0.25, -0.25);
glEnd();
}
This is my scene function:
void scene(void){
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glScalef(scalesize,scalesize,0.0);
polygon();
glPopMatrix();
glFlush();
}
float scalesize = 1.0;
Now I'm not sure how to prevent scaling lower than 0.15, regarding to my object size. I've tried with if statement to check if scalesize is bigger than 1.0, but didn't worked. Any solutions?
Thanks
Ok, thanks to #radical7 I've figured it out. Already did everything what he said, but the real solution was to let scene function do its job, I didnt have to call glScalef in my mouse function.
Thanks again.

glPushMatrix() glPopMatrix() doesn't work

I try to code two object move independent which mean both are moving two different direction it's worked but it can't move continuous. when i put glTranslatef() at outside the glPushMatrix() ... glPopMatrix() it work normally.
void display()
{
glClearColor(0.356, 0.701, 0.0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// if put gltransate() at here the object will moving continuous
glPushMatrix();
glTranslatef(.5, 0, 0);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(-0.8, 0.5);
glVertex2f(-0.8, 0.8);
glVertex2f(-0.2, 0.8);
glVertex2f(-0.2, 0.5);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef(-.5, 0, 0);
glBegin(GL_QUADS);
glColor3f(.0, .0, .0);
glVertex2f(-0.8, 0.2);
glVertex2f(-0.8, 0.5);
glVertex2f(-0.2, 0.5);
glVertex2f(-0.2, 0.2);
glEnd();
glPopMatrix();
}
i expect the for the first square objects will go to the right constantly but it seem like just translate once then stop at the position.
Note, in general I recommend to use a math library like OpenGL Mathematics to do the matrix calculations and glLoadMatrix() to load a matrix of type glm::mat4 to the current matrix.
Anyway, an operation like glTranslatef() creates a new matrix and multiplies the current matrix by the new matrix. That's why consecutive calls to glTranslatef cause progressive "movement".
glPushMatrix / glPopMatrix store and restore the matrix on the matrix stack. So the consecutive movement can't work, because the current matrix stays the same at the begin of each frame.
One solution would be to store the translation to a variable and increment the variable:
GLfloat trans_a = 0.0f;
GLflaot trans_b = 0.0f;
void display()
{
glClearColor(0.356, 0.701, 0.0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
trans_a += 0.5f;
glTranslatef(trans_a, 0, 0);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(-0.8, 0.5);
glVertex2f(-0.8, 0.8);
glVertex2f(-0.2, 0.8);
glVertex2f(-0.2, 0.5);
glEnd();
glPopMatrix();
glPushMatrix();
trans_b += 0.5f;
glTranslatef(trans_b, 0, 0);
glBegin(GL_QUADS);
glColor3f(.0, .0, .0);
glVertex2f(-0.8, 0.2);
glVertex2f(-0.8, 0.5);
glVertex2f(-0.2, 0.5);
glVertex2f(-0.2, 0.2);
glEnd();
glPopMatrix();
}
A more generalized solution is to get and store the current matrix (after the translation) by glGetFloatv(GL_MODELVIEW_MATRIX, ...) and to reload it by glLoadMatrix():
// init identity matrices
GLfloat mat_a[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
GLfloat mat_b[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
void display()
{
glClearColor(0.356, 0.701, 0.0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glLoadMatrixf(mat_a)
glTranslatef(0.5f, 0, 0);
glGetFloatv(GL_MODELVIEW_MATRIX, mat_a);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(-0.8, 0.5);
glVertex2f(-0.8, 0.8);
glVertex2f(-0.2, 0.8);
glVertex2f(-0.2, 0.5);
glEnd();
glPopMatrix();
glPushMatrix();
glLoadMatrixf(mat_b)
glTranslatef(0.5f, 0, 0);
glGetFloatv(GL_MODELVIEW_MATRIX, mat_b);
glBegin(GL_QUADS);
glColor3f(.0, .0, .0);
glVertex2f(-0.8, 0.2);
glVertex2f(-0.8, 0.5);
glVertex2f(-0.2, 0.5);
glVertex2f(-0.2, 0.2);
glEnd();
glPopMatrix();
}
Note, in this case mat_a and mat_b should be loaded after the initialization of the view matrix and when the view matrix changes, then the matrices would not consider that.

Colors disappear after drawing image

I am trying to draw a sphere and a cube at the same time on my screen. But the colors of my cube(which gets drawn first) dissapear. I don't understand why.
the sphere on the right is fine. But my cube on the left isn't.
I added texture to both:
I can perfectly draw both of them seperately, but when I try to draw both of them on one widget something goes wrong.
I tought the popping and pushing would solve this issue, but it doesn't.
code:
void MyGLWidget::drawCube()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(position,0.5,-0.1,-0.5,-0.5,0,0,0,1);
glTranslatef( 0.5, 0, 0.0);
glRotatef(getCubeAngle(), 1.0f, 0.0f, 0.0f);
glTranslatef(0, 0, 0);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
//back
glTexCoord2f(0.0, 1.0); glVertex3f(-0.1, 0.1,-0.1 );
glTexCoord2f(1.0, 1.0); glVertex3f(0.1, 0.1,-0.1);
glTexCoord2f(1.0, 0.0); glVertex3f(0.1,-0.1,-0.1);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.1,-0.1,-0.1);
/*rest of cube gets drawn*/
glEnd();
glFlush();
glPopMatrix();
}
void MyGLWidget::drawSun()
{
glPushMatrix();
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texturePlanet[0]);
glPushMatrix();
glScalef(1,1,1);
glLoadIdentity();
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricTexture(quadric, GLU_TRUE);
gluQuadricNormals(quadric, GLU_SMOOTH);
glEnable(GL_TEXTURE_2D); //
glBindTexture(GL_TEXTURE_2D,texturePlanet[0]);//
gluSphere(quadric, 0.25, 360,360);
glDisable(GL_TEXTURE_2D);//
gluDeleteQuadric(quadric);
glPopMatrix();
}
void MyGLWidget::paintGL()
{
drawCube();
drawSun();
}
It is because In your cube drawing, you didn't enable texturing.
glEnable(GL_TEXTURE_2D); //ADD THIS TO ENABLE TEXTURING
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
//back
glTexCoord2f(0.0, 1.0); glVertex3f(-0.1, 0.1,-0.1 );
glTexCoord2f(1.0, 1.0); glVertex3f(0.1, 0.1,-0.1);
glTexCoord2f(1.0, 0.0); glVertex3f(0.1,-0.1,-0.1);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.1,-0.1,-0.1);
/*rest of cube gets drawn*/
glEnd();
glFlush();
glPopMatrix();
glDisable(GL_TEXTURE_2D); // ADD THIS TO DISABLE TEXTURING

qt openGL - sphere gets disformed

I am trying to draw a sphere and a rotating cube around it. I am able to draw both of them perfectly seperately. Nevertheless once I draw both together I get strange results.
my sphere gets disformed.
when I change the angle of my cubeon purpose (by pressing on a button) it just dissapears from my screen.
when I only draw the cube and theng change the angle everything works fine.
Why please?
image: http://imgur.com/dIngayh (the cube looks ok, but the sphere is too stretched)
My code:
void MyGLWidget::paintGL()
{
glScalef(1,1,1);
setLight();
drawSun();
drawCube();
}
void MyGLWidget::initializeGL()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
}
void MyGLWidget::drawSun()
{
glPushMatrix();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glScalef(1,1,1);
glLoadIdentity();
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
glColor3f(1,1,0);
gluSphere(quadric, 0.25, 360,360);
gluDeleteQuadric(quadric);
glPopMatrix();
}
void MyGLWidget::drawCube()
{
glTranslatef(0, 0, 0);
glRotatef(getCubeAngle(), 1.0f, 0.0f, 0.0f);
glRotatef(0, 0.0f, 1.0f, 0.0f);
glRotatef(0, 0.0f, 0.0f, 1.0f);
glTranslatef( 0.5, 0, 0);
glBegin(GL_QUADS);
//back side of cube
glColor3f(255,0,0);
glVertex3f(-0.1, 0.1,-0.1 );//upper left corner
glVertex3f(0.1, 0.1,-0.1); //uper right
glVertex3f(0.1,-0.1,-0.1 ); // down left
glVertex3f(-0.1,-0.1,-0.1); // down right
/*draws other parts of the cube in the same way*/
glEnd();
glFlush();
}
/**/
void MyGLWidget::setLight()
{
// Prepare light parameters.
float SHINE_ALL_DIRECTIONS = 1;
float lightPos[4] = {-30, 0, 0, SHINE_ALL_DIRECTIONS};
float lightColorAmbient[4] = {50, 50, 0.1, 1};
float lightColorSpecular[4] = {150, 150, 0.5, 1};
// Set light parameters.
glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
glLightfv(GL_LIGHT1, GL_AMBIENT, lightColorAmbient);
glLightfv(GL_LIGHT1, GL_SPECULAR, lightColorSpecular);
// Enable lighting in GL.
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
// Set material properties.
float rgba[3] = {0.3, 0.5, 1};
glMaterialfv(GL_FRONT, GL_AMBIENT, rgba);
glMaterialfv(GL_FRONT, GL_SPECULAR, rgba);
glMaterialf(GL_FRONT, GL_SHININESS, 0.5f);
}
try to add this one:
void MyGLWidget::resizeGL(int width, int height);
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(height *1./width, 1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
and more read here (rus)

OpenGL project, using tessellation on a polygon rendered car

Ok so im seperating my problem up because i need a depthy answer cos im nooby with it and will fail if i have just a generalisation answer.
I have a car body which i originally drew using line_loop and have changed it to polygon so i can texture it. however it ignores the wheel arches like so.
(ignore the texturing for now, i need to figure that one out another time ;) )
This is what my car looks like with line_loop
If the way to make the wheel arches with polygon makes it a smoother circle then even better :)
This is my current code, (ignore the texture stuff) I did start tessellation with a prod in that direction from an earlier question but not sure exactly how to use it and which coords to pass etc etc. Thanks for all your help!!
void drawBody(int textureindex)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureLib[textureindex]);
GLUtesselator *tess = gluNewTess(); // create a tessellator
if(!tess) return 0; // failed to create tessellation object, return 0
glBegin(GL_POLYGON);
glTexCoord2f(0.0F, 0.0F);
glVertex2f(-1.0f, 0.0f);
glTexCoord2f(-0.97, 0.0);
glVertex2f(-1.97f, 0.0f);
//wheel arch begin.
glTexCoord2f(-0.93, 0.3);
glVertex2f(-1.93f, 0.3f);
glTexCoord2f(-0.95, 0.4);
glVertex2f(-1.95f, 0.4f);
glTexCoord2f(-1.2, 0.6);
glVertex2f(-2.2f, 0.6f);
glTexCoord2f(-1.6, 0.6);
glVertex2f(-2.6f, 0.6f);
glTexCoord2f(-1.82, 0.4);
glVertex2f(-2.82f, 0.4f);
glTexCoord2f(-1.8, 0.3);
glVertex2f(-2.8f, 0.3f);
glTexCoord2f(-1.78, 0.0);
glVertex2f(-2.78f, 0.0f);
//end wheel arch.
//Front of car.
glTexCoord2f(0.0, 0.0);
glVertex2f(-3.8f, 0.0f);
glTexCoord2f(0.0, 0.2);
glVertex2f(-3.7f, 0.2f);
glTexCoord2f(0.0, 0.4);
glVertex2f(-3.8f, 0.4f);
glTexCoord2f(0.0, 0.7);
glVertex2f(-2.8f, 0.7f);
glTexCoord2f(0.0, 0.7);
glVertex2f(-2.4f, 0.7f);
//Windscreen.
glTexCoord2f(0.0, 1.0);
glVertex2f(-1.0f, 1.0f);
glTexCoord2f(1.0, 1.0);
glVertex2f(0.5f, 1.05f);
glTexCoord2f(1.0, 0.8);
glVertex2f(2.3f, 0.8f);
//rear bumper.
glTexCoord2f(1.0, 0.5);
glVertex2f(2.15f, 0.5f);
glTexCoord2f(1.0, 0.3);
glVertex2f(2.15f, 0.3f);
glTexCoord2f(1.0, 0.3);
glVertex2f(2.35f, 0.3f);
glTexCoord2f(1.0, 0.0);
glVertex2f(2.0f, 0.0f);
glTexCoord2f(1.0, 0.0);
glVertex2f(1.83f, 0.0f);
//wheel arch begin.
glTexCoord2f(1.0, 0.3);
glVertex2f(1.85f, 0.3f);
glTexCoord2f(1.0, 0.4);
glVertex2f(1.86f, 0.4f);
glTexCoord2f(1.0, 0.6);
glVertex2f(1.6f, 0.6f);
glTexCoord2f(1.0, 0.6);
glVertex2f(1.2f, 0.6f);
glTexCoord2f(1.0, 0.4);
glVertex2f(1.0f, 0.4f);
glTexCoord2f(1.0, 0.3);
glVertex2f(1.0f, 0.3f);
glTexCoord2f(1.0, 0.0);
glVertex2f(1.05f, 0.0f);
//end wheel arch.
glEnd();
glDisable(GL_TEXTURE_2D);
}
Revised code for tessellation, (only attempted on one wheel arch so far and has had no affect).
GLdouble car[7][2] = { {-1.93,0.3}, {-1.95,0.4}, {-2.2,0.6}, {-2.6,0.6}, {-2.82,0.4}, {-2.8,0.3}, {-2.78,0.0} };
GLUtesselator *tess = gluNewTess(); // create a tessellator
gluTessBeginPolygon(tess, 0);
gluTessBeginContour(tess);
{
gluTessVertex(tess, car[0], car[0]);
gluTessVertex(tess, car[1], car[1]);
gluTessVertex(tess, car[2], car[2]);
gluTessVertex(tess, car[3], car[3]);
gluTessVertex(tess, car[4], car[4]);
gluTessVertex(tess, car[5], car[5]);
gluTessVertex(tess, car[6], car[6]);
}
gluTessEndContour(tess);
gluTessEndPolygon(tess);
Thanks for all your help, the final image looks like this:
Again thanks for all your help! Especially PeterT :)
You are not using the tessellator at all. Feeding the coordinates to the tessellator will look something like this
gluTessBeginContour(tess);
:
gluTessVertex(tess, v[i], v[i]);
:
gluTessEndContour(tess);
Read here and grab the examples http://www.songho.ca/opengl/gl_tessellation.html
GL_POLYGON is used for drawing convex polygons. Your car is not convex, so you can't draw everything in one go (glBegin.. glEnd). Split car into multiple parts that have different primitive types. GL_POLYGON can't be used for everything.
You aren't even using your tesselator.
Bottom line is that your question is very basic. Before going further with OpenGL, finish "OpenGL red book", that covers pretty much all basic information. Version 1.1 is available online for free in several different places.