Создание камеры для вращения куба не работает - PullRequest
1 голос
/ 30 сентября 2019

Я создал программу, которая создает цветной куб, я попытался переместить куб в функции keyCallback. Это не сработало, потому что я хотел, чтобы это сработало, и вместо этого переместил куб. Я попытался создать камеру, и это моя полная программа:

#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, я считаю, что это правильно, но я не уверен, нужно ли мне каким-либо образом использовать положение камеры как часть положения для куба.

1 Ответ

0 голосов
/ 30 сентября 2019

Вы должны загрузить матрицу вида (view) в текущую матрицу в основном цикле на glLoadMatrix.
Примечание, glm::lookAt простовычисляет матрицу и возвращает матрицу из функции, но она волшебным образом не устанавливает никакой матрицы OpenGL. Поэтому матрица, возвращаемая из функции, должна быть установлена ​​на текущую матрицу вида модели:

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

Если вы хотите, чтобы куб оставался в центре вида, я рекомендую установить матрицу проекции. , который проецируется симметрично оси X и Y. Например:

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

Обратите внимание, что смещение проекции может привести к смещению прямоугольника вида, и куб будет казаться центрированным (или вращающимся вокруг) в левом нижнем углу области просмотра.

См. Например, чтобы повернуть вид (положение глаза) вокруг куба:

#include <glm/gtc/type_ptr.hpp> // glm::value_ptr
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-screenWidth/2, screenWidth/2, -screenHeight/2, screenHeight/2, 0, 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();

    // [...]
}
...