0

In this project, I made a 3d cube and added a camera. We can go forward, backward, right or left with the W, A, S, D keys, but we cannot turn right or left. For example, I want to see the back side of the cube, but I cannot see it.Actually this is a simple problem and its solution is simple but my math level is insufficient, it will be better if someone explain it to me.I'll tell you my code and what I've tried below.

#include <Windows.h>

#include <gl/GL.h>
#include <gl/GLU.h>
#include <GLFW/glfw3.h>

#include <cstdio>
#include <iostream>
#include <cmath>
#include <math.h>

int width = 1280;
int height = 720;

float camera_z = 5;
float camera_y = 0;
float camera_x = 0;

float fov = 60;

GLFWwindow* window;

float speed = 0.01;


GLfloat vertices[] = {
    -1, -1, -1,   -1, -1,  1,   -1,  1,  1,   -1,  1, -1,
    1, -1, -1,    1, -1,  1,    1,  1,  1,    1,  1, -1,
    -1, -1, -1,   -1, -1,  1,    1, -1,  1,    1, -1, -1,
    -1,  1, -1,   -1,  1,  1,    1,  1,  1,    1,  1, -1,
    -1, -1, -1,   -1,  1, -1,    1,  1, -1,    1, -1, -1,
    -1, -1,  1,   -1,  1,  1,    1,  1,  1,    1, -1,  1
};

GLfloat colors[] = {
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   1, 1, 0,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   0, 1, 1,   0, 1, 0,   0, 1, 0,
    1, 1, 0,   0, 1, 1,   0, 1, 0,   0, 1, 0
};



void keyboard() {

    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {

        glfwSetWindowShouldClose(window, GL_TRUE);

    }
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {

        camera_z = camera_z - speed;

    }
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {

        camera_x = camera_x - speed;

    }
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {

        camera_z = camera_z + speed;

    }
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {

        camera_x = camera_x + speed;
    }
    if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {

        camera_y = camera_y + speed;
    }
    if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) {

        camera_y = camera_y - speed;
    }

    

    if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {

        // need help
       
    }
    if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
       
        // need help
    }

   
}
       




void drawCube() {

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glColorPointer(3, GL_FLOAT, 0, colors);
    
    glDrawArrays(GL_QUADS, 0, 24);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

}



int main(void)
{
    

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(width, height, "C++ OpenGL ", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    

    glEnable(GL_DEPTH_TEST); 

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        glViewport(0, 0, width, height);

        /* Render here */
        glClearColor(0.0, 192/256, 1, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        float aspect = (float)width / (float)height;
        float fov = 60;
        gluPerspective(fov, aspect, 0.1, 1000);
        
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        keyboard();
        
                                                      
        gluLookAt(
            camera_x,
            camera_y,
            camera_z,
            camera_x + 1, // need help
            camera_y + 1, // need help
            camera_z - fov ,
            0,
            1, 
            0
        );

        glTranslatef(0, 0,-3);
        drawCube();



        glFlush();

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

The things I tried were the variables camera_eyex,*_eyey,*_eyez. I added them to the loop to give the camera + 1 value. I used to increase or decrease them when I wanted to go left or right, but there are many errors in this method. For example, even if the camera rotates 45 degrees when I press the W key, it goes straight, so it does not go where I am looking. Also, turning more than 90 degrees to the right or left It's not possible. Also, when I press the left button to go left, turning is getting slower and slower.

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • 3
    You might find it easier if you don't use gluLookAt – user253751 Feb 17 '23 at 21:38
  • 1
    What disadvantage does gluLookAt have? – Bilal Akol Feb 17 '23 at 21:41
  • 1
    mainly that it's harder to calculate the parameters? – user253751 Feb 17 '23 at 21:42
  • although I see you have it looking in a fixed direction so maybe you already figured out what you have to do to use it. Hint: sin(angle) and cos(angle) calculate a point on a circle (in radians) – user253751 Feb 17 '23 at 21:43
  • Thank you, could you add to the code? My math knowledge is a bit low. I know this is a problem, coding and math are like brothers. Apologies in advance. – Bilal Akol Feb 17 '23 at 21:45
  • To accomplish it with lookat, you pretty much need to calculate a rotation matrix, apply it to individual vectors, and then have lookat recover the rotation matrix from those vectors. This is a very roundabout way of accomplishing this. [Stop using lookat](https://stannum.io/blog/0UaG8R), except when the camera and the point you want it to follow are truly independent. – Yakov Galka Feb 18 '23 at 04:08
  • see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) especially the links at the end ... – Spektre Feb 18 '23 at 08:15

1 Answers1

2

You need to build a transform matrix. A transformation usually is a combination of translation, scale and rotation.

Where you first rotate, then scale and then translate (the actual order of calculation - multiplication - is reversed):

translation x scale x rotation

If you want to scale or rotate around a certain point (pivot or center), then you have to translate to the center point and at the end translate back to the origin, like:

translation x center x scale x rotation x -center

The lookAt algorithm sets the rotation and translation based on the parameters (eye, target, up), whereas your goal is to separate the rotation from the translation. Therefore you have to build your own transformation, e.g.:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//set the position of the camera
glTranslate(pos);

//set the scale or rotation pivot
//glTranslate(center);

//scale
//glScale(scale);

//rotate around z-axis first
glRotate(z_angle, 0, 0, 1);    

//rotate around y-axis
glRotate(y_angle, 0, 1, 0);

//rotate around x-axis
glRotate(x_angle, 1, 0, 0);

//set the center back, if set before
//glTranslate(-center);

You'll find more info here (OpenGl related, although 'modern' OpenGl): https://learnopengl.com/Getting-started/Transformations

Note: You probably have to adjust the input 'W A S D' to the changed axises. If, for example the 'W' key adjusts the z-component, you will probably not go 'forward' (along the z-axis) with the setup above. In order to move according to the transformed axises, you'll need the transformation matrix and extract them. Better is to use a math library, e.g. glm. How a orbit camera could be implemented, again, have a look at: https://learnopengl.com/Getting-started/Camera


Building a camera system, needs some theoretical background in linear algebra.

Based on the comment section below, i list all relevant links here:

On top of that, it can be overwhelming for those who never visited a course in linear algebra, therefore i highly recommend The Essence of linear algebra by 3Blue1Brown.

A note on matrix multiplication, what is not adequate emphasized and mostly overlooked: Once one has internalized the geometric meaning of a dot product, and the geometric meaning of the rows and columns of a matrix, one should also note that each component of the resulting matrix is the result of the dot product of a row and a column vector, visualize that and internalize it.

Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11
  • @BilalAkol Bilal arkadaşım, don't give up. Matematik seviyen nedir? Ever had a course in linear algebra (lineer cebir)? Do the terms vector and matrix have any meaning to you, if so, what is your level of knowledge? If you give us a hint, we could be able to point you in the required direction. It is not as difficult as it first appears (depending on your visual imagination, even very intuitive). – Erdal Küçük Feb 18 '23 at 19:10
  • I don't know linear algebra, but I do know vectors. – Bilal Akol Feb 19 '23 at 11:47
  • Superb, that's a good start. Do you know what it 'means' to take the [dot](https://en.wikipedia.org/wiki/Dot_product) or [cross](https://en.wikipedia.org/wiki/Cross_product) product of two vectors? After studying those two topics, go over to [Translation](https://en.wikipedia.org/wiki/Translation_(geometry)) and [Rotation](https://en.wikipedia.org/wiki/Rotation_matrix), then you're basically done. I also highly recommend the [Essence of linear algebra](https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab) by [3Blue1Brown](https://www.youtube.com/@3blue1brown). – Erdal Küçük Feb 19 '23 at 15:09
  • **Addendum:** since there is no way around [Matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication), a hint from me, what is mostly overlooked: if you have internalized the geometric meaning of a dot product and after you've realized what geometric meaning the rows and columns of a matrix have, then you should also notice, that each component of the resulting matrix is the result of the dot product of a row and a column vector, visualize that and internalize it. – Erdal Küçük Feb 19 '23 at 15:33
  • Not 'will try', 'do it'! Start with the video series i've suggested. A couple of 10 minute videos, and you will not have to watch all of them at once. Start with the first 5 and chapter 9, 10, 11 (1 hour. of your life), after that, for a deeper understanding read the other articles. Within a week of study, i guarantee that you'll be able to build your camera system (based on true knowledge and not an already catched fish). – Erdal Küçük Feb 19 '23 at 18:37