Witam, muszę stworzyć "Manipulator RPR" za pomocą prymitywów w OpenGL. Generalnie całość wychodzi ładnie, pierwsza pierwszego elementu spoko, węzeł przesuwny także bez zarzutów. Problem mam z rotowaniem 3. Elementu wokół osi z (jest ona do nas). Nie mam pojęcia dla czego rotuje mi się w ten sposób - nic nie ustawiałem, a rotuje się prawie dobrze, to znaczy 1 jednostkę odległości od lewego końca prostopadłościanu (cały ma 6 jednostek odległości). Chciałbym owy element rotować na samym końcu. Czy mógłby ktoś powiedzieć, co robię nie tak? P.S. jestem początkującym w OpenGL. Niżej zamieszczam kod interesującego mnie elementu:
/*!!!!!!!!!!!!!!!STARTbloczek numer 3 start : R- */
glTranslatef(-2.5f, d2-0.5, -20.0f);
glRotatef(th1, 0, 1, 0);
glRotatef((float)th3, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(6.0f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(6.0f, 0.5f, 0.5f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f(6.0f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(6.0f, -0.5f, -0.5f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(6.0f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(6.0f, -0.5f, 0.5f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f(6.0f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(6.0f, 0.5f, -0.5f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(6.0f, 0.5f, -0.5f);
glVertex3f(6.0f, 0.5f, 0.5f);
glVertex3f(6.0f, -0.5f, 0.5f);
glVertex3f(6.0f, -0.5f, -0.5f);
glEnd(); // End of drawing color-cube
/*bloczek numer 3 end : R- */
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
jeśli chodzi o objaśnienie, to "glTranslatef(-2.5f, d2-0.5, -20.0f);" służy do przesunięcia klocka w prawo o 2,5 jednostki odległości, ponieważ człon ma być w "prawo". Dalej przesuwamy w 'y' o wartość węzła przesównego i trochę obniżamy, a ostatnie to oddalenie.
glRotatef(th1, 0, 1, 0); -> służy do rotowania razem z pierwszym węzłem rotacyjnym.
glRotatef((float)th3, 0.0f, 0.0f, 1.0f); -> zapisane w inny sposób niż pierwsze, ale to nie ma znaczenia, rezultat ten sam.
Oto jak wygląda symulacja:


Dodaje też cały kod aplikacji:
/*
* OGL01Shape3D.cpp: 3D Shapes
*/
#include <windows.h> // for MS Windows
#include <GL/glut.h> // GLUT, include glu.h and gl.h
#include<iostream>
/* Global variables */
char title[] = "3D Shapes";
float d2 = 2.0;
int th1 = 0;
int th3 = 0;
void FunkcjaDoObslugiKlawiatury(unsigned char key, int mouse_x, int mouse_y) //dla obslugi klawiatury
{
std::cout << "Naciśnięto klawisz: " << key << ", a myszka znajduje się w pozycji: " << mouse_x << ", " << mouse_y << "(w pikselach)" << std::endl;
switch (key)
{
case 'q':
{
th1 += 5;
break;
}
case 'a':
{
th1 -= 5;
break;
}
case 'w':
{
d2 +=0.1;
break;
}
case 's':
{
d2 -= 0.1;
break;
}
case 'e':
{
th3 += 5;
break;
}
case 'd':
{
th3 -= 5;
break;
}
}
}
/* Initialize OpenGL Graphics */
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f); // Set background depth to farthest
glutKeyboardFunc(FunkcjaDoObslugiKlawiatury);
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
}
void idle() {
glutPostRedisplay();
}
/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
/*bloczek numer 1 start : R| */
glTranslatef(-3.0f, -3.0f, -20.0f); // Move right and into the screen
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 2.0f, 0.0f); // Green
glVertex3f(1.0f, 2.0f, -1.0f);
glVertex3f(-1.0f, 2.0f, -1.0f);
glVertex3f(-1.0f, 2.0f, 1.0f);
glVertex3f(1.0f, 2.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f(1.0f, -2.0f, 1.0f);
glVertex3f(-1.0f, -2.0f, 1.0f);
glVertex3f(-1.0f, -2.0f, -1.0f);
glVertex3f(1.0f, -2.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(1.0f, 2.0f, 1.0f);
glVertex3f(-1.0f, 2.0f, 1.0f);
glVertex3f(-1.0f, -2.0f, 1.0f);
glVertex3f(1.0f, -2.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 2.0f, 0.0f); // Yellow
glVertex3f(1.0f, -2.0f, -1.0f);
glVertex3f(-1.0f, -2.0f, -1.0f);
glVertex3f(-1.0f, 2.0f, -1.0f);
glVertex3f(1.0f, 2.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 2.0f, 1.0f);
glVertex3f(-1.0f, 2.0f, -1.0f);
glVertex3f(-1.0f, -2.0f, -1.0f);
glVertex3f(-1.0f, -2.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 2.0f, -1.0f);
glVertex3f(1.0f, 2.0f, 1.0f);
glVertex3f(1.0f, -2.0f, 1.0f);
glVertex3f(1.0f, -2.0f, -1.0f);
glEnd(); // End of drawing color-cube
// Render a pyramid consists of 4 triangles
glLoadIdentity(); // Reset the model-view matrix
/*bloczek numer 1 end : R| */
/*bloczek numer 2 start : P| */
glTranslatef(-3.0f, d2-3, -20.0f);
glRotatef(th1, 0, 1, 0);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(0.5f, 2.0f, -0.5f);
glVertex3f(-0.5f, 2.0f, -0.5f);
glVertex3f(-0.5f, 2.0f, 0.5f);
glVertex3f(0.5f, 2.0f, 0.5f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f(0.5f, -2.0f, 0.5f);
glVertex3f(-0.5f, -2.0f, 0.5f);
glVertex3f(-0.5f, -2.0f, -0.5f);
glVertex3f(0.5f, -2.0f, -0.5f);
// Front face (z = 1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Red -> yellow
glVertex3f(0.5f, 2.0f, 0.5f);
glVertex3f(-0.5f, 2.0f, 0.5f);
glVertex3f(-0.5f, -2.0f, 0.5f);
glVertex3f(0.5f, -2.0f, 0.5f);
// Back face (z = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Yellow -> blue
glVertex3f(0.5f, -2.0f, -0.5f);
glVertex3f(-0.5f, -2.0f, -0.5f);
glVertex3f(-0.5f, 2.0f, -0.5f);
glVertex3f(0.5f, 2.0f, -0.5f);
// Left face (x = -1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Blue -> magneta
glVertex3f(-0.5f, 2.0f, 0.5f);
glVertex3f(-0.5f, 2.0f, -0.5f);
glVertex3f(-0.5f, -2.0f, -0.5f);
glVertex3f(-0.5f, -2.0f, 0.5f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Magenta -> RED
glVertex3f(0.5f, 2.0f, -0.5f);
glVertex3f(0.5f, 2.0f, 0.5f);
glVertex3f(0.5f, -2.0f, 0.5f);
glVertex3f(0.5f, -2.0f, -0.5f);
glEnd(); // End of drawing color-cube
// Render a pyramid consists of 4 triangles
glLoadIdentity();
/*!!!!!!!!!!!!!!!END bloczek numer 2 end : P| */
/*!!!!!!!!!!!!!!!STARTbloczek numer 3 start : R- */
glTranslatef(-2.5f, d2-0.5, -20.0f);
glRotatef(th1, 0, 1, 0);
glRotatef((float)th3, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(6.0f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(6.0f, 0.5f, 0.5f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f(6.0f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(6.0f, -0.5f, -0.5f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(6.0f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(6.0f, -0.5f, 0.5f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f(6.0f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(6.0f, 0.5f, -0.5f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(6.0f, 0.5f, -0.5f);
glVertex3f(6.0f, 0.5f, 0.5f);
glVertex3f(6.0f, -0.5f, 0.5f);
glVertex3f(6.0f, -0.5f, -0.5f);
glEnd(); // End of drawing color-cube
/*bloczek numer 3 end : R- */
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping volume to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
glutIdleFunc(idle);
initGL(); // Our own OpenGL initialization
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}