TESTSHAPERENDERER: new visual test case for the shape builder

master
Martin Gerhardy 2017-05-15 21:15:29 +02:00
parent 933dcfc546
commit fa3ff17a4a
11 changed files with 252 additions and 26 deletions

View File

@ -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-$@)

View File

@ -0,0 +1,5 @@
w +move_forward
a +move_left
s +move_backward
d +move_right
ctrl+q quit

View File

@ -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;

View File

@ -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];

View File

@ -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;

View File

@ -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)));
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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)