首页 > 解决方案 > 我想知道缩放和轨道哪里出了问题

问题描述

我希望能够平移、缩放和环绕立方体。我想知道为什么立方体在屏幕上显示为完全缩放,以至于我必须向后移动才能查看整个立方体。我还想将缩放控件更改为 alt 和鼠标右键以进行缩放和环绕,但我无法让它工作。任何援助将不胜感激。

/*/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));

   }

标签: c++eclipseopenglglsl

解决方案


从沿正 z 轴平移的相机位置开始(例如 (0, 0, 10))。front必须初始化:

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);

您必须初始化模型矩阵变量glm::mat4 model

glm API 文档参考了OpenGL 着色语言规范 4.20

5.4.2 向量和矩阵构造函数

如果向量构造函数有一个标量参数,则它用于将构造向量的所有组件初始化为该标量的值。如果矩阵构造函数只有一个标量参数,则它用于初始化矩阵对角线上的所有分量,其余分量初始化为 0.0。

这意味着,一个单位矩阵可以由单个参数 1.0 初始化:

glm::mat4 model(1.0f);

OpenGL数学中的角度单位是弧度而不是度数。( 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);

计算时有一些错误frontpitch < -89.0f而不是pitch > -89.0f. x 轴为sin(glm::radians(yaw)),z 轴为-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));

此外,sensitivity接缝要牢固,我建议减少它(例如GLfloat sensitivity = 0.05f;)。


推荐阅读