简体   繁体   English

OpenGL:请帮我理解这个 function

[英]OpenGL: Please help me understand this function

I am trying to understand this function, but I can't seem to follow how this code does its thing.我试图理解这个 function,但我似乎无法理解这段代码是如何工作的。

I am hoping someone can walk me through this so I can understand what's going on.我希望有人可以指导我完成此操作,以便我了解发生了什么。

void mountain::LoadData(const char* heightmap_filename)
{
    heightmap = cv::imread(heightmap_filename, 0);
    heightmap_rows = heightmap.rows;
    heightmap_cols = heightmap.cols;

    for (int i = 0; i < heightmap.rows; i++) 
        height.push_back(vector<float>(heightmap_cols, 0));

    for (int u = 0; u < heightmap_rows; u++)
    {
        for (int v = 0; v < heightmap_cols; v++)
        {
            height[u][v] = heightmap.at<uchar>(u, v);
            Points.push_back(BROAD_CONTROLLER * (u - 128));
            Points.push_back(BROAD_CONTROLLER * (v - 128));
            Points.push_back(HEIGHT_CONTROLLER * height[u][v]);
            Points.push_back((float)u / 255.);
            Points.push_back((float)v / 255.);
        }
    }

    for (int row = 1; row < heightmap_rows; row++)
    {
        for (int col = 1; col < heightmap_cols; col++)
        {
            indices.push_back((row - 1) * heightmap_cols + col - 1);
            indices.push_back((row - 1) * heightmap_cols + col);
            indices.push_back(row * heightmap_cols + col - 1);
            indices.push_back(row * heightmap_cols + col - 1);
            indices.push_back((row - 1) * heightmap_cols + col);
            indices.push_back(row * heightmap_cols + col);
        }
    }
}

May I know what is the Points vector is inserting?我可以知道 Points 向量插入的是什么吗?

Points.push_back(BROAD_CONTROLLER * (u - 128));
Points.push_back(BROAD_CONTROLLER * (v - 128));
Points.push_back(HEIGHT_CONTROLLER * height[u][v]);
Points.push_back((float)u / 255.);
Points.push_back((float)v / 255.);

and what is the indices vector is inserting?插入的索引向量是什么?

indices.push_back((row - 1) * heightmap_cols + col - 1);
indices.push_back((row - 1) * heightmap_cols + col);
indices.push_back(row * heightmap_cols + col - 1);
indices.push_back(row * heightmap_cols + col - 1);
indices.push_back((row - 1) * heightmap_cols + col);
indices.push_back(row * heightmap_cols + col);

This is the function to get silhouette, but I don't get it how does this function work.这是获得轮廓的 function,但我不明白这个 function 是如何工作的。

void mountain::FindSilhouette()
{
    int count = 0;
    for (int i = 0; i < Points.size() / 5; i++)
    {
        if (abs(Points[5 * i + 2] - SEALEVEL) < 2)
        {
            slet buffer(Points[5 * i], Points[5 * i + 1], Points[5 * i + 2]);
            buffer.num = count;
            silhouette.push_back(buffer);
            count++;
        }
    }
}
Points.push_back(BROAD_CONTROLLER * (u - 128));
Points.push_back(BROAD_CONTROLLER * (v - 128));
Points.push_back(HEIGHT_CONTROLLER * height[u][v]);
Points.push_back((float)u / 255.);
Points.push_back((float)v / 255.);

Points contains successive groups of 5 floats. Points包含连续的 5 个浮点组。 The first two are x and y , the two coordinate that the u and v are iterating over.前两个是xy ,这是uv迭代的两个坐标。 The third one is z , which is looked up in the heightmap ( height ).第三个是z ,在高度图( height )中查找。 The fourth and fifth are most likely uv texture coordinates.第四个和第五个很可能是uv纹理坐标。

indices.push_back((row - 1) * heightmap_cols + col - 1);
indices.push_back((row - 1) * heightmap_cols + col);
indices.push_back(row * heightmap_cols + col - 1);
indices.push_back(row * heightmap_cols + col - 1); // <- repeats third
indices.push_back((row - 1) * heightmap_cols + col); // <- repeats second
indices.push_back(row * heightmap_cols + col);

The indices are the indices to use to draw two triangles, in this fashion: indices是用于绘制两个三角形的索引,以这种方式:

0--2
| / 3
|/ /|
1 / |
 4--5

That's why 3 (the fourth) repeats 2 (the third), and 4 repeats 1. heightmap_cols is the number of column in the heightmap, row and col the current position.这就是为什么 3(第四个)重复 2(第三个),4 重复 1。 heightmap_cols是当前 position 的高度图中的列数、行数和列数。 Basically, it builds a list of indices to lookup the position as the heightmap is drawn as a set of pair of triangles.基本上,它构建了一个索引列表来查找 position,因为高度图被绘制为一组三角形。 Each pair forms a square.每对 forms 一个正方形。

May I know what is the Points vector is inserting?

It's effectively inserting a 3D vertex, and a 2D texture coordinate.它有效地插入了 3D 顶点和 2D 纹理坐标。 ie IE

struct Vertex {
  // the 3D position of the vertex
  float x;
  float y;
  float z;
  // the 2D texture coordinate
  float u;
  float u;
};

It generates one of these structures for every single pixel in the input image.它为输入图像中的每个像素生成这些结构之一。 I actually think the code is wrong, because it seems to assume images can only ever be 256x256 pixels?我实际上认为代码是错误的,因为它似乎假设图像只能是 256x256 像素? I'd probably replace the hardcoded 255 and 128 values with the following:我可能会用以下内容替换硬编码的 255 和 128 值:

            // read pixel from image
            height[u][v] = heightmap.at<uchar>(u, v);

            // x & y coordinates 
            Points.push_back(BROAD_CONTROLLER * (u - heightmap_rows/2));
            Points.push_back(BROAD_CONTROLLER * (v - heightmap_cols/2)));
            Points.push_back(HEIGHT_CONTROLLER * height[u][v]);
            Points.push_back((float)u / float(heightmap_rows - 1));
            Points.push_back((float)v / float(heightmap_cols - 1));

That should now work for any image size.这现在应该适用于任何图像大小。

and what is the indices vector is inserting?

indices.push_back((row - 1) * heightmap_cols + col - 1);
indices.push_back((row - 1) * heightmap_cols + col);
indices.push_back(row * heightmap_cols + col - 1);
indices.push_back(row * heightmap_cols + col - 1);
indices.push_back((row - 1) * heightmap_cols + col);
indices.push_back(row * heightmap_cols + col);

To begin with, we now have a 2D grid of vertices (however that has been flattened into a single array - Points ).首先,我们现在有一个 2D 顶点网格(但是它已被展平为单个数组 - Points )。 I could here write a simple lambda to convert a 2D index pair (U & V) into a 1D index, which may make it a bit more obvious as to what is happening我可以在这里编写一个简单的 lambda 来将二维索引对(U & V)转换为一维索引,这可能会使正在发生的事情更加明显

auto index = [heightmap_cols](int row, int col) {
  return row * heightmap_cols + col;
};

//   (row-1, col)          (row,   col)
//
//               o---------o
//               |       / |
//               |  2   /  |
//               |     /   |
//               |    /    |
//               |   /  1  |
//               |  /      |
//               | /       |
//               o---------o
// 
//   (row-1, col-1)        (row-1, col-1)

// indices for first triangle
indices.push_back(index(row - 1, col - 1));
indices.push_back(index(row - 1, col    ));
indices.push_back(index(row    , col - 1));

// indices for second triangle
indices.push_back(index(row    , col - 1));
indices.push_back(index(row - 1, col    ));
indices.push_back(index(row    , col    ));

This is the function to get silhouette, but I don't get it how does this function work.

It is creating a new array of points, containing only those points whose height is lower than some threshold (in this case, SEALEVEL and the magic number '2') .它正在创建一个新的点数组,仅包含那些高度低于某个阈值的点(在本例中为 SEALEVEL 和幻数“2”)

if (abs(Points[5 * i + 2] - SEALEVEL) < 2)

It's probably a badly named function.它可能是一个名字不好的 function。 findAllPointsUnderwater is probably a better name... findAllPointsUnderwater可能是一个更好的名字......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM