how to use glTranslatef,glScalef,glRotatef in openGL - c

I just want something like this video : https://youtu.be/dGWtdYlryQQ
It shows how to use glTranslate, glRotate, gluOrtho2d in OpenGL ,but it's not guide me anything
In my case, I draw a diamond instead of triangle and here is my condition
condition :
when I press r or R on the keyboard the diamond will rotate clockwise
when I press t or T on the keyboard the diamond will move to the right side
when I press + on the keyboard the diamond will bigger
here is my code :
#include <stdlib.h>
#include <windows.h>
#include <GL/glut.h>
#include <iostream>
using namespace std;
float angle = 0;
float t,s=0.5,m=0;
void myinit(void){
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
}
void keyboard(unsigned char key, int x, int y){
if(key==27)
{
exit(0);
}else if(key == 82 || key == 114){
angle-=0.1;
glRotatef(angle,0,0,1);
glutPostRedisplay();
}else if(key == 84 || key == 116 )
{
t+=0.01;
glTranslatef(t,0,0);
glutPostRedisplay();
}else if(key == 43){
s+=0.01;
// m-=0.1;
// glTranslatef(m,m,0.0);
glScalef(s,s,0);
glutPostRedisplay();
}
(void)(x);
(void)(y);
}
void hut(void){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.5,0.4,0.0);
glVertex3f(0.42,0.5,0.0); // GREEN
glVertex3f(0.44,0.5,0.0);
glColor3f(1.5,1.0,0.0);
glVertex3f(0.46,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.57,0.5,0.0);
glEnd();
glFlush();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.44,0.55,0.0);
glVertex3f(0.42,0.5,0.0);
glVertex3f(0.46,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.48,0.55,0.0);
glEnd();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.48,0.55,0.0);
glVertex3f(0.46,0.5,0.0);
glVertex3f(0.50,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.52,0.55,0.0);
glEnd();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.52,0.55,0.0);
glVertex3f(0.50,0.5,0.0);
glVertex3f(0.54,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.56,0.55,0.0);
glEnd();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.56,0.55,0.0);
glVertex3f(0.54,0.5,0.0);
glVertex3f(0.57,0.5,0.0);
glEnd();
glFlush();
}
int main(int argc,char** argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(640,480);
glutCreateWindow("Polygon with viewport");
myinit();
glutDisplayFunc(hut);
glutKeyboardFunc(keyboard);
glutMainLoop();
}
And here is my output : https://drive.google.com/file/d/14HHRiCbOHK9ZSZtDOqSl4GP4aSy7UQLh/view?usp=sharing
It it’s not similar to this https://youtu.be/dGWtdYlryQQ

The operations on the matrix stack are based on one another. The reference system of each operation is the current transformation.
See the documentation of glTranslate:
glTranslate produces a translation by x y z . The current matrix (see glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix, [...]
and see the documentation of glRotate:
glRotate produces a rotation of angle degrees around the vector x y z . The current matrix (see glMatrixMode) is multiplied by a rotation matrix with the product replacing the current matrix.
This means that glRotate does a rotation around the origin of the current local system.
While glRotatetf followed by glTranslatef results in:
glTranslatef followed by glRotatef results in:
Since you object is displaced, you have to translate it in that way, that the rotation point is placed in the origin:
glTranslatef(-0.5f, -0.5f, 0.0f);
Then you can rotate it:
glRotatef(angle, 0.0f, 0.0f, 1.0f);
And move it back:
glTranslatef(0.5f, 0.5f, 0.0f);
Note, on the Fixed Function Pipeline stack you have to "push" this operations in the reverse order. Further you should use the GL_MODELVIEW matrix stack. (See glMatrixMode.)
Remove all the matrix operations from the function keyboard and add the following to the function hut:
void hut(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(t, 0.0f, 0.0f);
glTranslatef(0.5f, 0.5f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glScalef(s, s, 0.0f);
glTranslatef(-0.5f, -0.5f, 0.0f);
.....
Further, your object gets destroyed by the aspect ratio of the view. This can be fixed by taking care of the aspect ratio when setting up the projection matrix:
float w = 640.0f;
float h = 480.0f;
glOrtho(0.0,w/h,0.0,1.0,-1.0,1.0);

glRotate rotates about the origin (0,0). Given your projection matrix (that you set with glOrtho) the origin is initially at the lower left corner of your screen, unless you use glTranslate. Your diamond is not centered at the origin, but positioned somewhat away from it. What you need to do is change the vertex values in your void hut(void) method to make the diamond centered at 0,0. Then use glTranslate to move the render origin (and thus also the diamond) to where you want it, then use glRotate.

Related

Object not rendering after adding transformations

I'm adding transformations to my C OpenGL program. I'm using CGLM as my maths library. The program has no warnings or errors. Still however, when I compile and run the program, I simply get a window coloured my clear colour. The following is my program's main loop
// Initialize variables for framerate counting
double lastTime = glfwGetTime();
int frameCount = 0;
// Program loop
while (!glfwWindowShouldClose(window)) {
// Calculate framerate
double thisTime = glfwGetTime();
frameCount++;
// If a second has passed.
if (thisTime - lastTime >= 1.0) {
printf("%i FPS\n", frameCount);
frameCount = 0;
lastTime = thisTime;
}
processInput(window);
// Clear the window
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Bind textures on texture units
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
// Create transformations
mat4 transform = {{1.0f}};
glm_translate(transform, (vec3){0.5f, -0.5f, 0.0f});
glm_rotate(transform, (float)glfwGetTime(), (vec3){0.0f, 0.0f, 1.0f});
printf("%i\n", transform);
// Get matrix's uniform location and set matrix
shaderUse(myShaderPtr);
GLint transformLoc = glGetUniformLocation(myShaderPtr->shaderID, "transform");
printf("%i\n", transformLoc);
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, *transform);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window); // Swap the front and back buffers
glfwPollEvents(); // Check for events (mouse movement, mouse click, keyboard press, keyboard release etc.)
}
The Program is up on github here if you'd like to check out the full code.
The output of this program is
However, the intended output is a spinning box with my profile picture on it.
mat4 transform = {{1.0f}}; does not do what you expect. C doesn't have a constructor like C++. The C++ version's constructor initialized the matrix with the Identity matrix. You have to use glm_mat4_identity to initialize with the identity matrix:
mat4 transform;
glm_mat4_identity(transform);
glm_rotate(transform, (float)glfwGetTime(), (vec3){0.0f, 0.0f, 1.0f});
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, (float*)transform);
Additionally, you need to specify and add an orthographic projection matrix that compensates for the aspect ratio of the viewport:
float aspect = (float)width / (float)height;
mat4 projection;
glm_ortho(-aspect, aspect, -1.0f, 1.0f, -1.0f, 1.0f, projection)
mat4 transform;
glm_rotate(transform, (float)glfwGetTime(), (vec3){0.0f, 0.0f, 1.0f});
glm_mat4_identity(transform);
mat4 mvp;
glm_mat4_mul(projection, transform, mvp);
GLint transformLoc = glGetUniformLocation(myShaderPtr->shaderID, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, (float*)mvp);

Make some shapes in OpenGL to be moved with arrow keys - it zooms out instead of moving

Well, I have the following C code on a GLUT Project (I use CodeBlocks).
It draw some 2D shapes (something like Robot :p ).
I want to make the whole drawing shapes to be moved with the keyboard arrow keys. I have wrote the following, but for some reason when I push the arrow keys, it seems like it zoom in/out. It does not move.
#include <GL/glut.h>
GLuint head_x1=5, head_y1=30, head_x2=15, head_y2=30, head_x3=15,head_y3=40, head_x4=5,head_y4=40;
// shape
GLuint listID;
void MrRobot(GLsizei displayListID)
{
glNewList(displayListID,GL_COMPILE);
//Save current colour state
glPushAttrib(GL_CURRENT_BIT);
// body
glColor3f(0.5,0.5,0.5);
glBegin(GL_POLYGON);
glVertex2f(0,10);
glVertex2f(20,10);
glVertex2f(20,30);
glVertex2f(0,30);
glEnd();
// head
glColor3f(0,0,1);
glBegin(GL_POLYGON);
glVertex2f(head_x1,head_y1);
glVertex2f(head_x2,head_y2);
glVertex2f(head_x3,head_y3);
glVertex2f(head_x4,head_y4);
glEnd();
// legs
glColor3f(1,0,0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(10,10);
glVertex2f(20,0);
glVertex2f(10,-5);
glVertex2f(0,0);
glEnd();
// right hand
glColor3f(0,1,0);
glBegin(GL_TRIANGLES);
glVertex2f(20,30);
glVertex2f(30,27.5);
glVertex2f(20,25);
glEnd();
// left hand
glColor3f(0,1,0);
glBegin(GL_TRIANGLES);
glVertex2f(-10,27.5);
glVertex2f(0,30);
glVertex2f(0,25);
glEnd();
//Recall saved colour state
glPopAttrib();
glEndList();
}
void display()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,0,0);
//Defining a modelview transform matrix
glScalef(0.3,0.3,0.3);
//Execute the display list (the modelview matrix will be applied)
glCallList(listID);
glFlush();
}
void keyboard(unsigned char key,int x, int y)
{
printf("\nKeyboard event detected. \nCharacter key: %c\nMouse pointer position: x=%d y=%d",key,x,y);
if (key==GLUT_KEY_UP)
{
head_y1++;
head_y2++;
head_y3++;
head_y4++;
}
if (key==GLUT_KEY_DOWN)
{
head_y1--;
head_y2--;
head_y3--;
head_y4--;
}
if (key==GLUT_KEY_LEFT)
{
head_x1--;
head_x2--;
head_x3--;
head_x4--;
}
if (key==GLUT_KEY_RIGHT)
{
head_x1++;
head_x2++;
head_x3++;
head_x4++;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitWindowPosition(50,50);
glutInitWindowSize(800,600);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("Mr Robot");
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-5,35,-5,30);
listID=glGenLists(1);
MrRobot(listID);
glutDisplayFunc(display);
glutSpecialFunc(keyboard);
glutMainLoop();
return 0;
}
Maybe is something with the axis, but have no idea what I should change.
Any help?
Well there are a lot of problems. You seem to be writing OpenGL a little bit differently.
Anyways here is the problem.
The reason its scaling is because everytime you call display you are calling glScalef(0.3, 0.3, 0.3); without loading the identity matrix.
Also when you press a key the increment is happening but you havent even called MrRobot() in the display function. You have only called it once in the main function
Also just before you call display you must call glMatrixMode(GL_MODELVIEW); or else all transformations you do will affect the GL_PROJECTION matrix

OpenGL - Rotating moon around sun without it spinning?

I'm working on a graphics model of the Moon rotating around the Earth. Right now, the Moon spins on its y axis while rotating around the Earth. How can I prevent the Moon from spinning but still allow it to orbit? Here's the code..
Edit:
Added an animation video to demonstrate problem:
http://www.youtube.com/watch?v=ltGV4pXD5Cs
void DrawInhabitants(GLint nShadow)
{
static GLfloat yRot = 0.0f; // Rotation angle for animation
if(nShadow == 0)
{
yRot += 0.2f;
}
// Draw the randomly located spheres
glBindTexture(GL_TEXTURE_2D, textureObjects[MOON_TEXTURE]);
glPushMatrix();
glTranslatef(0.0f, 0.1f, -2.5f);
glPushMatrix();
glRotatef(-yRot * 2.0f, 0.0f, 1.0f, 0.0f);
glTranslatef(1.0f, 0.0f, 0.0f);
gltDrawSphere(0.1f,21, 11);
glPopMatrix();
if(nShadow == 0)
{
// Torus alone will be specular
glMaterialfv(GL_FRONT, GL_SPECULAR, fBrightLight);
}
glRotatef(-yRot, 0.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, textureObjects[EARTH_TEXTURE]);
gltDrawSphere(0.3f, 21, 11);
glMaterialfv(GL_FRONT, GL_SPECULAR, fNoLight);
glPopMatrix();
}
The problem is that you're rotating the coordinate system in order to place the moon in its desired relative position. This rotation is global so it affects the orientation of the moon as well. You need to undo the rotation after translating, so you have "translation sandwich"
rotate a
translate
rotate -a

Unable to render a color cube

I am trying to draw a color cube in OpenGL. All I am getting is a square.
(Is only one face of the cube visible in the output? I tried calling gluLookAt(), but that didn't make any difference to the output.)
This is my code:
#include<GL/glut.h>
#include<math.h>
float vertices[8][3]={{0,0,0},{0,0,200},{0,200,0},{200,0,0},{0,200,200},{200,0,200},{200,200,0},{200,200,200}};
float colors[8][3]={{0.6,0.9,0.1},{0.2,0.1,0.3},{0.7,0.7,0.5},{0.2,0.7,0.4},{0.6,0.6,0.4},{0.1,0.1,0.5},{0.7,0.2,0.5},{0.9,0.7,0.4}};
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBegin(GL_POLYGON);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glEnd();
glBegin(GL_POLYGON);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glEnd();
glBegin(GL_POLYGON);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glEnd();
glBegin(GL_POLYGON);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glEnd();
glBegin(GL_POLYGON);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glEnd();
glBegin(GL_POLYGON);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glEnd();
glFlush();
}
void init()
{
glClearColor(1.0,1.0,1.0,0);
glEnable(GL_DEPTH_TEST);
glOrtho(-960,960,-720,720,-600,600);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(960,720);
glutInitWindowPosition(0,0);
glutCreateWindow("Color Cube");
glutDisplayFunc(display);
init();
glutMainLoop();
}
You are requesting a double-buffered framebuffer via the GLUT_DOUBLE flag. So you have a back buffer you are drawing into, and a front buffer which is shown in the window. When you are finished with drawing, you have to swap those buffers so that the things you have drawn now become visible and you can draw the next frame (without destroying the currently visible image). Just replace that glFlush(); at the end of your display() function by a glutSwapBuffers() call and your rendering should become visible.
Try using push and pop matrix
ex.
glPushMatrix();
//your cube's code
glPopMatrix();
glFlush();
If you want to see more than 1 side of your cube, you will need to rotate your cube.
Look up the glRotate() function, which multiplies the current matrix by a rotation. Applying this rotation (before drawing the cube) will effectively rotate your cube by a given angle, about the specified axis.

rotate shape become rotate and translating

I'm new on using openGL, and now I'm trying to rotate the square i made, but when I rotate it, the square doesn't only rotate, but also moving around while rotating. I think I made a mistake on the rotate and translate process, but cannot find the the solution
void drawSquare(double x,double y, int num)
{
double xLength = 0.6;
double yLength = 0.6;
for(int i=0;i<num;i++)
{
glLoadIdentity();
glPushMatrix();
glTranslatef(0, 0, 0.0f);
glRotatef(angleCW, 0.0f, 0.0f,1.0f);
glBegin( GL_QUADS );
if(i%2==0)
{
glColor3f(gCurrentRed,gCurrentGreen,gCurrentBlue);
}
else
{
glColor3f(0.0f,0.0f,0.0f);
}
glVertex3f(x,y,0);
glVertex3f(x+xLength,y,0);
glVertex3f(x+xLength,y+yLength,0);
glVertex3f(x,y+yLength,0);
xLength -=0.1;
yLength -=0.1;
x += 0.05;
y += 0.05;
glEnd();
glPopMatrix();
}
}
Your quads are going to rotate around the origin (0,0,0). If that's not in the middle of your quads then it is going to look like it is translating too. Maybe you can translate it so the quads a centered, rotate it, and then translate it back
Edit:
See #datenwolf's comment for an example where he:
creates the quad with 0,0,0 as the center
rotates the quad
translates the quad to its position

Resources