【问题标题】:Cube not being displayed as a cube多维数据集未显示为多维数据集
【发布时间】:2020-01-28 06:26:40
【问题描述】:

我有一些代码在其中创建了一个立方体,然后将多边形模式更改为line。然后我意识到它看起来不像一个立方体,只是看起来像一个正方形,所以我试着旋转它。它似乎在旋转,但停止显示正方形的一部分,而且它似乎不是一个立方体。我不确定我是否正确旋转或正确绘制立方体,甚至两者兼而有之。

完整的 c++ 代码:

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

void DrawCube(GLfloat centerPosX, GLfloat centerPosY, GLfloat centerPosZ, GLfloat edgeLength);

int main(void) {
    GLFWwindow* window;

    //Init library
    if (!glfwInit())
        return -1;
    //create a window
    glEnable(GL_DEPTH_TEST);
    GLfloat screenWidth = 640;
    GLfloat screenHeight = 480;
    window = glfwCreateWindow(screenWidth, screenHeight, "electroCaft", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glViewport(0.0f, 0.0f, screenWidth, screenHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, screenWidth, 0, screenHeight, 0, 500); // essentially setting coodinates
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_DEPTH_TEST);

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

    //loop until user closes window
    while (!glfwWindowShouldClose(window)) {
        //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

        DrawCube(halfScreenWidth, halfScreenHeight, -500, 250); //x,y,w,h z is calculated in cube func
        //DrawCube(halfScreenWidth, halfScreenHeight - 100, -500, 250);

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

}


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);
    glVertexPointer( 3, GL_FLOAT, 0, vertices);
    glDrawArrays(GL_QUADS, 0, 24);
    glDisableClientState(GL_VERTEX_ARRAY);
}

【问题讨论】:

    标签: c++ opengl matrix rotation opengl-compat


    【解决方案1】:

    不计算立方体的平移顶点坐标。在 (0, 0, 0) 周围绘制立方体。使用glTranslate 将立方体移动到其在世界中的位置。因为立方体可以旋转glRotate。由于glTranslateglRotate 创建一个矩阵并将当前矩阵乘以新矩阵,所以glRotate 指令必须在glTranslate 指令之后执行。
    如果立方体是立方体到眼睛位置的距离是500,到远平面的距离是500,那么立方体的后半部分将被剪裁。当您通过glOrtho 设置Orthographic projection 时,您必须更改远平面。例如:

    glViewport(0.0f, 0.0f, screenWidth, screenHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, screenWidth, 0, screenHeight, 0, 1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_DEPTH_TEST);
    
    GLfloat angle = 1.0;
    while (!glfwWindowShouldClose(window)) {
    
        glClearColor(62.0f / 255.0f, 85.9f / 255.0f, 255.0 / 255.0, 0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glPushMatrix();
    
        glTranslatef((GLfloat)screenWidth/2.0f, (GLfloat)screenHeight/2.0f, -500.0f );
        glRotatef(angle, 0.5f, 1.0f, 0.0f);
        angle += 1.0f;
        DrawCube(0.0, 0.0, 0.0, 250);
    
        glPopMatrix();
    
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    

    无论如何,对于“真实”的 3 维外观,我建议通过gluPerspective 设置Perspective projection。例如:

    glViewport(0.0f, 0.0f, screenWidth, screenHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.0, (float)screenWidth/screenHeight, 1.0, 1000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_DEPTH_TEST);
    
    GLfloat angle = 1.0;
    while (!glfwWindowShouldClose(window)) {
    
        glClearColor(62.0f / 255.0f, 85.9f / 255.0f, 255.0 / 255.0, 0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glPushMatrix();
    
        glTranslatef(0.0, 0.0, -500 );
        glRotatef(angle, 0.5f, 1.0f, 0.0f);
        angle += 1.0f;
        DrawCube(0.0, 0.0, 0.0, 250);
    
        glPopMatrix();
    
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    

    【讨论】:

    • 这是一个非常有帮助的答案,帮助我了解了 Opengl
    • 如何在不旋转的情况下显示完整的立方体
    • @Dextron 设置一个恒定的角度(例如angle=45.0f;),但不要增加它(删除angle += 1.0f;
    猜你喜欢
    • 2023-03-04
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多