mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-18 16:08:11 +08:00
地形图完成
This commit is contained in:
parent
e6b97f5363
commit
16fba2241e
@ -117,27 +117,27 @@ void SceneViewer::paintGL() {
|
|||||||
ter->render();
|
ter->render();
|
||||||
terrainShader.unbind();
|
terrainShader.unbind();
|
||||||
|
|
||||||
//_shaderProgram.bind();
|
_shaderProgram.bind();
|
||||||
|
|
||||||
//// Set view and projection matrices
|
// Set view and projection matrices
|
||||||
//_shaderProgram.setUniform("view", view);
|
_shaderProgram.setUniform("view", view);
|
||||||
//_shaderProgram.setUniform("projection", projection);
|
_shaderProgram.setUniform("projection", projection);
|
||||||
|
|
||||||
//for (auto object : _objects) {
|
for (auto object : _objects) {
|
||||||
// object.render(_shaderProgram);
|
object.render(_shaderProgram);
|
||||||
//}
|
}
|
||||||
|
|
||||||
//_shaderProgram.unbind();
|
_shaderProgram.unbind();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//skyshader.bind();
|
skyshader.bind();
|
||||||
//view = glm::mat4(glm::mat3(view));
|
view = glm::mat4(glm::mat3(view));
|
||||||
//skyshader.setUniform("view", view);
|
skyshader.setUniform("view", view);
|
||||||
//skyshader.setUniform("projection", projection);
|
skyshader.setUniform("projection", projection);
|
||||||
//sky->render();
|
sky->render();
|
||||||
//skyshader.unbind();
|
skyshader.unbind();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
Terrain::Terrain(std::string path){
|
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;
|
int rez = 1;
|
||||||
unsigned bytePerPixel = nrChannels;
|
unsigned bytePerPixel = nrChannels;
|
||||||
for (int i = 0; i < height; i++)
|
for (int i = 0; i < height; i++)
|
||||||
{
|
{
|
||||||
|
std::vector<float> temp;
|
||||||
for (int j = 0; j < width; j++)
|
for (int j = 0; j < width; j++)
|
||||||
{
|
{
|
||||||
unsigned char* pixelOffset = data + (j + width * i) * bytePerPixel;
|
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(-height / 2.0f + height * i / (float)height); // vx
|
||||||
vertices.push_back((int)y * yScale - yShift); // vy
|
vertices.push_back((int)y * yScale - yShift); // vy
|
||||||
vertices.push_back(-width / 2.0f + width * j / (float)width); // vz
|
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);
|
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);
|
OPENGL_EXTRA_FUNCTIONS->glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
// position attribute
|
// 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);
|
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->glGenBuffers(1, &terrainIBO);
|
||||||
OPENGL_EXTRA_FUNCTIONS->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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);
|
//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 x = ((int)fx) % height;
|
||||||
int greater_y = ceil(point.y);
|
int z = ((int)fz) % width;
|
||||||
int less_x = floor(point.x);
|
int gx = (x + 1) % height;
|
||||||
int less_y = floor(point.y);
|
int gz = (z + 1) % width;
|
||||||
|
|
||||||
float great_z = Point[greater_x][greater_y];
|
float ans = (x - fx) * (Point[gx][gz] - Point[x][z]) + Point[x][z];
|
||||||
float less_z = Point[less_x][less_y];
|
|
||||||
|
|
||||||
float z = (point.x - less_x) * (great_z - less_z) + less_z;
|
return ans;
|
||||||
|
|
||||||
if (fabs(z - point.z) < 1e-2) {
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
if (z > point.z) {
|
|
||||||
return 1;
|
glm::vec3 Terrain::GetNormal(glm::vec3 pos) {
|
||||||
|
float fx = pos.x;
|
||||||
|
float fz = pos.z;
|
||||||
|
|
||||||
|
glm::vec3 point1(fx - 1, GetHeight(fx - 1, fz - 1), fz - 1);
|
||||||
|
glm::vec3 point2(fx + 1, GetHeight(fx + 1, fz + 1), fz + 1);
|
||||||
|
|
||||||
|
glm::vec3 l1 = pos - point1;
|
||||||
|
glm::vec3 l2 = point2 - point1;
|
||||||
|
glm::vec3 ans = glm::normalize(glm::cross(l1, l2));
|
||||||
|
return ans;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
return -1;
|
lastRayPosition = orig;
|
||||||
|
orig += rayStep;
|
||||||
|
map_height = GetHeight(orig.x, orig.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
glm::vec3 startPosition = lastRayPosition;
|
||||||
|
glm::vec3 endPosition = orig;
|
||||||
|
|
||||||
Vertex Terrain::hitPoint(glm::vec3 orig, glm::vec3 dir) {
|
// Binary search with 32 steps. Try to find the exact collision point
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
glm::vec3 step = glm::normalize(dir);
|
{
|
||||||
|
// Binary search pass
|
||||||
int flag = if_under_terrain(orig);
|
glm::vec3 middlePoint = (startPosition + endPosition) * 0.5f;
|
||||||
|
if (middlePoint.y < height)
|
||||||
glm::vec3 right = orig;
|
endPosition = middlePoint;
|
||||||
while (true) {
|
else
|
||||||
right += step;
|
startPosition = middlePoint;
|
||||||
int temp = if_under_terrain(right);
|
|
||||||
if (temp == 0) {
|
|
||||||
return Vertex(glm::vec3(0.0f));
|
|
||||||
}
|
}
|
||||||
if (flag * temp == -1 || temp == 2) {
|
glm::vec3 position = (startPosition + endPosition) * 0.5f;
|
||||||
glm::vec4 ans = Model * glm::vec4(right,1.0f);
|
glm::vec3 normal = GetNormal(position);
|
||||||
return Vertex(glm::vec3(ans));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -12,16 +12,18 @@ private:
|
|||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
unsigned int terrainVAO, terrainVBO, terrainIBO;
|
unsigned int terrainVAO, terrainVBO, terrainIBO;
|
||||||
std::vector<std::vector<float>> Point;
|
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 width, height, nrChannels;
|
||||||
int numStrips, numTrisPerStrip;
|
int numStrips, numTrisPerStrip;
|
||||||
int NUM_PATCH_PTS = 4;
|
int NUM_PATCH_PTS = 4;
|
||||||
unsigned rez = 20;
|
unsigned rez = 20;
|
||||||
|
float yScale = 64.0f / 256.0f, yShift = 30.0f;
|
||||||
public:
|
public:
|
||||||
unsigned int tex;
|
unsigned int tex;
|
||||||
Terrain(std::string path);
|
Terrain(std::string path);
|
||||||
void render();
|
void render();
|
||||||
unsigned int loadTexture(std::string path);
|
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);
|
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