I wonder where am going wrong with the zooming and orbiting

巧了我就是萌 提交于 2020-01-24 12:17:47

问题


I want to be able to pan, zoom, and orbit the cube. I would like to know why the cube appears fully zoomed on the screen such that I have to move backwards to view the whole cube. I would also like to change the zooming controls to alt and right mouse button for both zooming and orbiting but I cant get it to work. Any assistance would be appreciated.

/*/header inclusions*/
#include <iostream> // Includes C++ i/o stream
#include <GL/glew.h> // Includes glew header
#include <GL/freeglut.h> // Includes freeglut header

// GLM Math inclusions
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>

using namespace std; // Uses the standard namespace

#define WINDOW_TITLE "Modern OpenGL" // Macro for window title

//Vertex and fragment shader
#ifndef GLSL
#define GLSL(Version, source) "#version " #Version "\n" #source
#endif


// Variables for window width and height
GLint ShaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO;

GLfloat cameraSpeed = 0.0005f;

GLchar currentKey;

GLfloat lastMouseX = 400, lastMouseY = 300;
GLfloat mouseXOffset, mouseYOffset, yaw = 0.0f, pitch = 0.0f;
GLfloat sensitivity = 0.5f;
bool mouseDetected = true;


//global vectors declaration
glm::vec3 cameraPosition = glm::vec3(0.0f,0.0f,0.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f,1.0f,0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f,0.0f,-1.0f);
glm::vec3 front;


/* User-defined Function prototypes to:*/
void UResizeWindow(int,int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UKeyboard(unsigned char key, int x, int y);
void UKeyReleased(unsigned char key, int x, int y);
void UMouseMove(int x, int y);

/*Vertex shader source code*/
const GLchar * vertexShaderSource = GLSL(330,
layout(location=0) in vec3 position;
layout(location=1) in vec3 color;

out vec3 mobileColor; //declare a vec 4 variable

//Global variables for the transform matrices
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;

 void main(){
        gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices
            mobileColor = color;
        }
);


/*Fragment shader program source code*/
const GLchar * fragmentShaderSource = GLSL(330,
in vec3 mobileColor;

out vec4 gpuColor;//out vertex_Color;

    void main(){

      gpuColor = vec4 (mobileColor, 1.0);

    }
);


//main program
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);

glutReshapeFunc(UResizeWindow);


glewExperimental = GL_TRUE;
    if (glewInit()!= GLEW_OK)
    {
    std::cout << "Failed to initialize GLEW" << std::endl;
    return -1;
    }

    UCreateShader();

    UCreateBuffers();

    // Use the Shader program
    glUseProgram(ShaderProgram);


    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color

    glutDisplayFunc(URenderGraphics);

    glutKeyboardFunc(UKeyboard);

    glutKeyboardUpFunc(UKeyReleased);

    glutPassiveMotionFunc(UMouseMove);

    glutMainLoop();

    // Destroys Buffer objects once used
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);

    return 0;

}

/* Resizes the window*/
void UResizeWindow(int w, int h)
{
WindowWidth = w;
    WindowHeight = h;
    glViewport(0, 0, WindowWidth, WindowHeight);
 }


 /* Renders graphics */
void URenderGraphics(void)
{

    glEnable(GL_DEPTH_TEST); // Enable z-depth

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen

    glBindVertexArray(VAO); // Activate the Vertex Array Object before rendering and transforming them

    //camera movement logic
    if(currentKey == 'w')
        cameraPosition += cameraSpeed * CameraForwardZ;

    if(currentKey == 's')
            cameraPosition -= cameraSpeed * CameraForwardZ;

    if(currentKey == 'a')
        cameraPosition -= glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;

    if(currentKey == 'd')
            cameraPosition += glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;
            CameraForwardZ = front;

    // Transforms the object
    glm::mat4 model;
    model = glm::translate(model, glm::vec3(0.0, 0.0f, 0.0f)); // Place the object at the center of the 7i,p9rA
    model = glm::rotate(model, 45.0f, glm::vec3(1.0, 1.0f, 1.0f)); // Rotate the object 45 degrees on the XYZ
    model = glm::scale(model, glm::vec3(1.0f, 1.0f, -1.0f)); // Increase the object size by a scale of 2

    // Transforms the camera
    glm::mat4 view;
    view = glm::lookAt(cameraPosition, cameraPosition + CameraForwardZ, CameraUpY); //Moves the world 0.5 units on X and -5 units in Z

    // Creates a perspective projection
    glm::mat4 projection;
    projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);

    // Retrieves and passes transform matrices to the Shader program
    GLint modelLoc = glGetUniformLocation(ShaderProgram, "model");
    GLint viewLoc = glGetUniformLocation(ShaderProgram, "view");
    GLint projLoc = glGetUniformLocation(ShaderProgram, "projection");

    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

    glutPostRedisplay();

// Draws the triangles
    glDrawArrays(GL_TRIANGLES,0, 36);

    glBindVertexArray(0); // Deactivate the Vertex Array Object

    glutSwapBuffers(); // Flips the the back buffer with the front buffer every frame. Similar to GL FLush

 }

 /*Creates the Shader program*/
 void UCreateShader()
 {

    // Vertex shader
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // Attaches the Vertex Shader to the source code
    glCompileShader(vertexShader); // Compiles the Vertex Shader

    // Fragment Shader
    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code
    glCompileShader(fragmentShader); // Compiles the Fragment Shader

    // Shader program
    ShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id
    glAttachShader(ShaderProgram, vertexShader); // Attach Vertex Shader to the Shader program
    glAttachShader(ShaderProgram, fragmentShader);; // Attach Fragment Shader to the Shader program
    glLinkProgram(ShaderProgram); //Link Vertex and Fragment shader, to Shader program

    // Delete the Vertex and Fragment shaders once linked
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

 }


/*creates the buffer and array object*/
 void UCreateBuffers()
 {

     //position and color data
     GLfloat vertices[] = {
                        //vertex positions and colors
                    -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
                     0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
                     0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
                     0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
                    -0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
                    -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,

                    -0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 0.0f,
                     0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 0.0f,
                     0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f,
                     0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f,
                    -0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f,
                    -0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 0.0f,

                    -0.5f,  0.5f,  0.5f, 0.0f, 0.0f, 1.0f,
                    -0.5f,  0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
                    -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
                    -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
                    -0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f,
                    -0.5f,  0.5f,  0.5f, 0.0f, 0.0f, 1.0f,

                     0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 0.0f,
                     0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
                     0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
                     0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
                     0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 0.0f,
                     0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 0.0f,

                    -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
                     0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
                     0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 1.0f,
                     0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 1.0f,
                    -0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 1.0f,
                    -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,

                    -0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
                     0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
                     0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 1.0f,
                     0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 1.0f,
                    -0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 1.0f,
                    -0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 1.0f,

                };


     //Generate buffer id,
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1,&VBO);


// Activate the Vertex Array Object before binding and setting any VB0s and Vertex Attribute Pointers.
    glBindVertexArray(VAO);

    // Activate the VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO

// Set attribute pointer 0 to hold Position data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); // Enables vertex attribute

// Set attribute pointer 1 to hold Color data
 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
 glEnableVertexAttribArray(1); // Enables vertex attribute

glBindVertexArray(0); // Deactivates the VAC, which is good practice

}


 //implement the UKeyboard function
 void UKeyboard(unsigned char key, GLint x, GLint y)
 {
     switch(key){
                 case 'w':
                     currentKey = key;
                     cout<<"You Pressed W"<<endl;
                     break;

                case 's':
                     currentKey = key;
                     cout<<"You Pressed S"<<endl;
                     break;

             case 'a':
                     currentKey = key;
                     cout<<"You Pressed A"<<endl;
                     break;

            case 'd':
                     currentKey = key;
                     cout<<"You Pressed D"<<endl;
                     break;

            default:
                cout<<"Press a key!"<<endl;
     }

 }

     //implement the UKeyReleased function
 void UKeyReleased(unsigned char key, GLint x, GLint y)
  {
     cout<<"Key Released!"<<endl;
         currentKey = '0';
  }

 //implement UMouseMove function
 void UMouseMove(int x, int y)
   {

         if(mouseDetected)
         {
             lastMouseX = x;
             lastMouseY = y;
             mouseDetected = false;
         }

     //get the direction mouse was moved
         mouseXOffset = x - lastMouseX;
        mouseYOffset = lastMouseY - y;

        //update new coordinates
        lastMouseX = x;
        lastMouseY = y;

        //apply sensitivity
        mouseXOffset *= sensitivity;
        mouseYOffset *= sensitivity;

        //accumulate yaw and pitch
        yaw += mouseXOffset;
        pitch += mouseYOffset;

        //maintain 90 degree pitch
        if (pitch > 89.0f)
             pitch = 89.0f;

        if (pitch > -89.0f)
             pitch = -89.0f;

        //convert mouse coordinates
        front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
        front.y = sin(glm::radians(pitch));
        front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));

   }

回答1:


Start at a camera position, which is translated along the positiv z axis (e.g. (0, 0, 10)). front has to be initialized:

glm::vec3 cameraPosition = glm::vec3(0.0f,0.0f,10.0f);
glm::vec3 CameraUpY      = glm::vec3(0.0f,1.0f,0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f,0.0f,-1.0f);
glm::vec3 front          = glm::vec3(0.0f,0.0f,-1.0f);

You have to initialize the model matrix variable glm::mat4 model.

The glm API documentation refers to The OpenGL Shading Language specification 4.20.

5.4.2 Vector and Matrix Constructors

If there is a single scalar parameter to a vector constructor, it is used to initialize all components of the constructed vector to that scalar’s value. If there is a single scalar parameter to a matrix constructor, it is used to initialize all the components on the matrix’s diagonal, with the remaining components initialized to 0.0.

This means, that an Identity matrix can be initialized by the single parameter 1.0:

glm::mat4 model(1.0f);

The unit of the angles in OpenGL Mathematics is radian rather than degree. (glm::perspective, glm::rotate):

// Transforms the object
glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(0.0, 0.0f, 0.0f)); // Place the object at the center of the 7i,p9rA
model = glm::rotate(model, glm::radians(45.0f), glm::vec3(1.0, 1.0f, 1.0f)); // Rotate the object 45 degrees on the XYZ
model = glm::scale(model, glm::vec3(1.0f, 1.0f, -1.0f)); // Increase the object size by a scale of 2

// Transforms the camera
glm::mat4 view = glm::lookAt(cameraPosition, cameraPosition +  CameraForwardZ, CameraUpY); //Moves the world 0.5 units on X and -5 units in Z

// Creates a perspective projection
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);

There are some mistakes when front is calculated. pitch < -89.0f rather than pitch > -89.0f. The x axis is sin(glm::radians(yaw)) and the z axis is -cos(glm::radians(yaw)):

//maintain 90 degree pitch
if (pitch > 89.0f)
      pitch = 89.0f;

if (pitch < -89.0f)
      pitch = -89.0f;

//convert mouse coordinates
front.x = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
front.y = sin(glm::radians(pitch));
front.z = cos(glm::radians(pitch)) * -cos(glm::radians(yaw));

Furthermore, the sensitivity seams to be to strong, I recommend to reduce it (e.g. GLfloat sensitivity = 0.05f;).



来源:https://stackoverflow.com/questions/59101909/i-wonder-where-am-going-wrong-with-the-zooming-and-orbiting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!