TESTSHAPERENDERER: new visual test case for the shape builder
parent
933dcfc546
commit
fa3ff17a4a
2
Makefile
2
Makefile
|
@ -141,7 +141,7 @@ edit-local-config:
|
|||
doc: cmake
|
||||
$(call COMPILE, $@)
|
||||
|
||||
server client voxedit shapetool worldrenderertool shadertool noisetool noisetool2 databasetool uitool tests tests-core tests-noise testmesh testcamera testdepthbuffer testtexture testvoxelfont testplane testimgui testoctree flatc: cmake
|
||||
server client voxedit shapetool worldrenderertool shadertool noisetool noisetool2 databasetool uitool tests tests-core tests-noise testmesh testcamera testdepthbuffer testtexture testvoxelfont testplane testimgui testoctree testshapebuilder flatc: cmake
|
||||
$(call COMPILE, $@)
|
||||
$(call COMPILE, copy-data-shared)
|
||||
$(call COMPILE, copy-data-$@)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
w +move_forward
|
||||
a +move_left
|
||||
s +move_backward
|
||||
d +move_right
|
||||
ctrl+q quit
|
|
@ -68,7 +68,7 @@ int32_t ShapeRenderer::createMesh(const video::ShapeBuilder& shapeBuilder) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
const video::ShapeBuilder::Indices& indices= shapeBuilder.getIndices();
|
||||
const video::ShapeBuilder::Indices& indices = shapeBuilder.getIndices();
|
||||
_indexIndex[meshIndex] = _vbo[meshIndex].create(indices, video::VertexBufferType::IndexBuffer);
|
||||
if (_indexIndex[meshIndex] == -1) {
|
||||
_vertexIndex[meshIndex] = -1;
|
||||
|
|
|
@ -15,8 +15,9 @@ namespace frontend {
|
|||
* @see video::VertexBuffer
|
||||
*/
|
||||
class ShapeRenderer {
|
||||
private:
|
||||
public:
|
||||
static constexpr int MAX_MESHES = 16;
|
||||
private:
|
||||
video::VertexBuffer _vbo[MAX_MESHES];
|
||||
int32_t _vertexIndex[MAX_MESHES];
|
||||
int32_t _indexIndex[MAX_MESHES];
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
class TestApp: public imgui::IMGUIApp {
|
||||
private:
|
||||
using Super = imgui::IMGUIApp;
|
||||
protected:
|
||||
bool _cameraMotion = false;
|
||||
bool _renderPlane = false;
|
||||
bool _renderAxis = true;
|
||||
protected:
|
||||
video::Camera _camera;
|
||||
frontend::Axis _axis;
|
||||
frontend::Plane _plane;
|
||||
|
|
|
@ -5,54 +5,42 @@ namespace video {
|
|||
void ShapeBuilder::aabbGridXY(const core::AABB<float>& aabb, bool near, float stepWidth) {
|
||||
setPrimitive(Primitive::Lines);
|
||||
const glm::vec3& width = aabb.getWidth();
|
||||
const glm::vec3& halfWidth = width / 2.0f;
|
||||
const glm::vec3& center = aabb.getCenter();
|
||||
const float wx = halfWidth.x + center.x;
|
||||
const float wy = halfWidth.y + center.y;
|
||||
const float wz = near ? 0.0f : center.z + halfWidth.z;
|
||||
const float wz = near ? 0.0f : width.z;
|
||||
for (float x = 0.0f; x <= width.x; x += stepWidth) {
|
||||
addIndex(addVertex(glm::vec3(x, 0.0f, wz)));
|
||||
addIndex(addVertex(glm::vec3(x, wy, wz)));
|
||||
addIndex(addVertex(glm::vec3(x, width.y, wz)));
|
||||
}
|
||||
for (float y = 0.0f; y <= width.y; y += stepWidth) {
|
||||
addIndex(addVertex(glm::vec3(0.0f, y, wz)));
|
||||
addIndex(addVertex(glm::vec3(wx, y, wz)));
|
||||
addIndex(addVertex(glm::vec3(width.x, y, wz)));
|
||||
}
|
||||
}
|
||||
|
||||
void ShapeBuilder::aabbGridYZ(const core::AABB<float>& aabb, bool near, float stepWidth) {
|
||||
setPrimitive(Primitive::Lines);
|
||||
const glm::vec3& width = aabb.getWidth();
|
||||
const glm::vec3& halfWidth = width / 2.0f;
|
||||
const glm::vec3& center = aabb.getCenter();
|
||||
const float wx = near ? 0.0f : center.x + halfWidth.x;
|
||||
const float wy = halfWidth.y + center.y;
|
||||
const float wz = halfWidth.z + center.z;
|
||||
const float wx = near ? 0.0f : width.x;
|
||||
for (float y = 0.0f; y <= width.y; y += stepWidth) {
|
||||
addIndex(addVertex(glm::vec3(wx, y, 0.0f)));
|
||||
addIndex(addVertex(glm::vec3(wx, y, wz)));
|
||||
addIndex(addVertex(glm::vec3(wx, y, width.z)));
|
||||
}
|
||||
for (float z = 0.0f; z <= width.z; z += stepWidth) {
|
||||
addIndex(addVertex(glm::vec3(wx, 0.0f, z)));
|
||||
addIndex(addVertex(glm::vec3(wx, wy, z)));
|
||||
addIndex(addVertex(glm::vec3(wx, width.y, z)));
|
||||
}
|
||||
}
|
||||
|
||||
void ShapeBuilder::aabbGridXZ(const core::AABB<float>& aabb, bool near, float stepWidth) {
|
||||
setPrimitive(Primitive::Lines);
|
||||
const glm::vec3& width = aabb.getWidth();
|
||||
const glm::vec3& halfWidth = width / 2.0f;
|
||||
const glm::vec3& center = aabb.getCenter();
|
||||
const float wx = halfWidth.x + center.x;
|
||||
const float wy = near ? 0.0f : center.y + halfWidth.y;
|
||||
const float wz = halfWidth.z + center.z;
|
||||
const float wy = near ? 0.0f : width.y;
|
||||
for (float x = 0.0f; x <= width.x; x += stepWidth) {
|
||||
addIndex(addVertex(glm::vec3(x, wy, 0.0f)));
|
||||
addIndex(addVertex(glm::vec3(x, wy, wz)));
|
||||
addIndex(addVertex(glm::vec3(x, wy, width.z)));
|
||||
}
|
||||
for (float z = 0.0f; z <= width.z; z += stepWidth) {
|
||||
addIndex(addVertex(glm::vec3(0.0f, wy, z)));
|
||||
addIndex(addVertex(glm::vec3(wx, wy, z)));
|
||||
addIndex(addVertex(glm::vec3(width.x, wy, z)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,5 +5,6 @@ add_subdirectory(testplane)
|
|||
add_subdirectory(testimgui)
|
||||
add_subdirectory(testcamera)
|
||||
add_subdirectory(testoctree)
|
||||
add_subdirectory(testshapebuilder)
|
||||
add_subdirectory(testvoxelfont)
|
||||
#add_subdirectory(testtemplate)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
project(testshapebuilder)
|
||||
set(SRCS
|
||||
TestShapeBuilder.h TestShapeBuilder.cpp
|
||||
)
|
||||
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS} WINDOWED)
|
||||
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES testcore frontend imgui)
|
||||
#generate_shaders(${PROJECT_NAME} color)
|
|
@ -0,0 +1,190 @@
|
|||
#include "TestShapeBuilder.h"
|
||||
#include "io/Filesystem.h"
|
||||
#include "core/Color.h"
|
||||
#include "imgui/IMGUI.h"
|
||||
|
||||
TestShapeBuilder::TestShapeBuilder(const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider) :
|
||||
Super(filesystem, eventBus, timeProvider), _color(core::Color::DarkGreen) {
|
||||
init(ORGANISATION, "testshapebuilder");
|
||||
setCameraMotion(true);
|
||||
setRenderPlane(true);
|
||||
setRenderAxis(true);
|
||||
setCameraSpeed(0.5f);
|
||||
}
|
||||
|
||||
core::AppState TestShapeBuilder::onInit() {
|
||||
core::AppState state = Super::onInit();
|
||||
|
||||
if (!_shapeRenderer.init()) {
|
||||
Log::error("Failed to init the shape renderer");
|
||||
return core::AppState::Cleanup;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)SDL_arraysize(_position); ++i) {
|
||||
_scale[i] = glm::one<glm::vec3>();
|
||||
_position[i] = glm::zero<glm::ivec3>();
|
||||
}
|
||||
|
||||
_shapeBuilder.clear();
|
||||
_shapeBuilder.setPosition(glm::vec3(0.0f));
|
||||
_shapeBuilder.setColor(core::Color::Red);
|
||||
_shapeBuilder.cube(glm::vec3(-0.5f), glm::vec3(0.5f));
|
||||
_meshUnitCube = _shapeRenderer.createMesh(_shapeBuilder);
|
||||
_shapeBuilder.clear();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void TestShapeBuilder::doRender() {
|
||||
for (int i = 0; i < _meshCount; ++i) {
|
||||
const glm::mat4& model = glm::scale(glm::translate(glm::mat4(), glm::vec3(_position[i])), _scale[i]);
|
||||
_shapeRenderer.render(_meshes[i], _camera, model);
|
||||
}
|
||||
}
|
||||
|
||||
void TestShapeBuilder::onRenderUI() {
|
||||
const int width = 95;
|
||||
bool buildMesh = false;
|
||||
_shapeBuilder.clear();
|
||||
_shapeBuilder.setColor(_color);
|
||||
glm::ivec3& pos = _position[_meshCount];
|
||||
glm::vec3& scale = _scale[_meshCount];
|
||||
_shapeBuilder.setPosition(pos);
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(400, 120));
|
||||
ImGui::Begin("Keys and information");
|
||||
Super::onRenderUI();
|
||||
ImGui::End();
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(540, 300));
|
||||
ImGui::Begin("Actions and Settings");
|
||||
|
||||
ImGui::ColorEdit4("color", glm::value_ptr(_color), false);
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputInt("x", &pos.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputInt("y", &pos.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputInt("z", &pos.z);
|
||||
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("sx", &scale.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("sy", &scale.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("sz", &scale.z);
|
||||
|
||||
int numSlices = 5;
|
||||
int numStacks = 4;
|
||||
float radius = 20.0f;
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputInt("slices", &numSlices);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputInt("stacks", &numStacks);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("radius", &radius);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Sphere")) {
|
||||
_shapeBuilder.sphere(numSlices, numStacks, radius);
|
||||
buildMesh = true;
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("mins.x", &_mins.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("mins.y", &_mins.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("mins.z", &_mins.z);
|
||||
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("maxs.x", &_maxs.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("maxs.y", &_maxs.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(width);
|
||||
ImGui::InputFloat("maxs.z", &_maxs.z);
|
||||
|
||||
if (ImGui::Button("Cube")) {
|
||||
_shapeBuilder.cube(_mins, _maxs);
|
||||
buildMesh = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("UnitCube")) {
|
||||
if (_meshCount < SDL_arraysize(_meshes)) {
|
||||
_meshes[_meshCount++] = _meshUnitCube;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("AABB")) {
|
||||
_shapeBuilder.aabb(core::AABB<float>(_mins, _maxs));
|
||||
buildMesh = true;
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Near plane", &_near);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputFloat("Step width", &_stepWidth);
|
||||
if (ImGui::Button("AABB Grid XY")) {
|
||||
_shapeBuilder.aabbGridXY(core::AABB<float>(_mins, _maxs), _near, _stepWidth);
|
||||
buildMesh = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("AABB Grid XZ")) {
|
||||
_shapeBuilder.aabbGridXZ(core::AABB<float>(_mins, _maxs), _near, _stepWidth);
|
||||
buildMesh = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("AABB Grid YZ")) {
|
||||
_shapeBuilder.aabbGridYZ(core::AABB<float>(_mins, _maxs), _near, _stepWidth);
|
||||
buildMesh = true;
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (buildMesh && _meshCount < SDL_arraysize(_meshes)) {
|
||||
_meshes[_meshCount] = _shapeRenderer.createMesh(_shapeBuilder);
|
||||
if (_meshes[_meshCount] != -1) {
|
||||
++_meshCount;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("meshes: %i", _meshCount);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Checkbox("Render Axis", &_renderAxis);
|
||||
ImGui::Checkbox("Render Plane", &_renderPlane);
|
||||
|
||||
if (ImGui::Button("Clear")) {
|
||||
for (int i = 0; i < _meshCount; ++i) {
|
||||
_shapeRenderer.deleteMesh(_meshes[i]);
|
||||
_meshes[i] = -1;
|
||||
}
|
||||
_meshCount = 0;
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
core::AppState TestShapeBuilder::onCleanup() {
|
||||
core::AppState state = Super::onCleanup();
|
||||
_shapeRenderer.shutdown();
|
||||
return state;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const core::EventBusPtr eventBus = std::make_shared<core::EventBus>();
|
||||
const io::FilesystemPtr filesystem = std::make_shared<io::Filesystem>();
|
||||
const core::TimeProviderPtr timeProvider = std::make_shared<core::TimeProvider>();
|
||||
TestShapeBuilder app(filesystem, eventBus, timeProvider);
|
||||
return app.startMainLoop(argc, argv);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "testcore/TestApp.h"
|
||||
#include "frontend/ShapeRenderer.h"
|
||||
#include "video/ShapeBuilder.h"
|
||||
|
||||
class TestShapeBuilder: public TestApp {
|
||||
private:
|
||||
using Super = TestApp;
|
||||
mutable video::ShapeBuilder _shapeBuilder;
|
||||
frontend::ShapeRenderer _shapeRenderer;
|
||||
int _meshCount = 0;
|
||||
glm::ivec3 _position[frontend::ShapeRenderer::MAX_MESHES] {};
|
||||
glm::vec3 _scale[frontend::ShapeRenderer::MAX_MESHES] {};
|
||||
glm::vec4 _color;
|
||||
bool _near = false;
|
||||
float _stepWidth = 1.0f;
|
||||
glm::vec3 _mins {-10.0f, -10.0f, -10.0f};
|
||||
glm::vec3 _maxs { 10.0f, 10.0f, 10.0f};
|
||||
int _meshes[frontend::ShapeRenderer::MAX_MESHES] {-1};
|
||||
int _meshUnitCube = -1;
|
||||
|
||||
void doRender() override;
|
||||
void onRenderUI() override;
|
||||
public:
|
||||
TestShapeBuilder(const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider);
|
||||
|
||||
virtual core::AppState onInit() override;
|
||||
virtual core::AppState onCleanup() override;
|
||||
};
|
|
@ -3,5 +3,5 @@ set(SRCS
|
|||
TestTemplate.h TestTemplate.cpp
|
||||
)
|
||||
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS} WINDOWED)
|
||||
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES testcore)
|
||||
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES testcore imgui)
|
||||
#generate_shaders(${PROJECT_NAME} color)
|
||||
|
|
Loading…
Reference in New Issue