簡體   English   中英

創建相機來旋轉立方體不起作用

[英]Creating a camera to rotate a cube not working

我創建了一個創建彩色立方體的程序,我試圖在keyCallback function 中移動立方體。 這不起作用,因為我打算讓它起作用,而是移動了立方體。 我試圖創建一個相機,這是我的完整程序:

#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm.hpp>
#include <gtc\matrix_transform.hpp>
#include <GL/freeglut.h>
#include <GL\GL.h>

void DrawCube(GLfloat centerPosX, GLfloat centerPosY, GLfloat centerPosZ, GLfloat edgeLength);
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
void framebuffer_size_callback(GLFWwindow* wndow, int width, int height);

GLfloat rotateX = 0.0f;
GLfloat rotateY = 0.0f;

GLfloat xPos = 0.0f;
GLfloat yPos = 0.0f;
GLfloat zPos = 0.0f;

int main(void) {
    GLFWwindow* window;

    //Init library
    if (!glfwInit())
        return -1;
    //create a window
    glEnable(GL_DEPTH_TEST);
    window = glfwCreateWindow(840, 420, "electroCaft", NULL, NULL);
    int screenWidth, screenHeight;
    glfwSetKeyCallback(window, keyCallback);
    //get resolution
    glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glViewport(0.0f, 0.0f, screenWidth, screenHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, screenWidth, 0, screenHeight, 0, 1000); // essentially setting coodinates last num sets view point of distance
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_DEPTH_TEST);
    glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
    glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f);
    glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget);
    glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection));
    glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight);
    glm::mat4 view;
    view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f),
        glm::vec3(0.0f, 0.0f, 0.0f),
        glm::vec3(0.0f, 1.0f, 0.0f));
    float radius = 10.0f;
    float camX = sin(glfwGetTime()) * radius;
    float camZ = cos(glfwGetTime()) * radius;
    //glm::mat4 view;
    view = glm::lookAt(glm::vec3(camX, 0.0, camZ), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));


    GLfloat halfScreenWidth = screenWidth / 2;
    GLfloat halfScreenHeight = screenHeight / 2;

    GLfloat rotationSpeed = 1.0f;

    //load textures

    //loop until user closes window
    while (!glfwWindowShouldClose(window)) {
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

        //render graphics
        //glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(62.0f / 255.0f, 85.9f / 255.0f, 255.0 / 255.0, 0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //drawing here
        //printf("screen width is: %d \n", screenWidth);

        view = glm::lookAt(glm::vec3(camX, 0.0, camZ), glm::vec3(100, 100, 100), glm::vec3(0.0, 1.0, 0.0));

        glPushMatrix();
        glTranslatef((GLfloat)screenWidth / 2.0f, (GLfloat)screenHeight / 2.0f, -500.0f);
        glRotatef(rotateX, 1, 0, 0);
        glRotatef(rotateY, 0, 1, 0);
        //rotateX += 1;
        //rotateY -= 1;

        //DrawCube(halfScreenWidth, halfScreenHeight, -500, 250); //x,y,w,h z is calculated in cube func
        DrawCube(xPos, yPos, zPos, 250);
        //DrawCube(xPos - 50, yPos, zPos, 50);
        //DrawCube(xPos + 50, yPos, zPos, 50);
        //DrawCube(halfScreenWidth, halfScreenHeight - 100, -500, 250);
        glPopMatrix();



        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();
    return 0;

}


void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    const GLfloat rotationSpeed = 10;


    if (action == GLFW_PRESS || action == GLFW_REPEAT)
    {
        switch (key)
        {
        case GLFW_KEY_W:
            zPos += rotationSpeed;
            break;
        case GLFW_KEY_S:
            zPos -= rotationSpeed;
            break;
        case GLFW_KEY_D:
            xPos += rotationSpeed;
            break;
        case GLFW_KEY_A:
            xPos -= rotationSpeed;
            break;
        case GLFW_KEY_SPACE:
            yPos -= rotationSpeed;
            break;

        //rotate the cube
        case GLFW_KEY_UP:
            rotateX -= rotationSpeed;
            break;
        case GLFW_KEY_DOWN:
            rotateX += rotationSpeed;
            break;
        case GLFW_KEY_RIGHT:
            rotateY += rotationSpeed;
            break;
        case GLFW_KEY_LEFT:
            rotateY -= rotationSpeed;
            break;
        }


    }
}

void framebuffer_size_callback(GLFWwindow* wndow, int width, int height)
{
    glViewport(0, 0, width, height);
    //glViewport(xPos, yPos, zPos, width);
}



void DrawCube(GLfloat centerPosX, GLfloat centerPosY, GLfloat centerPosZ, GLfloat edgeLength) {
    GLfloat halfSideLength = edgeLength * 0.5;
    GLfloat vertices[] = {
        // front face
        centerPosX - halfSideLength, centerPosY + halfSideLength, centerPosZ + halfSideLength, //top left
        centerPosX + halfSideLength, centerPosY + halfSideLength, centerPosZ + halfSideLength, //top right
        centerPosX + halfSideLength, centerPosY - halfSideLength, centerPosZ + halfSideLength, //bottom right
        centerPosX - halfSideLength, centerPosY - halfSideLength, centerPosZ + halfSideLength, // bottom left

        // back face
        centerPosX - halfSideLength, centerPosY + halfSideLength, centerPosZ - halfSideLength, //top left
        centerPosX + halfSideLength, centerPosY + halfSideLength, centerPosZ - halfSideLength, //top right
        centerPosX + halfSideLength, centerPosY - halfSideLength, centerPosZ - halfSideLength, //bottom right
        centerPosX - halfSideLength, centerPosY - halfSideLength, centerPosZ - halfSideLength, // bottom left

        // left face
        centerPosX - halfSideLength, centerPosY + halfSideLength, centerPosZ + halfSideLength, //top left
        centerPosX - halfSideLength, centerPosY + halfSideLength, centerPosZ - halfSideLength, //top right
        centerPosX - halfSideLength, centerPosY - halfSideLength, centerPosZ - halfSideLength, //bottom right
        centerPosX - halfSideLength, centerPosY - halfSideLength, centerPosZ + halfSideLength, // bottom left

        // right face
        centerPosX + halfSideLength, centerPosY + halfSideLength, centerPosZ + halfSideLength, //top left
        centerPosX + halfSideLength, centerPosY + halfSideLength, centerPosZ - halfSideLength, //top right
        centerPosX + halfSideLength, centerPosY - halfSideLength, centerPosZ - halfSideLength, //bottom right
        centerPosX + halfSideLength, centerPosY - halfSideLength, centerPosZ + halfSideLength, // bottom left

        // top face
        centerPosX - halfSideLength, centerPosY + halfSideLength, centerPosZ + halfSideLength, //top left
        centerPosX - halfSideLength, centerPosY + halfSideLength, centerPosZ - halfSideLength, //top right
        centerPosX + halfSideLength, centerPosY + halfSideLength, centerPosZ - halfSideLength, //bottom right
        centerPosX + halfSideLength, centerPosY + halfSideLength, centerPosZ + halfSideLength, // bottom left

        // bottom face
        centerPosX - halfSideLength, centerPosY - halfSideLength, centerPosZ + halfSideLength, //top left
        centerPosX - halfSideLength, centerPosY - halfSideLength, centerPosZ - halfSideLength, //top right
        centerPosX + halfSideLength, centerPosY - halfSideLength, centerPosZ - halfSideLength, //bottom right
        centerPosX + halfSideLength, centerPosY - halfSideLength, centerPosZ + halfSideLength // bottom left
    };

    //glRotated(edgeLength, 0, 0, 1);
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer( 3, GL_FLOAT, 0, vertices);
    glColorPointer(3, GL_FLOAT, 0, vertices);
    glDrawArrays(GL_QUADS, 0, 24);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}

我不確定是否有任何用於相機的 glm 代碼是循環的一部分。 我在循環中定義了view ,我相信這是正確的,但我不確定是否需要以某種方式使用相機 position 作為立方體的 position 的一部分。

您必須通過glLoadMatrix將視圖矩陣( view )加載到主循環中的當前矩陣。
注意, glm::lookAt只是計算矩陣並從 function 返回矩陣,但它不會神奇地設置任何 OpenGL 矩陣。 所以從 function 返回的矩陣必須設置為當前的模型視圖矩陣:

glm::mat4 view = glm::lookAt(eye, center, up);
glLoadMatrixf( glm::value_ptr(view) );

如果你想讓立方體保持在視圖的中心,那么我建議設置一個投影矩陣,它對稱地投影到 x 和 y 軸。 例如:

glOrtho(-screenWidth/2, screenWidth/2, -screenHeight/2, screenHeight/2, -1000, 1000); 

請注意,移位的投影會導致視圖矩形被移位,並且立方體看起來如此居中(或圍繞視口的左下角旋轉)。

請參閱示例,以圍繞立方體旋轉視圖(眼睛位置):

#include <glm/gtc/type_ptr.hpp> // glm::value_ptr
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-screenWidth/2, screenWidth/2, -screenHeight/2, screenHeight/2, -1000, 1000); 
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while (!glfwWindowShouldClose(window)) {

    // [...]

    float time = glfwGetTime();
    float radius = 500.0f;
    float camX = sin(time) * radius;
    float camZ = cos(time) * radius;

    glm::vec3 center = glm::vec3(0.0f, 0.0f, 0.0f);
    glm::vec3 eye    = center + glm::vec3(camX, camZ, 0.0f);
    glm::vec3 up     = glm::vec3(0.0, 0.0, 1.0);
    glm::mat4 view   = glm::lookAt(eye, center, up);
    glLoadMatrixf( glm::value_ptr(view) );

    glPushMatrix();
    glTranslatef(xPos, yPos, zPos);
    glRotatef(rotateX, 1, 0, 0);
    glRotatef(rotateY, 0, 1, 0);
    DrawCube(0.0f, 0.0f, 0.0f, 250.0f);
    glPopMatrix();

    // [...]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM