游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5226|回复: 12

救命:简单地形渲染时的一个问题

[复制链接]

1

主题

11

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2007-8-16 21:24:00 | 显示全部楼层 |阅读模式
各位高手,为什么在渲染时会出现中间那些点,而遮挡不了背面被挡的呢?
而且,已经启用了深度缓冲,glClearDepth(1.0); glDepthFunc(GL_LEQUAL);也启用了透视修正为GL_NICEST.
请大侠们救命.. [em6]
sf_2007816212335.jpg

1

主题

11

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2007-8-17 18:51:00 | 显示全部楼层

Re: 救命:简单地形渲染时的一个问题

难道...没人遇到过这个问题吗? 还是无人回复... [em17]

3

主题

53

帖子

104

积分

注册会员

Rank: 2

积分
104
发表于 2007-8-17 20:47:00 | 显示全部楼层

Re: 救命:简单地形渲染时的一个问题

可能是那些地方地形太陡峭,周围没有过渡的缘故

1

主题

11

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2007-8-17 21:43:00 | 显示全部楼层

Re: 救命:简单地形渲染时的一个问题

这..这不大可能吧..渲染是按三角形带来渲染,一排一排地渲染过去的..应该会紧密连接上的啊. 如果是三角形间的衔接不好,那也应该只是边吧? 可这里是..直接整个可以透过去看到后面的东西... 呃...

1

主题

11

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2007-8-20 12:25:00 | 显示全部楼层

Re: 救命:简单地形渲染时的一个问题

还是没人?。。。

180

主题

3511

帖子

3520

积分

论坛元老

Rank: 8Rank: 8

积分
3520
发表于 2007-8-20 20:38:00 | 显示全部楼层

Re:救命:简单地形渲染时的一个问题

1.图片太小,看不清细节。
2.没有渲染部分的代码。

所以,很难判断。

1

主题

11

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2007-8-21 08:01:00 | 显示全部楼层

Re: Re:救命:简单地形渲染时的一个问题

snhun: Re:救命:简单地形渲染时的一个问题

1.图片太小,看不清细节。
2.没有渲染部分的代码。

所以,很难判断。

//源代码:
#include <windows.h>
#include <stdio.h>
#include <gl/gl.h>
#include <gl/glut.h>
#include <gl/glaux.h>
#include <time.h>

#pragma comment(lib, "glaux.lib")

#define SIZE 128
#define TILE_SIZE 5

struct HEIGHT_REGION
{
        int low_height;
        int optimal_height;
        int high_height;
};

//|----|----|----|----|----|

class CTerrain
{
private:
        UCHAR heightmap[SIZE * SIZE];
        float smooth_filter;
        HEIGHT_REGION regions[4];
        GLuint texture;

private:
        void FilterBand(float *band, int stride, int count, float filter);
        void Smooth(float *heightmap);

public:
        CTerrain()
        {
        }

        ~CTerrain()
        {
        }

        int Initialize();

        int GenerateFaultFormation(int num_iterations, float height, float height_reducer);
        int GenerateMidPoint(float height, float height_reducer);

        void Render();

        void GenTexture();

        void Output()
        {
                for (int i=0; i<SIZE/4; i++)
                        for (int j=0; j<SIZE/4; j++)
                                printf("%3d ", heightmap[i*SIZE + j]);
        }
};

int CTerrain::Initialize()
{
        int i, j;

        smooth_filter = 0.3f;

        for (i=0; i<SIZE; i++)
                for (j=0; j<SIZE; j++)
                {
                        heightmap[i * SIZE + j] = 0;
                }

                //初始化高度区域
        int half_height_range = 255 / 4;

        for (int i=0; i<4; i++)
        {
                regions.low_height = i * half_height_range;
                regions.optimal_height = regions.low_height + half_height_range;
                regions.high_height = regions.optimal_height + half_height_range;

                printf("region %d : %d, %d, %d\n",i, regions.low_height, regions.optimal_height, regions.high_height);
        }

        return 1;
}

void CTerrain::FilterBand(float *band, int stride, int count, float filter)
{
        float v = band[0];
        int j = stride;
       

        for (int i = 1; i < count; i++)
        {
                band[j] = filter * v + (1 - filter) * band[j];
                v = band[j];
                j += stride;
        }
}

void CTerrain::Smooth(float *heightmap)
{
        int i;
        for (i=0; i<SIZE; i++)
                FilterBand(&heightmap[i * SIZE], 1, SIZE, smooth_filter);

        for (i=0; i<SIZE; i++)
                FilterBand(&heightmap[i * SIZE + SIZE -1], -1, SIZE, smooth_filter);

        for (i=0; i<SIZE; i++)
                FilterBand(&heightmap, SIZE, SIZE, smooth_filter);

        for (i=0; i<SIZE; i++)
                FilterBand(&heightmap[(SIZE-1) * SIZE + i], -SIZE, SIZE, smooth_filter);
}
               
int CTerrain::GenerateFaultFormation(int num_iterations, float height, float height_reducer)
{
        int curr_iteration = 0;
        int x1, z1, x2, z2;
        int dir_x1, dir_z1, dir_x2, dir_z2;
        int i, j;

        float *temp_buffer = new float[SIZE * SIZE];

        for (i=0; i<SIZE*SIZE; i++)
                temp_buffer = 0.0f;

        for (; curr_iteration < num_iterations; curr_iteration++)
        {
                do
                {
                        x1 = rand()%SIZE;
                        z1 = rand()%SIZE;
                        x2 = rand()%SIZE;
                        z2 = rand()%SIZE;
                }while (x1 == x2 && z1 == z2);

                dir_x1 = x2 - x1;
                dir_z1 = z2 - z1;

                for (i=0; i<SIZE; i++)
                        for (j=0; j<SIZE; j++)
                        {
                                dir_x2 = j - x1;
                                dir_z2 = i - z1;

                                if (dir_x1 * dir_z2 - dir_z1 * dir_x2 > 0)
                                        temp_buffer[i*SIZE + j] += height;
                        }

                height *= height_reducer;

                Smooth(temp_buffer); //在这里平滑

        }

        //filter to 0~255
        float max_height, min_height, height_range;

        max_height = min_height = temp_buffer[0];

        for (i=0; i<SIZE * SIZE; i++)
        {
                if (temp_buffer > max_height)
                        max_height = temp_buffer;
                else
                if (temp_buffer < min_height)
                        min_height = temp_buffer;
        }

        height_range = max_height - min_height;

        for (i=0; i<SIZE * SIZE; i++)
        {
                heightmap = (UCHAR)((temp_buffer - min_height) * 255.0f / height_range);
        }

        delete[] temp_buffer;

        return 1;
}


int CTerrain::GenerateMidPoint(float height, float height_reducer)
{
        int i, j, index;
        int rect_size = SIZE;

        float *temp_buffer = new float[SIZE * SIZE];

        for (i=0; i<SIZE*SIZE; i++)
                temp_buffer = 0.0f;

        while (rect_size > 0)
        {
                for (i=0; i<SIZE; i+=rect_size)
                        for (j=0; j<SIZE; j+=rect_size)
                        {
                                index = i * rect_size * SIZE + j * rect_size;
                                if (index > 0 && index < SIZE * SIZE)
                                        temp_buffer[index] = (temp_buffer[index-rect_size] + temp_buffer[index+rect_size] + temp_buffer[index - SIZE*rect_size] + temp_buffer[index+SIZE*rect_size]) * 0.25 - height + rand()%((int)(height*2.0f));
                        }
               
                Smooth(temp_buffer);
                height *= height_reducer;
                rect_size /= 2;
        }

        float max_height, min_height, height_range;

        max_height = min_height = temp_buffer[0];

        for (i=0; i<SIZE * SIZE; i++)
        {
                if (temp_buffer > max_height)
                        max_height = temp_buffer;
                else
                if (temp_buffer < min_height)
                        min_height = temp_buffer;
        }

        height_range = max_height - min_height;

        for (i=0; i<SIZE * SIZE; i++)
        {
                heightmap = (UCHAR)((temp_buffer - min_height) * 255.0f / height_range);
        }

        delete[] temp_buffer;

        return 1;
}

void CTerrain::Render()
{
        glPushMatrix();
                glTranslatef(-SIZE*TILE_SIZE*0.5f, 0, -SIZE*TILE_SIZE*0.5f);
               
                int i, j;
                UCHAR color;

                glColor3f(1.0f, 1.0f, 1.0f);

                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, texture);

                for (i=0; i<SIZE-1; i++)
                {
                        glBegin(GL_TRIANGLE_STRIP);
                        for (j=0; j<SIZE-1; j++)
                        {
                                color = heightmap[i * SIZE + j];
        //                        glColor3ub(color, color, color);
                                glTexCoord2f((float)j / (float)SIZE, (float)i / (float)SIZE);
                                glVertex3f(j * TILE_SIZE, color, i * TILE_SIZE);

                                color = heightmap[i * SIZE + j + SIZE];
                        //  glColor3ub(color, color, color);
                                glTexCoord2f((float)j / (float)SIZE, (float)(i+1) / (float)SIZE);
                                glVertex3f(j * TILE_SIZE, color, i * TILE_SIZE + TILE_SIZE);
                        }
                        glEnd();
                }

        glPopMatrix();
}


void CTerrain::GenTexture()
{
        float u_ratio, v_ratio;
        AUX_RGBImageRec *image[4];
        image[0] = auxDIBImageLoad("lowestTile.bmp");
        image[1] = auxDIBImageLoad("lowTile.bmp");
        image[2] = auxDIBImageLoad("highTile.bmp");

        image[3] = auxDIBImageLoad("highestTile.bmp");

        int i, j, curr_tile, index;
        int height;
        float presence;

        UCHAR data[SIZE * SIZE * 3] = {0};

        float half_height = 255.0f / 4.0f;

        for (i=0; i<SIZE; i++)
                for (j=0; j<SIZE; j++)
                {
                        index = i * SIZE + j;
                        height = heightmap[index];
                        for (curr_tile=0; curr_tile < 4; curr_tile++)
                        {
                                if (height > regions[curr_tile].low_height && height < regions[curr_tile].high_height)
                                {
                                        if (height < regions[curr_tile].optimal_height)
                                                presence = (float)(height - regions[curr_tile].low_height) / half_height;
                                        else
                                                presence = (float)(regions[curr_tile].high_height - height) / half_height;

                                        data[index * 3 + 0] += image[curr_tile]->data[index * 3 + 0] * presence;
                                        data[index * 3 + 1] += image[curr_tile]->data[index * 3 + 1] * presence;
                                        data[index * 3 + 2] += image[curr_tile]->data[index * 3 + 2] * presence;

                        //                printf("(%2d, %2d, %2d, %2d, %.2f) ", regions[curr_tile].low_height, regions[curr_tile].optimal_height, regions[curr_tile].high_height, height, presence);
                                }

                        }

        //                printf("(%3d %3d %3d)", data[index * 3 + 0], data[index * 3 + 1], data[index * 3 + 2]);
                }

        for (curr_tile = 0; curr_tile < 4; curr_tile ++)
        {
                if (image[curr_tile]->data)
                        free(image[curr_tile]->data);
        }

        //gen texture
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
       
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}


//main.cpp

CTerrain terrain;

void init()
{
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
       
        glEnable(GL_DEPTH_TEST);
        glClearDepth(1.0f);
        glDepthFunc(GL_LEQUAL);

//        glEnable(GL_CULL_FACE);
        glDisable(GL_CULL_FACE);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

        glShadeModel(GL_SMOOTH);

        srand(time(NULL));

        terrain.Initialize();
        terrain.GenerateFaultFormation(32, 128, 0.95f);
//        terrain.GenerateMidPoint(64, 0.9f);
        terrain.GenTexture();
//        terrain.Output();
}

void reshape(GLsizei w, GLsizei h)
{
        glViewport(0, 0, w, h);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
       
        gluPerspective(90, 1.0f, 0.0f, 1000.0f);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
       
        gluLookAt(0.0f, 400.0f, 500.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
}

void display()
{
        int time_counter = GetTickCount();

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        static float rot = 0.0f;

        rot += 5.0f;

        if (rot > 360.0f)
                rot -= 360.0f;

        glPushMatrix();
                glRotatef(rot, 0.0f, 1.0f, 0.0f);
                terrain.Render();
        glPopMatrix();

        glutSwapBuffers();

        while (GetTickCount() - time_counter < 33);

        glutPostRedisplay();
}

void keyboard(int key, int mousex, int mousey)
{
        switch (key)
        {
        case GLUT_KEY_UP:
                terrain.GenerateFaultFormation(32, 128, 0.9f);
                break;
        }
}

void main()
{
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("Frac terrain generation");
        glutReshapeFunc(reshape);
        glutDisplayFunc(display);
        glutSpecialFunc(keyboard);

        init();

        glutMainLoop();
}





6

主题

33

帖子

33

积分

注册会员

Rank: 2

积分
33
发表于 2007-8-21 23:02:00 | 显示全部楼层

Re: Re: Re:救命:简单地形渲染时的一个问题

vcxyk: Re: Re:救命:简单地形渲染时的一个问题

你的是Focus on 3D Terrain中的程序吧?

你试试把视锥体的远平面设的近一点
我以前好像碰到过这个问题

1

主题

11

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2007-8-22 10:08:00 | 显示全部楼层

Re: Re: Re: Re:救命:简单地形渲染时的一个问题

xiaowantong: Re: Re: Re:救命:简单地形渲染时的一个问题


你的是Focus on 3D Terrain中的程序吧?

你试试把视锥体的远平面设的近一点
我以前好像碰到过这个问题

谢谢你的建议,可是问题仍然存在。而且,gluPerspective(angle, aspect_ratio, near_plane, far_plane)中,只要我把far_plane设成大于0的任意无论多小的数,也都能看到整个地形,而且,仍然会透过.. 看起来像是深度缓冲的问题.. 可是就是找不出来..自杀中..

180

主题

3511

帖子

3520

积分

论坛元老

Rank: 8Rank: 8

积分
3520
发表于 2007-8-22 13:06:00 | 显示全部楼层

Re: Re: Re: Re: Re:救命:简单地形渲染时的一个问题

[em15]其实,渲染部分也就是以下这几行:
  1. for (i=0; i<SIZE-1; i++)
  2. {
  3.   glBegin(GL_TRIANGLE_STRIP);
  4.   for (j=0; j<SIZE-1; j++)
  5.   {
  6.     color = heightmap[i * SIZE + j];
  7.     glTexCoord2f((float)j / (float)SIZE, (float)i / (float)SIZE);
  8.     glVertex3f(j * TILE_SIZE, color, i * TILE_SIZE);
  9.     color = heightmap[i * SIZE + j + SIZE];
  10.     glTexCoord2f((float)j / (float)SIZE, (float)(i+1) / (float)SIZE);
  11.     glVertex3f(j * TILE_SIZE, color, i * TILE_SIZE + TILE_SIZE);
  12.   }
  13.   glEnd();
  14. }
复制代码

看不出有什么缺口。
你把 gluPerspective(90, 1.0f, 0.0f, 1000.0f);
改成 gluPerspective(90, 1.0f, 100.0f, 1000.0f);
然后把运行结果告诉我吧。

如果方便的话,把 原代码+资源文件 打包发给我:
liangshengxun@163.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-4-5 07:45

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表