地形图的hitpoint

使用线性搜索法
This commit is contained in:
胤龙 2022-12-18 16:59:14 +08:00
parent 15bcb698bd
commit ada32313b8
4 changed files with 85 additions and 18 deletions

View File

@ -104,16 +104,15 @@ void SceneViewer::resizeGL(int w, int h) {
void SceneViewer::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 view = _camera.viewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(_camera.zoomVal()), (float)width() / (float)height(), 0.1f, 100.0f);
terrainShader.bind();
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 view = _camera.viewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(_camera.zoomVal()), (float)width() / (float)height(), 0.1f, 100.0f);
Model = glm::translate(Model, glm::vec3(0.0f, -5.0f, 0.0f));
Model = glm::scale(Model, glm::vec3(100.0f));
terrainShader.setUniform("view", view);
terrainShader.setUniform("projection", projection);
terrainShader.setUniform("model", Model);
terrainShader.setUniform("model",ter->Model);
terrainShader.setUniform("texture1", 2);
ter->render();
terrainShader.unbind();

View File

@ -1,13 +1,19 @@
#include "terrain.h"
#include "utils.h"
#include "vertex.h"
#include <STBImage/stb_image.h>
#include <vector>
#include <GLM/glm.hpp>
#include <GLM/gtc/type_ptr.hpp>
Terrain::Terrain(std::string path){
Vertex.clear();
_Vertex.clear();
Indicess.clear();
int imgW, imgH, imgChannel;
Point.clear();
Model = glm::translate(Model, glm::vec3(0.0f, -10.0f, 0.0f));
Model = glm::scale(Model, glm::vec3(20.0f));
unsigned char* data = stbi_load((path + "/heightmap.jpg").c_str(), &imgW, &imgH, &imgChannel, 1);
@ -19,21 +25,26 @@ Terrain::Terrain(std::string path){
if (data) {
for (int r = 0; r < imgH; r++)
{
std::vector<float> temp;
for (int c = 0; c < imgW; c++)
{
//生成顶点数组, 坐标按照三角网格处理 GL_TRIGANLES
index1 = r * imgW + c;
Vertex.push_back((c - xrate) / xrate);
Vertex.push_back(data[index1] / 255.0f);
Vertex.push_back((r - rrate) / rrate);
_Vertex.push_back((c - xrate) / xrate);
_Vertex.push_back(data[index1] / 255.0f);
_Vertex.push_back((r - rrate) / rrate);
temp.push_back(data[index1] / 255.0f);
//顶点颜色
Vertex.push_back(1.0f);
Vertex.push_back(0.0f);
Vertex.push_back(0.0f);
_Vertex.push_back(1.0f);
_Vertex.push_back(0.0f);
_Vertex.push_back(0.0f);
//纹理坐标
Vertex.push_back((c - xrate) / imgW);
Vertex.push_back((r - rrate) / imgH);
_Vertex.push_back((c - xrate) / imgW);
_Vertex.push_back((r - rrate) / imgH);
}
Point.push_back(temp);
}
imgH -= 1;
int iW = imgW - 1;
@ -65,7 +76,7 @@ Terrain::Terrain(std::string path){
OPENGL_EXTRA_FUNCTIONS->glBindVertexArray(VAO);
OPENGL_EXTRA_FUNCTIONS->glBindBuffer(GL_ARRAY_BUFFER, VBO);
OPENGL_EXTRA_FUNCTIONS->glBufferData(GL_ARRAY_BUFFER, Vertex.size() * sizeof(float), &Vertex[0], GL_STATIC_DRAW);
OPENGL_EXTRA_FUNCTIONS->glBufferData(GL_ARRAY_BUFFER, _Vertex.size() * sizeof(float), &_Vertex[0], GL_STATIC_DRAW);
OPENGL_EXTRA_FUNCTIONS->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
OPENGL_EXTRA_FUNCTIONS->glBufferData(GL_ELEMENT_ARRAY_BUFFER, Indicess.size() * sizeof(unsigned int), &Indicess[0], GL_STATIC_DRAW);
@ -137,4 +148,54 @@ void Terrain::render() {
OPENGL_EXTRA_FUNCTIONS->glBindVertexArray(VAO);
OPENGL_EXTRA_FUNCTIONS->glDrawElements(GL_TRIANGLES, Indicess.size(), GL_UNSIGNED_INT, 0);
}
int Terrain::if_under_terrain(glm::vec3 point) {
if (point.x >= imgH-1 || point.y >= imgW-1 || point.x < 0 || point.y < 0) {
return 0;
}
int greater_x = ceil(point.x);
int greater_y = ceil(point.y);
int less_x = floor(point.x);
int less_y = floor(point.y);
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;
}
}
Vertex Terrain::hitPoint(glm::vec3 orig, glm::vec3 dir) {
if (orig.x >= imgH - 1 || orig.y >= imgW - 1 || orig.x <0 || orig.y < 0) {
return Vertex(glm::vec3(0.0f));
}
glm::vec3 step = glm::normalize(dir);
int flag = if_under_terrain(orig);
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) {
return Vertex(right);
}
}
}

View File

@ -1,18 +1,24 @@
#pragma once
#include "utils.h"
#include "vertex.h"
#include <vector>
#include <string>
class Terrain {
private:
std::vector<float> Vertex;
std::vector<float> _Vertex;
std::vector<unsigned int> Indicess;
unsigned int VAO, VBO, EBO;
std::vector<std::vector<float>> Point;
int if_under_terrain(glm::vec3 point);
int imgW, imgH, imgChannel;
public:
unsigned int tex;
Terrain(std::string path);
void render();
unsigned int loadTexture(std::string path);
Vertex hitPoint(glm::vec3 orig, glm::vec3 dir);
glm::mat4 Model = glm::mat4(1.0f);
};

View File

@ -5,6 +5,7 @@
#include <qopengl.h>
#include <qopenglcontext.h>
#include "texture.h"
#include "logger.h"