将射弹模拟转换为 3D 会导致绘图消失?

标签 c opengl 3d freeglut opengl-compat

我有一段代码可以成功绘制 2D 射弹,但我需要应用更改才能在 3D 中绘制。

#include <stdio.h>
#include <GL/glut.h>
#include <math.h>
#include <unistd.h>

#define g 9.8
#define PI 3.14
#define ESC 27



void initialize(void)
{
    glClearColor(0, 0, 0, 0);
    glColor3f(0.0, 1.0, 0.0);
    glPointSize(3.0);
    glEnable(GL_POINT_SMOOTH);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, 1000, 0, 500);
}

static void keyPressFunc(unsigned char key, int x, int y)
{
    switch(key) {
        case ESC:
            exit(1);
    }
}

void display(void)
{
    float Pheta, Pheta2, Pheta3,Pheta4, Vo, time, time_top, d1, d2, d3, Uox1, Uox2, Uox3;
    Vo = 60;
    Pheta = 60;
    Pheta2 = 30;
    Pheta3 = 40;
    Pheta4 = 50;
    time = (2 * Vo * sin(Pheta * PI / 180)) / g;
    time_top = time/2;
    d1 = 500;
    d2 = 650;
    d3 = 800;

    Uox1 = (d1 - Vo * cos(Pheta * PI / 180) * 2)/2;
    Uox2 = (d2 - Vo * cos(Pheta * PI / 180)*  time_top)/time_top;
    Uox3 = (d3 - Vo * cos(Pheta * PI / 180) * 8)/8;


    for(float t=0; t < 12 ; t += 0.0005)
    {
        float x1 = (Vo * cos(Pheta * PI / 180) * t);
        float y1 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        float x2 = (d1 - Uox1 * t);
        float y2 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        float x3 = (d2 - Uox2 * t);
        float y3 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        float x4 = (d3 - Uox3 * t);
        float y4 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        glBegin(GL_POINTS);
        glVertex2d(x1, y1);
        glVertex2d(x2, y2);
        glVertex2d(x3, y3);
        glVertex2d(x4, y4);

        if  (x1+0.1 >= x4 && x4+0.1 >= x1)
        {
            break;
        }

        glEnd();
        glFlush();
    }

}

int main(int argc, char** argv)
{

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

    glutInitWindowSize(800, 600);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("C-Lang-Project");

    glutKeyboardFunc(keyPressFunc);

    initialize();
    glutDisplayFunc(display);
    glutMainLoop();
}

为了使其成为 3D,我将 glVertex2d 更改为 glVertex3d,设置变量 z 并将其添加到 glVertex3d。 我得到的最终代码:

#include <stdio.h>
#include <GL/glut.h>
#include <math.h>
#include <unistd.h>

#define g 9.8
#define PI 3.14
#define ESC 27


void initialize(void)
{
    glClearColor(0, 0, 0, 0);
    glColor3f(0.0, 1.0, 0.0);
    glPointSize(3.0);
    glEnable(GL_POINT_SMOOTH);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(0, 1000, 0, 500);
}

static void keyPressFunc(unsigned char key, int x, int y)
{
    switch(key) {
        case ESC:
            exit(1);
    }
}

void display(void)
{
    float Pheta, Pheta2, Pheta3,Pheta4, Vo, time, time_top, d1, d2, d3, Uox1, Uox2, Uox3, z;
    Vo = 60;
    Pheta = 60;
    Pheta2 = 30;
    Pheta3 = 40;
    Pheta4 = 50;
    time = (2 * Vo * sin(Pheta * PI / 180)) / g;
    time_top = time/2;
    d1 = 500;
    d2 = 650;
    d3 = 800;
    z = 15;

    Uox1 = (d1 - Vo * cos(Pheta * PI / 180) * 2)/2;
    Uox2 = (d2 - Vo * cos(Pheta * PI / 180)*  time_top)/time_top;
    Uox3 = (d3 - Vo * cos(Pheta * PI / 180) * 8)/8;

    for(float t=0; t < 12 ; t += 0.0005)
    {
        float x1 = (Vo * cos(Pheta * PI / 180) * t);
        float y1 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        float x2 = (d1 - Uox1 * t);
        float y2 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        float x3 = (d2 - Uox2 * t);
        float y3 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        float x4 = (d3 - Uox3 * t);
        float y4 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

        glBegin(GL_POINTS);
        glVertex3d(x1, y1, z);
        glVertex3d(x2, y2, z);
        glVertex3d(x3, y3, z);
        glVertex3d(x4, y4, z);

        if  (x1+0.1 >= x4 && x4+0.1 >= x1)
        {
            break;
        }

        glEnd();
        glFlush();
    }

}
int main(int argc, char** argv)
{

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

    glutInitWindowSize(800, 600);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("C-Lang-Project");

    glutKeyboardFunc(keyPressFunc);

    initialize();
    glutDisplayFunc(display);
    glutMainLoop();
}

但它没有显示任何错误,只是显示一个黑色窗口。

附言我正在使用 OpenGL 和 freeglut

最佳答案

场景被正射投影的近平面裁剪。

几何的 z 坐标设置为 z=15; 但正射投影设置为 gluOrtho2D(0, 1000, 0, 500);gluOrtho2D设置 -1 的近平面和 1 的远平面。
View 空间 z 坐标必须位于近平面和远平面之间。
由于 View 空间z轴指向视口(viewport)外,因此 View 空间z坐标为-15。

这意味着,如果 z=15 则必须满足以下条件:

near < -15 < far 

更改正交投影以解决问题。使用 glOrtho :

例如

void initialize(void)
{
    // [...]

    glOrtho(0, 1000, 0, 500, -20, 1);
}

当然可以切换到透视投影。在这种情况下,您必须反转 z 坐标。
要获得屏幕上的所有几何体(在裁剪空间中),我建议增加 z 坐标的数量和(当然)到远平面的距离:

例如

void display(void)
{
    float z = -500;

    // [...]
}
void initialize(void)
{
    // [...]


    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective( 90.0, 1000.0 / 500.0, 0.1, 1000.0 );
}

不要在事件处理循环中实现渲染循环。使用 glutPostRedisplay强制重新绘制显示:

float t=0;

void display(void)
{
    float Pheta, Pheta2, Pheta3,Pheta4, Vo, time, time_top, d1, d2, d3, Uox1, Uox2, Uox3, z;
    Vo = 60;  Pheta = 60; Pheta2 = 30; Pheta3 = 40; Pheta4 = 50;
    time = (2 * Vo * sin(Pheta * PI / 180)) / g;
    time_top = time/2; d1 = 500; d2 = 650; d3 = 800;
    z = 15;

    Uox1 = (d1 - Vo * cos(Pheta * PI / 180) * 2)/2;
    Uox2 = (d2 - Vo * cos(Pheta * PI / 180)*  time_top)/time_top;
    Uox3 = (d3 - Vo * cos(Pheta * PI / 180) * 8)/8;

    float x1 = (Vo * cos(Pheta * PI / 180) * t);
    float y1 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);
    float x2 = (d1 - Uox1 * t);
    float y2 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);
    float x3 = (d2 - Uox2 * t);
    float y3 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);
    float x4 = (d3 - Uox3 * t);
    float y4 = (Vo * sin(Pheta * PI / 180) * t - 0.5 * g * t * t);

    glBegin(GL_POINTS);
    glVertex3d(x1, y1, z);
    glVertex3d(x2, y2, z);
    glVertex3d(x3, y3, z);
    glVertex3d(x4, y4, z);
    glEnd();

    t += 0.0005;

    glFlush();
    glutPostRedisplay();
}

关于将射弹模拟转换为 3D 会导致绘图消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56026511/

相关文章:

c++ - 在 Mac OS X 上使用现代 OpenGL

c++ - glEnable(GL_ALPHA_TEST) 给出了无效的枚举(似乎被折旧了——虽然代码有效——但为什么呢?)

c++ - 添加额外的渲染调用时 GLFW 在关闭时挂起

javascript - 需要。 JavaScript 3D 框架,具有帧速率和键盘事件的精确时间戳

javascript - 4点图像变换

wpf - 在WPF中绘制3D线

c - Unsigned Char 位访问,确定 char 是否由 1 和 0 组成

C—修改数据时出现段错误

C数据段标识

c - 设置定时器问题