mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-17 07:28:12 +08:00
地形图完成
This commit is contained in:
parent
e6b97f5363
commit
16fba2241e
@ -117,27 +117,27 @@ void SceneViewer::paintGL() {
|
||||
ter->render();
|
||||
terrainShader.unbind();
|
||||
|
||||
//_shaderProgram.bind();
|
||||
_shaderProgram.bind();
|
||||
|
||||
//// Set view and projection matrices
|
||||
//_shaderProgram.setUniform("view", view);
|
||||
//_shaderProgram.setUniform("projection", projection);
|
||||
// Set view and projection matrices
|
||||
_shaderProgram.setUniform("view", view);
|
||||
_shaderProgram.setUniform("projection", projection);
|
||||
|
||||
//for (auto object : _objects) {
|
||||
// object.render(_shaderProgram);
|
||||
//}
|
||||
for (auto object : _objects) {
|
||||
object.render(_shaderProgram);
|
||||
}
|
||||
|
||||
//_shaderProgram.unbind();
|
||||
_shaderProgram.unbind();
|
||||
|
||||
|
||||
|
||||
|
||||
//skyshader.bind();
|
||||
//view = glm::mat4(glm::mat3(view));
|
||||
//skyshader.setUniform("view", view);
|
||||
//skyshader.setUniform("projection", projection);
|
||||
//sky->render();
|
||||
//skyshader.unbind();
|
||||
skyshader.bind();
|
||||
view = glm::mat4(glm::mat3(view));
|
||||
skyshader.setUniform("view", view);
|
||||
skyshader.setUniform("projection", projection);
|
||||
sky->render();
|
||||
skyshader.unbind();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -8,16 +8,16 @@
|
||||
|
||||
Terrain::Terrain(std::string path){
|
||||
|
||||
stbi_set_flip_vertically_on_load(false);
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
|
||||
unsigned char* data = stbi_load((path + "/heightmap.png").c_str(), &width, &height, &nrChannels, 0);
|
||||
unsigned char* data = stbi_load("D:/ProgrammingFile/LearnOpenGL/src/8.guest/2021/3.tessellation/terrain_gpu_dist/resources/heightmaps/iceland_heightmap.png", &width, &height, &nrChannels, 0);
|
||||
|
||||
|
||||
float yScale = 64.0f / 256.0f, yShift = 16.0f;
|
||||
|
||||
int rez = 1;
|
||||
unsigned bytePerPixel = nrChannels;
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
std::vector<float> temp;
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
unsigned char* pixelOffset = data + (j + width * i) * bytePerPixel;
|
||||
@ -27,7 +27,11 @@ Terrain::Terrain(std::string path){
|
||||
vertices.push_back(-height / 2.0f + height * i / (float)height); // vx
|
||||
vertices.push_back((int)y * yScale - yShift); // vy
|
||||
vertices.push_back(-width / 2.0f + width * j / (float)width); // vz
|
||||
vertices.push_back((float)i);
|
||||
vertices.push_back((float)j);
|
||||
temp.push_back((int)y * yScale - yShift);
|
||||
}
|
||||
Point.push_back(temp);
|
||||
}
|
||||
stbi_image_free(data);
|
||||
|
||||
@ -53,8 +57,11 @@ Terrain::Terrain(std::string path){
|
||||
OPENGL_EXTRA_FUNCTIONS->glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
// position attribute
|
||||
OPENGL_EXTRA_FUNCTIONS->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
OPENGL_EXTRA_FUNCTIONS->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
OPENGL_EXTRA_FUNCTIONS->glEnableVertexAttribArray(0);
|
||||
// texCoord attribute
|
||||
OPENGL_EXTRA_FUNCTIONS->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(sizeof(float) * 3));
|
||||
OPENGL_EXTRA_FUNCTIONS->glEnableVertexAttribArray(1);
|
||||
|
||||
OPENGL_EXTRA_FUNCTIONS->glGenBuffers(1, &terrainIBO);
|
||||
OPENGL_EXTRA_FUNCTIONS->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, terrainIBO);
|
||||
@ -62,7 +69,7 @@ Terrain::Terrain(std::string path){
|
||||
|
||||
|
||||
//textureID = loadTexture2(texName, GL_REPEAT, GL_REPEAT, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
||||
tex = loadTexture(path + "/white.jpg");
|
||||
tex = loadTexture(path + "/grass.jpg");
|
||||
|
||||
}
|
||||
|
||||
@ -127,48 +134,62 @@ void Terrain::render() {
|
||||
|
||||
}
|
||||
|
||||
int Terrain::if_under_terrain(glm::vec3 point) {
|
||||
float Terrain::GetHeight(float px, float pz) {
|
||||
float fx = px + height / 2;
|
||||
float fz = pz + width / 2;
|
||||
|
||||
int greater_x = ceil(point.x);
|
||||
int greater_y = ceil(point.y);
|
||||
int less_x = floor(point.x);
|
||||
int less_y = floor(point.y);
|
||||
int x = ((int)fx) % height;
|
||||
int z = ((int)fz) % width;
|
||||
int gx = (x + 1) % height;
|
||||
int gz = (z + 1) % width;
|
||||
|
||||
float great_z = Point[greater_x][greater_y];
|
||||
float less_z = Point[less_x][less_y];
|
||||
|
||||
float z = (point.x - less_x) * (great_z - less_z) + less_z;
|
||||
|
||||
if (fabs(z - point.z) < 1e-2) {
|
||||
return 2;
|
||||
}
|
||||
if (z > point.z) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
float ans = (x - fx) * (Point[gx][gz] - Point[x][z]) + Point[x][z];
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
Vertex Terrain::hitPoint(glm::vec3 orig, glm::vec3 dir) {
|
||||
glm::vec3 Terrain::GetNormal(glm::vec3 pos) {
|
||||
float fx = pos.x;
|
||||
float fz = pos.z;
|
||||
|
||||
glm::vec3 step = glm::normalize(dir);
|
||||
glm::vec3 point1(fx - 1, GetHeight(fx - 1, fz - 1), fz - 1);
|
||||
glm::vec3 point2(fx + 1, GetHeight(fx + 1, fz + 1), fz + 1);
|
||||
|
||||
int flag = if_under_terrain(orig);
|
||||
glm::vec3 l1 = pos - point1;
|
||||
glm::vec3 l2 = point2 - point1;
|
||||
glm::vec3 ans = glm::normalize(glm::cross(l1, l2));
|
||||
return ans;
|
||||
}
|
||||
|
||||
glm::vec3 right = orig;
|
||||
while (true) {
|
||||
right += step;
|
||||
int temp = if_under_terrain(right);
|
||||
if (temp == 0) {
|
||||
return Vertex(glm::vec3(0.0f));
|
||||
}
|
||||
if (flag * temp == -1 || temp == 2) {
|
||||
glm::vec4 ans = Model * glm::vec4(right,1.0f);
|
||||
return Vertex(glm::vec3(ans));
|
||||
}
|
||||
void Terrain::hitPoint(glm::vec3 orig, glm::vec3 dir) {
|
||||
// A good ray step is half of the blockScale
|
||||
glm::vec3 rayStep = dir * (float)width * 0.25f;
|
||||
glm::vec3 rayStartPosition = orig;
|
||||
|
||||
// Linear search - Loop until find a point inside and outside the terrain Vector3
|
||||
glm::vec3 lastRayPosition = orig;
|
||||
orig += rayStep;
|
||||
float map_height = GetHeight(orig.x,orig.z);
|
||||
while (orig.y > map_height)
|
||||
{
|
||||
lastRayPosition = orig;
|
||||
orig += rayStep;
|
||||
map_height = GetHeight(orig.x, orig.z);
|
||||
}
|
||||
|
||||
glm::vec3 startPosition = lastRayPosition;
|
||||
glm::vec3 endPosition = orig;
|
||||
|
||||
// Binary search with 32 steps. Try to find the exact collision point
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
// Binary search pass
|
||||
glm::vec3 middlePoint = (startPosition + endPosition) * 0.5f;
|
||||
if (middlePoint.y < height)
|
||||
endPosition = middlePoint;
|
||||
else
|
||||
startPosition = middlePoint;
|
||||
}
|
||||
glm::vec3 position = (startPosition + endPosition) * 0.5f;
|
||||
glm::vec3 normal = GetNormal(position);
|
||||
}
|
||||
@ -12,16 +12,18 @@ private:
|
||||
std::vector<unsigned int> indices;
|
||||
unsigned int terrainVAO, terrainVBO, terrainIBO;
|
||||
std::vector<std::vector<float>> Point;
|
||||
int if_under_terrain(glm::vec3 point);
|
||||
float GetHeight(float px, float pz);
|
||||
glm::vec3 GetNormal(glm::vec3 pos);
|
||||
int width, height, nrChannels;
|
||||
int numStrips, numTrisPerStrip;
|
||||
int NUM_PATCH_PTS = 4;
|
||||
unsigned rez = 20;
|
||||
float yScale = 64.0f / 256.0f, yShift = 30.0f;
|
||||
public:
|
||||
unsigned int tex;
|
||||
Terrain(std::string path);
|
||||
void render();
|
||||
unsigned int loadTexture(std::string path);
|
||||
Vertex hitPoint(glm::vec3 orig, glm::vec3 dir);
|
||||
void hitPoint(glm::vec3 orig, glm::vec3 dir);
|
||||
glm::mat4 Model = glm::mat4(1.0f);
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.8 KiB |
Loading…
x
Reference in New Issue
Block a user