Hi, here is class I used to draw a mesh
// =============================================================
// Helper Functions (outside the class)
// =============================================================
// Example height function
float f(float x, float y, float tx = 0.0f)
{
float dx = x - 0.5f;
float dy = y - 0.5f;
float r = std::sqrt(dx * dx + dy * dy);
return std::sin((r + tx) * 8.0f * 3.1415926f) * 0.5f;
}
// Generate grid like your old code
void generate_grid(int N, std::vector<threepp::Vector3>& vertices, std::vector<unsigned int>& indices)
{
vertices.clear();
indices.clear();
for (int j = 0; j <= N; ++j)
{
for (int i = 0; i <= N; ++i)
{
float x = (float)i / (float)N;
float y = (float)j / (float)N;
float z = f(x, y);
vertices.push_back({x, y, z});
}
}
for (int j = 0; j < N; ++j)
{
for (int i = 0; i < N; ++i)
{
int row1 = j * (N + 1);
int row2 = (j + 1) * (N + 1);
// triangle 1
indices.push_back(row1 + i);
indices.push_back(row1 + i + 1);
indices.push_back(row2 + i + 1);
// triangle 2
indices.push_back(row1 + i);
indices.push_back(row2 + i + 1);
indices.push_back(row2 + i);
}
}
}
///////////////////////////////////////////////////////////////////////////////
#define TEST 1
#if not TEST
class SurfaceRenderer
{
public:
SurfaceRenderer()
{
m_Geometry = std::make_shared<threepp::BufferGeometry>();
m_Material = threepp::ShaderMaterial::create();
// Use the simplified shaders below
m_Material->vertexShader = m_VertexShader;
m_Material->fragmentShader = m_FragmentShader;
// No need for ZL/ZH uniforms in the simplified version
m_Material->uniforms = {};
m_Mesh = std::make_shared<threepp::Mesh>(m_Geometry, m_Material);
m_Mesh->frustumCulled = false;
}
void SetData(const std::vector<threepp::Vector3>& vertices,
const std::vector<unsigned int>& indices)
{
std::vector<float> verticesData;
verticesData.reserve(vertices.size() * 3);
for (const auto& v : vertices)
{
verticesData.push_back(v.x);
verticesData.push_back(v.y);
verticesData.push_back(v.z);
}
auto positionsUnique = threepp::TypedBufferAttribute<float>::create(verticesData, 3);
m_Geometry->setAttribute("position", std::move(positionsUnique));
m_Geometry->setIndex(indices);
m_Geometry->computeVertexNormals();
m_Geometry->computeBoundingSphere();
m_Geometry->computeBoundingBox();
}
void SetZRange(float /*zl*/, float /*zh*/) {}
std::shared_ptr<threepp::Mesh> GetMesh()
{
return m_Mesh;
}
private:
std::shared_ptr<threepp::BufferGeometry> m_Geometry;
std::shared_ptr<threepp::ShaderMaterial> m_Material;
std::shared_ptr<threepp::Mesh> m_Mesh;
const std::string m_VertexShader = R"(#version 330 core
layout(location = 0) in vec3 vertPos;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
out vec3 pos;
void main()
{
gl_Position = projectionMatrix * modelViewMatrix * vec4(vertPos, 1.0);
pos = vertPos;
})";
const std::string m_FragmentShader = R"(#version 330 core
uniform float ZL;
uniform float ZH;
in vec3 pos;
out vec3 color;
vec3 jet(float t)
{
return clamp(vec3(1.5) - abs(4.0 * vec3(t) + vec3(-3, -2, -1)),
vec3(0), vec3(1));
}
void main()
{
float param = (pos.z - ZL) / (ZH - ZL);
color = jet(param);
})";
};
#else
// =============================================================
// TEST MODE: MeshBasicMaterial-based Renderer
// =============================================================
class SurfaceRenderer
{
public:
SurfaceRenderer()
{
m_Geometry = std::make_shared<threepp::BufferGeometry>();
m_Material = threepp::MeshBasicMaterial::create();
m_Material->color = threepp::Color::red;
m_Mesh = std::make_shared<threepp::Mesh>(m_Geometry, m_Material);
}
void SetData(const std::vector<threepp::Vector3>& vertices,
const std::vector<unsigned int>& indices)
{
std::vector<float> verticesData;
verticesData.reserve(vertices.size() * 3);
for (auto& v : vertices)
{
verticesData.push_back(v.x);
verticesData.push_back(v.y);
verticesData.push_back(v.z);
}
auto positionsUnique = threepp::TypedBufferAttribute<float>::create(verticesData, 3);
m_Geometry->setAttribute("position", std::move(positionsUnique));
m_Geometry->setIndex(indices);
m_Geometry->computeVertexNormals();
m_Geometry->computeBoundingSphere();
m_Geometry->computeBoundingBox();
}
void SetZRange(float /*zl*/, float /*zh*/)
{
// ignored for testing
}
std::shared_ptr<threepp::Mesh> GetMesh()
{
return m_Mesh;
}
private:
std::shared_ptr<threepp::BufferGeometry> m_Geometry;
std::shared_ptr<threepp::MeshBasicMaterial> m_Material;
std::shared_ptr<threepp::Mesh> m_Mesh;
const std::string m_VertexShader = "";
const std::string m_FragmentShader = "";
};
#endif
Here is the client code to use this class:
// Create and keep the instance alive
surface = std::make_shared<SurfaceRenderer>();
std::vector<threepp::Vector3> vertices1;
std::vector<unsigned int> indices1;
generate_grid(50, vertices1, indices1);
surface->SetData(vertices1, indices1);
float zl = +std::numeric_limits<float>::max();
float zh = -std::numeric_limits<float>::max();
for (auto &v: vertices1)
{
if(v.z < zl) zl = v.z;
if(v.z > zh) zh = v.z;
}
surface->SetZRange(zl, zh);
scene->add(surface->GetMesh());
You can see that if the TEST is defined as 1, then the simplified red mesh is shown, see the image shot below:
But if the TEST is defined as 0, nothing is shown. I mean I can't use the ShaderMaterial class for customized shaders.
The expected output is like below, it is a kind of height map(jet color map), which means the higher parts of the mesh will shown in red, and the lower parts of the mesh will shown in blue, see image shot below:
The above image is drawn by pure OpenGL code/render, I'm trying to migrate the code from the pure OpenGL to threepp framework, but found a bit hard. Can you help? Thanks.
BTW, It looks like the mouse rotation method has slightly different along different x,y,z axis. I mean in some axis' rotation, it is hard to rotate. Is the mouse rotation follow the way like: Object Mouse Trackball - OpenGL Wiki?
In my own pure OpenGL code, I don't see the mouse rotation is different if I rotate on different direction. But under threepp, it looks like in some axis, the rotation angle has a positive and negative limit? Thanks.
Hi, here is class I used to draw a mesh
Here is the client code to use this class:
You can see that if the
TESTis defined as1, then the simplified red mesh is shown, see the image shot below:But if the
TESTis defined as0, nothing is shown. I mean I can't use theShaderMaterialclass for customized shaders.The expected output is like below, it is a kind of height map(jet color map), which means the higher parts of the mesh will shown in red, and the lower parts of the mesh will shown in blue, see image shot below:
The above image is drawn by pure OpenGL code/render, I'm trying to migrate the code from the pure OpenGL to threepp framework, but found a bit hard. Can you help? Thanks.
BTW, It looks like the mouse rotation method has slightly different along different x,y,z axis. I mean in some axis' rotation, it is hard to rotate. Is the mouse rotation follow the way like: Object Mouse Trackball - OpenGL Wiki?
In my own pure OpenGL code, I don't see the mouse rotation is different if I rotate on different direction. But under threepp, it looks like in some axis, the rotation angle has a positive and negative limit? Thanks.