首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >连接天台和平面的OpenGL

连接天台和平面的OpenGL
EN

Stack Overflow用户
提问于 2014-03-31 16:14:56
回答 1查看 3.5K关注 0票数 2

我正在建设一个简单的城市与OpenGL和过剩,我创造了一个质感天穹,现在我想连接一个平面,以提供一个地平线的外观。为了给出相对的尺寸,天穹半径为3.0,关闭深度掩模,只有相机旋转,并坐在相机上方。一座建筑物的大小约为30.0,我正从y=500.0向下看它。

我有一个地面平面,是1000x1000,我是纹理与1024x1024分辨率纹理,看起来很近,当我是对着地面。我的纹理用GL_REPEAT加载,纹理坐标为1000,可以重复1000次。

把天穹和平地平面连接起来是我遇到问题的地方。我会列举一些我尝试过的事情。

问题:

( 1)当我旋转航向时,由于平面的方形性质,我看到的边缘像附图,而不是平平的地平线。

( 2)我尝试了一个圆形的地面平面,但是我得到了一个曲线地平线,当我飞起来时,它会变得更弯曲。

( 3)为了避免无限天穹顶和我有限大小的平面之间的黑色空隙,我对我能飞的高度设置了一个限制,并在我上升的时候将天穹稍微向下移动,所以我在高处看不到无限天顶和我的平面之间的黑色间隙。是否有其他方法将飞机淡入穹顶,并在不同位置的空隙大小变化时照顾空隙(即。围正方形的圆圈)?我试着在地平线上涂上迷雾的颜色,但在白色的地面上我看到了一层紫色的薄雾。

( 4)如果我把地面贴在天穹半球的底部盖子上,那么当我放大和缩小时,它看起来很奇怪,它看起来像是在滑动,并且与我的建筑断开了连接。

( 5)通过设置w=0,尝试用消失点的概念绘制无限大平面。绘制无限大平面视界看起来是平的,但是正确的纹理看起来很困难,所以我只能使用单一的颜色。

6)如果我想让地面平面照明,那么在一定的俯仰角下,我的飞机看起来会是黑色的,但我的天空仍然是完全亮着的,而且看起来很不自然。

( 7)如果我使我的飞机变大,如10000×10000,地平线就会看上去是平的,但是,如果我按箭头键调整航向,地平线就会摇晃几秒钟,然后稳定下来,是什么造成的,以及如何防止它。与此相关的一个问题是,似乎平铺和纹理1000x1000地面平面和10000x10000不影响我的帧速率,为什么?更多的瓷砖不就意味着更多的工作吗?

8)我阅读了一些基于数学的方法,通过计算裁剪矩形来绘制地平线,但我不知道是否有更简单的方法/technical/graphics-programming-and-theory/a-super-simple-method-for-creating-infinite-sce-r2769

我所读到的大多数关于地平线的文章都会说,使用天窗,使用天穹,但我还没有遇到一个关于将天穹和一个大的地面平面很好地合并的具体教程。一个指向这样一个教程的指针将是很好的。请随意回答问题的任何部分,指出数字,我不想分开,因为它们都是相关的。谢谢。

下面是我设置的一些相关代码:

代码语言:javascript
复制
void Display()
    {        

        // Clear frame buffer and depth buffer
        glClearColor (0.0,0.0,0.0,1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);     

        glLoadIdentity();
        camera.Update();

        GLfloat accumulated_camera_rotation_matrix[16];
        GetAccumulatedRotationMatrix(accumulated_camera_rotation_matrix);

        SkyDome_Draw(accumulated_camera_rotation_matrix);

        FlatGroundPlane_Draw();     

        // draw buildings

        // swap buffers when GLUT_DOUBLE double buffering is enabled
        glutSwapBuffers();

    }

    void SkyDome_Draw(GLfloat (&accumulated_camera_rotation_matrix)[16])
    {
        glPushMatrix();
        glLoadIdentity();
        glDepthMask(GL_FALSE);
        glDisable(GL_LIGHTING);     

        glMultMatrixf(accumulated_camera_rotation_matrix);

        // 3.0f is the radius of the skydome        
        // If we offset by 0.5f in camera.ground_plane_y_offset, we can offset by another 1.5f 
        // at skydome_sky_celing_y_offset of 500.  500 is our max allowable altitude
        glTranslatef( 0, -camera.ground_plane_y_offset - camera.GetCameraPosition().y /c amera.skydome_sky_celing_y_offset/1.5f, 0);

        skyDome->Draw();                
        glEnable(GL_LIGHTING);
        glDepthMask(GL_TRUE);       
        glEnable(GL_CULL_FACE);
        glPopMatrix();
    }

    void GetAccumulatedRotationMatrix(GLfloat (&accumulated_rotation_matrix)[16])
    {
        glGetFloatv(GL_MODELVIEW_MATRIX, accumulated_rotation_matrix);
        // zero out translation is in elements m12, m13, m14
        accumulated_rotation_matrix[12] = 0;
        accumulated_rotation_matrix[13] = 0;
        accumulated_rotation_matrix[14] = 0;
    }

    GLfloat GROUND_PLANE_WIDTH = 1000.0f;

    void FlatGroundPlane_Draw(void) 
    {   

        glEnable(GL_TEXTURE_2D);            
        glBindTexture( GL_TEXTURE_2D, concreteTextureId); 
        glBegin(GL_QUADS);  


        glNormal3f(0, 1, 0);

        glTexCoord2d(0, 0);


        // repeat 1000 times for a plane 1000 times in width
        GLfloat textCoord = GROUND_PLANE_WIDTH;

        glVertex3f( -GROUND_PLANE_WIDTH, 0, -GROUND_PLANE_WIDTH);

        // go beyond 1 for texture coordinate so it repeats
        glTexCoord2d(0, textCoord);

        glVertex3f( -GROUND_PLANE_WIDTH, 0, GROUND_PLANE_WIDTH);

        glTexCoord2d(textCoord, textCoord);
        glVertex3f( GROUND_PLANE_WIDTH, 0, GROUND_PLANE_WIDTH);

        glTexCoord2d(textCoord, 0);
        glVertex3f( GROUND_PLANE_WIDTH, 0, -GROUND_PLANE_WIDTH);

        glEnd();

        glDisable(GL_TEXTURE_2D);
    }

    Void Init()
    {
        concreteTextureId = modelParser->LoadTiledTextureFromFile(concreteTexturePath);
    }

    ModelParser::LoadTiledTextureFromFile(string texturePath)
    {
        RGBImage image; // wrapping 2-d array of data
        image.LoadData(texturePath);
        GLuint texture_id;
        UploadTiledTexture(texture_id, image);
        image.ReleaseData();
        return texture_id;
    }


    void ModelParser::UploadTiledTexture(unsigned int &iTexture, const RGBImage &img)
    {
        glGenTextures(1, &iTexture); // create the texture
        glBindTexture(GL_TEXTURE_2D, iTexture);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        // the texture would wrap over at the edges (repeat)
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img.Width(), img.Height(), GL_RGB, GL_UNSIGNED_BYTE, img.Data());

}
EN

回答 1

Stack Overflow用户

发布于 2014-03-31 20:19:01

尝试使用随机的高度图,而不是使用平面。这不仅看起来更现实,它将使地面的边缘隐形,因为海拔的变化。你也可以尝试加入一些顶点雾,以模糊的地区,天空框和地面平面相交。这大概是我做的,这里

很多3D渲染都依赖于技巧来让事情看起来更逼真。如果你看大多数游戏,他们要么有一大堆前景物体遮住地平线,要么他们在远处有“山”(拉高图),也遮住了地平线。

另一个想法是将你的地面平面映射到一个球体上,这样它就像地球一样向下弯曲。这可能会让地平线看起来更像地球。这类似于你对圆形地面的处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22766749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档