3D Editor treaks

This commit is contained in:
IlyaShurupov 2024-11-05 12:26:48 +03:00 committed by Ilya Shurupov
parent 8d167b960a
commit 573541ba2d
27 changed files with 254 additions and 124 deletions

View file

@ -19,5 +19,6 @@ file(GLOB APP_SOURCES "./applications/*.cpp")
add_executable(3DEditorApp ${APP_SOURCES}) add_executable(3DEditorApp ${APP_SOURCES})
target_link_libraries(3DEditorApp ${PROJECT_NAME}) target_link_libraries(3DEditorApp ${PROJECT_NAME})
file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") file(COPY "../RasterRender/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
file(COPY "rsc/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") file(COPY "../Graphics/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
file(COPY "../3DScene/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")

View file

@ -37,4 +37,4 @@ void Editor::denoise() {
if (device.getError(errorMessage) != oidn::Error::None) { if (device.getError(errorMessage) != oidn::Error::None) {
std::cerr << "Error: " << errorMessage << std::endl; std::cerr << "Error: " << errorMessage << std::endl;
} }
} }

View file

@ -24,7 +24,10 @@ Editor::Editor() {
void Editor::renderViewport() { void Editor::renderViewport() {
switch (mRenderType) { switch (mRenderType) {
case RenderType::RASTER: case RenderType::RASTER:
mRasterRenderer.render(mScene, mScene.mRenderSettings.size); mRasterRenderer.beginRender(mScene, mScene.mRenderSettings.size);
mRasterRenderer.renderDefault(mScene);
if (mActive) mRasterRenderer.renderOutline(mScene.mCamera, *mActive);
mRasterRenderer.endRender();
break; break;
case RenderType::PATH_TRACER: case RenderType::PATH_TRACER:
@ -54,6 +57,7 @@ uint4 Editor::getViewportTexID() {
void Editor::loadDefaults() { void Editor::loadDefaults() {
mScene.load("rsc/scene/script.lua"); mScene.load("rsc/scene/script.lua");
mResetCamera = mScene.mCamera;
} }
void Editor::setViewportSize(const Vec2F& size) { void Editor::setViewportSize(const Vec2F& size) {
@ -73,6 +77,7 @@ Editor::~Editor() {
} }
void Editor::renderPathFrame() { void Editor::renderPathFrame() {
mScene.updateCache();
mPathRenderer.render(mScene, mPathTracerBuffers, mScene.mRenderSettings); mPathRenderer.render(mScene, mPathTracerBuffers, mScene.mRenderSettings);
sendBuffersToGPU(); sendBuffersToGPU();
} }
@ -116,5 +121,20 @@ void Editor::navigationZoom(halnf factor) {
} }
void Editor::navigationReset() { void Editor::navigationReset() {
mScene.mCamera.lookAtPoint({ 0, 0, 0 }, { 1, 5, 1 }, { 0, 0, 1 }); mScene.mCamera = mResetCamera;
} // mScene.mCamera.lookAtPoint({ 0, 0, 0 }, { 1, 5, 1 }, { 0, 0, 1 });
}
void Editor::selectObject(const Vec2F& screenPos) {
mScene.updateCache();
auto dir = (mScene.mCamera.project(screenPos) - mScene.mCamera.getPos()).normalize();
Ray ray = Ray( dir, mScene.mCamera.getPos() );
auto rayCastData = mScene.castRay(ray, 1000);
mActive = rayCastData.obj;
}
Object* Editor::getActiveObject() { return mActive; }
Scene* Editor::getScene() { return &mScene; }

View file

@ -28,6 +28,10 @@ namespace tp {
void navigationZoom(halnf factor); void navigationZoom(halnf factor);
void navigationReset(); void navigationReset();
void selectObject(const Vec2F& screenPos);
Object* getActiveObject();
Scene* getScene();
private: private:
void sendBuffersToGPU(); void sendBuffersToGPU();
@ -36,6 +40,8 @@ namespace tp {
private: private:
Scene mScene; Scene mScene;
Camera mResetCamera;
RenderType mRenderType = RenderType::RASTER; RenderType mRenderType = RenderType::RASTER;
RasterRender mRasterRenderer; RasterRender mRasterRenderer;
@ -43,5 +49,7 @@ namespace tp {
RayTracer::OutputBuffers mPathTracerBuffers; RayTracer::OutputBuffers mPathTracerBuffers;
uint4 mPathRenderTexture = 0; uint4 mPathRenderTexture = 0;
Object* mActive = nullptr;
}; };
} }

View file

@ -66,11 +66,13 @@ namespace tp {
mNavigationOrbit.setText("Orbit"); mNavigationOrbit.setText("Orbit");
mNavigationZoom.setText("Zoom"); mNavigationZoom.setText("Zoom");
mNavigationReset.setText("Reset"); mNavigationReset.setText("Reset");
mNavigationSelect.setText("Select");
mNavigationMenu.addToMenu(&mNavigationPan); mNavigationMenu.addToMenu(&mNavigationPan);
mNavigationMenu.addToMenu(&mNavigationOrbit); mNavigationMenu.addToMenu(&mNavigationOrbit);
mNavigationMenu.addToMenu(&mNavigationZoom); mNavigationMenu.addToMenu(&mNavigationZoom);
mNavigationMenu.addToMenu(&mNavigationReset); mNavigationMenu.addToMenu(&mNavigationReset);
mNavigationMenu.addToMenu(&mNavigationSelect);
mNavigationMenu.setText("Navigation"); mNavigationMenu.setText("Navigation");
} }
@ -85,30 +87,39 @@ namespace tp {
mNavigationOrbit.setAction( [this]() { mNavigationType = ORBIT; }); mNavigationOrbit.setAction( [this]() { mNavigationType = ORBIT; });
mNavigationPan.setAction( [this]() { mNavigationType = PAN; }); mNavigationPan.setAction( [this]() { mNavigationType = PAN; });
mNavigationZoom.setAction( [this](){ mNavigationType = ZOOM; }); mNavigationZoom.setAction( [this](){ mNavigationType = ZOOM; });
mNavigationSelect.setAction( [this](){ mNavigationType = SELECT; });
mNavigationReset.setAction( [this]() { mEditor->navigationReset(); }); mNavigationReset.setAction( [this]() { mEditor->navigationReset(); });
} }
void process(const EventHandler& events) override { void process(const EventHandler& events) override {
DockWidget::process(events); DockWidget::process(events);
auto pointer = events.getPointer(); if (auto obj = mEditor->getActiveObject()) { // dummy rotate active object
auto pointerPrev = events.getPointerPrev(); auto rotator = obj->mTopology.Basis.rotatorDir({1, 1, 1}, 0.1);
obj->mTopology.Basis = rotator * obj->mTopology.Basis;
}
mEditor->getScene()->updateCache();
const auto& activeArea = mViewport.getArea(); const auto& activeArea = mViewport.getArea();
auto pointer = events.getPointer();
auto pointerPrev = events.getPointerPrev();
auto pointerRelative = (((pointer - activeArea.pos) / activeArea.size) - 0.5f) * 2;
if (activeArea.isInside(pointer) && events.isDown(InputID::MOUSE1)) { if (activeArea.isInside(pointer) && events.isDown(InputID::MOUSE1)) {
switch (mNavigationType) { switch (mNavigationType) {
case ORBIT: mEditor->navigationOrbit(events.getPointerDelta() / activeArea.size * 3); break; case ORBIT: mEditor->navigationOrbit(events.getPointerDelta() / activeArea.size * 3); break;
case PAN: case PAN:
{ {
auto pointerRelative = (((pointer - activeArea.pos) / activeArea.size) - 0.5f) * 2;
auto prevPointerRelative = (((pointerPrev - activeArea.pos) / activeArea.size) - 0.5f) * 2; auto prevPointerRelative = (((pointerPrev - activeArea.pos) / activeArea.size) - 0.5f) * 2;
mEditor->navigationPan(prevPointerRelative, pointerRelative); mEditor->navigationPan(prevPointerRelative, pointerRelative);
} }
break; break;
case ZOOM: mEditor->navigationZoom(1 + (events.getPointerDelta().y / activeArea.size.y)); break; case ZOOM: mEditor->navigationZoom(1 + (events.getPointerDelta().y / activeArea.size.y)); break;
case SELECT: mEditor->selectObject(pointerRelative * -1); break;
} }
} }
} }
@ -129,13 +140,14 @@ namespace tp {
ButtonWidget mRenderDeNoise; ButtonWidget mRenderDeNoise;
// Navigation // Navigation
enum NavigationType { ORBIT, PAN, ZOOM } mNavigationType = ORBIT; enum NavigationType { SELECT, ORBIT, PAN, ZOOM } mNavigationType = ORBIT;
FloatingMenu mNavigationMenu; FloatingMenu mNavigationMenu;
ButtonWidget mNavigationPan; ButtonWidget mNavigationPan;
ButtonWidget mNavigationOrbit; ButtonWidget mNavigationOrbit;
ButtonWidget mNavigationZoom; ButtonWidget mNavigationZoom;
ButtonWidget mNavigationReset; ButtonWidget mNavigationReset;
ButtonWidget mNavigationSelect;
RGBA mBaseColor; RGBA mBaseColor;
}; };

View file

@ -7,6 +7,61 @@ extern "C" {
} }
#include <filesystem> #include <filesystem>
#include <utility>
tp::Vec3F tp::Scene::getVec3(lua_State* state, const char* name) {
int stackSize = lua_gettop(state);
// Access the "pos" field and validate it
lua_getfield(state, -1, name);
if (!lua_istable(state, -1) || lua_rawlen(state, -1) != 3) {
throw IOError(std::string("Invalid vec3 named ") + name);
}
// Read the values from the table
float pos[3];
for (int i = 0; i < 3; i++) {
lua_rawgeti(state, -1, i + 1);
if (lua_isnumber(state, -1)) {
pos[i] = lua_tonumber(state, -1);
} else {
throw IOError("vec3 values must be numbers");
}
lua_pop(state, 1); // pop number
}
lua_pop(state, 1); // pop vec3
ASSERT(stackSize == lua_gettop(state))
return { pos[0], pos[1], pos[2] };
}
tp::Vec2F tp::Scene::getVec2(lua_State* state, const char* name) {
int stackSize = lua_gettop(state);
// Access the "pos" field and validate it
lua_getfield(state, -1, name);
if (!lua_istable(state, -1) || lua_rawlen(state, -1) != 2) {
throw IOError(std::string("Invalid vec2 named ") + name);
}
// Read the values from the table
float pos[2];
for (int i = 0; i < 2; i++) {
lua_rawgeti(state, -1, i + 1);
if (lua_isnumber(state, -1)) {
pos[i] = lua_tonumber(state, -1);
} else {
throw IOError("vec3 values must be numbers");
}
lua_pop(state, 1); // pop number
}
lua_pop(state, 1); // pop vec3
ASSERT(stackSize == lua_gettop(state))
return { pos[0], pos[1] };
}
// Function to read a Lua table representing RenderSettings // Function to read a Lua table representing RenderSettings
int readRenderSettings(lua_State* L, tp::RenderSettings& settings) { int readRenderSettings(lua_State* L, tp::RenderSettings& settings) {
@ -53,23 +108,8 @@ int readRenderSettings(lua_State* L, tp::RenderSettings& settings) {
} }
// Function to read a Lua table representing a light // Function to read a Lua table representing a light
int readLight(lua_State* L, tp::PointLight* light) { int tp::Scene::readLight(lua_State* L, tp::PointLight* light) {
lua_getfield(L, -1, "pos"); // Get the "pos" field from the light table light->pos = getVec3(L, "pos");
if (!lua_istable(L, -1)) {
printf("Light is missing the 'pos' table.\n");
return 0; // Error
}
for (int i = 0; i < 3; i++) {
lua_rawgeti(L, -1, i + 1); // Index is 1-based in Lua
if (!lua_isnumber(L, -1)) {
printf("Light 'pos' field is not a number at index %d.\n", i);
lua_pop(L, 2); // Pop both the number and the 'pos' table
return 0; // Error
}
light->pos[i] = lua_tonumber(L, -1);
lua_pop(L, 1); // Pop the number
}
lua_pop(L, 1); // Pop the 'pos' table
lua_getfield(L, -1, "intensity"); // Get the "intensity" field from the light table lua_getfield(L, -1, "intensity"); // Get the "intensity" field from the light table
if (!lua_isnumber(L, -1)) { if (!lua_isnumber(L, -1)) {
@ -121,66 +161,29 @@ bool tp::Scene::loadLuaFormat(const std::string& scenePath) {
} }
// --- camera // --- camera
{
// Access Camera table lua_getglobal(L, "Camera");
lua_getglobal(L, "Camera"); if (!lua_istable(L, -1)) {
if (!lua_istable(L, -1)) { printf("Camera is not a table.\n");
printf("Camera is not a table.\n");
lua_close(L);
return false;
}
// Verify you are inside the "Camera" table
int cameraTableIndex = lua_gettop(L); // Get the index of the "Camera" table
// Access the "pos" field and validate it
lua_getfield(L, cameraTableIndex, "pos");
if (!lua_istable(L, -1) || lua_rawlen(L, -1) != 3) {
printf("Invalid 'pos' field in Camera table.\n");
lua_close(L);
return false;
}
// Read the values from the table
float pos[3];
for (int i = 0; i < 3; i++) {
lua_rawgeti(L, -1, i + 1);
if (lua_isnumber(L, -1)) {
pos[i] = lua_tonumber(L, -1);
} else {
printf("Invalid 'pos' field value at index %d.\n", i + 1);
lua_close(L); lua_close(L);
return false; return false;
} }
Vec3F camPos = getVec3(L, "pos");
Vec3F camTarget = getVec3(L, "target");
Vec3F camUp = getVec3(L, "up");
Vec2F camSize = getVec2(L, "size");
mRenderSettings.size = camSize;
mCamera.lookAtPoint(camTarget, camPos, camUp);
mCamera.setFOV(3.14 / 4);
mCamera.setFar(100);
mCamera.setRatio((tp::halnf) camSize.y / (tp::halnf) camSize.x);
lua_pop(L, 1); lua_pop(L, 1);
} }
// Access the "size_x" field and validate it
lua_getfield(L, cameraTableIndex, "size_x");
if (!lua_isnumber(L, -1)) {
printf("Invalid or missing 'size_x' field in Camera table.\n");
lua_close(L);
return false;
}
int size_x = lua_tointeger(L, -1);
lua_pop(L, 1); // Pop the 'size_x' value from the stack
// Access the "size_y" field and validate it
lua_getfield(L, cameraTableIndex, "size_y");
if (!lua_isnumber(L, -1)) {
printf("Invalid or missing 'size_y' field in Camera table.\n");
lua_close(L);
return false;
}
int size_y = lua_tointeger(L, -1);
mRenderSettings.size = { (tp::halnf) size_x, (tp::halnf) size_y };
mCamera.lookAtPoint({ 0, 0, 0 }, { pos[0], pos[1], pos[2] }, { 0, 0, 1 });
mCamera.setFOV(3.14 / 4);
mCamera.setFar(100);
mCamera.setRatio((tp::halnf) size_y / (tp::halnf) size_x);
// ---------- LIGHTS // ---------- LIGHTS
{ {
lua_getglobal(L, "Lights"); lua_getglobal(L, "Lights");

View file

@ -48,4 +48,39 @@ bool tp::Scene::loadOBJFormat(const std::string& objetsPath) {
} }
return mObjects.size(); return mObjects.size();
}
const tp::RayCastData& tp::Scene::castRay(const Ray& ray, alnf farVal) {
auto& out = mRayCastData;
out.hit = false;
out.obj = nullptr;
farVal *= farVal;
for (auto obj : mObjects) {
for (auto trig : obj->mCache.TrigCaches) {
if (trig->castRay(ray)) {
auto dist = (TrigCache::getHitPos() - ray.pos).length2();
if (farVal > dist && dist > EPSILON) {
out.trig = &trig.data();
out.hitPos = TrigCache::getHitPos();
out.obj = &obj.data();
out.hit = true;
farVal = dist;
}
}
}
}
return mRayCastData;
}
void tp::Scene::updateCache() {
for (auto obj : mObjects) {
obj->mCache.updateCache();
}
} }

View file

@ -2,5 +2,13 @@
#include "Scene.hpp" #include "Scene.hpp"
bool tp::Scene::load(const std::string& scenePath) { bool tp::Scene::load(const std::string& scenePath) {
return loadLuaFormat(scenePath); try {
auto res = loadLuaFormat(scenePath);
if (!res) throw IOError("Failed loading lua script");
} catch (const IOError& err) {
printf("Failed loading scene : %s\n", err.description.c_str());
return false;
}
return true;
} }

View file

@ -6,6 +6,8 @@
#include <string> #include <string>
struct lua_State;
namespace tp { namespace tp {
struct RenderSettings { struct RenderSettings {
uhalni depth = 2; uhalni depth = 2;
@ -42,7 +44,22 @@ namespace tp {
halnf intensity = 1.f; halnf intensity = 1.f;
}; };
struct RayCastData {
Object* obj = nullptr;
TrigCache* trig = nullptr;
Vec3F hitPos = { 0, 0, 0 };
bool hit = false;
bool inv = false;
};
class Scene { class Scene {
struct IOError : public std::exception {
explicit IOError(std::string in) :
description(std::move(in)) {}
std::string description;
};
public: public:
Scene() = default; Scene() = default;
@ -51,11 +68,23 @@ namespace tp {
bool loadLuaFormat(const std::string& scenePath); bool loadLuaFormat(const std::string& scenePath);
bool loadOBJFormat(const std::string& objectsPath); bool loadOBJFormat(const std::string& objectsPath);
const RayCastData& castRay(const Ray& ray, alnf farVal);
void updateCache();
private:
Vec3F getVec3(lua_State* state, const char* name);
Vec2F getVec2(lua_State* state, const char* name);
int readLight(lua_State* L, tp::PointLight* light);
public: public:
Buffer<Object> mObjects; Buffer<Object> mObjects;
Buffer<PointLight> mLights; Buffer<PointLight> mLights;
Camera mCamera; Camera mCamera;
RenderSettings mRenderSettings; RenderSettings mRenderSettings;
RayCastData mRayCastData;
}; };
} }

View file

@ -2,9 +2,10 @@
Meshes = "meshes.obj" Meshes = "meshes.obj"
Camera = { Camera = {
pos = { 0.5, 4.5, 0.2 }, pos = { 0, 5, 0 },
size_x = 600, target = { 0, 0, 0 },
size_y = 800, up = { 0, 0, 1 },
size = { 600, 800 },
} }
Lights = { Lights = {

View file

@ -19,5 +19,5 @@ target_link_libraries(Example${PROJECT_NAME} ${PROJECT_NAME} ${BINDINGS_LIBS})
target_include_directories(Example${PROJECT_NAME} PRIVATE ${BINDINGS_INCLUDE}) target_include_directories(Example${PROJECT_NAME} PRIVATE ${BINDINGS_INCLUDE})
file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") file(COPY "../Graphics/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")

Binary file not shown.

View file

@ -27,7 +27,7 @@ Canvas::Canvas(Window* window) {
mContext->vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); mContext->vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
if (nvgCreateFont(mContext->vg, "default", "Font.ttf") == -1) { if (nvgCreateFont(mContext->vg, "default", "rsc/Font.ttf") == -1) {
ASSERT(!"Cant create NVG font") ASSERT(!"Cant create NVG font")
} }
} }

View file

@ -36,7 +36,7 @@ DebugGUI::DebugGUI(Window* window) {
ImGui_ImplOpenGL3_Init("#version 330"); ImGui_ImplOpenGL3_Init("#version 330");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("Font.ttf", 20.f); io.Fonts->AddFontFromFileTTF("rsc/Font.ttf", 20.f);
io.ConfigInputTrickleEventQueue = false; io.ConfigInputTrickleEventQueue = false;

View file

@ -88,7 +88,7 @@ void Camera::lookAtPoint(const Vec3F& aTarget, const Vec3F& aPos, Vec3F aUp) {
} }
mPos = aPos; mPos = aPos;
mTarget = aTarget; mTarget = aTarget;
Vec3F f = (mPos - mTarget).normalize(); Vec3F f = (mTarget - mPos).normalize();
mUp = f * (aUp.normalize() * f); mUp = f * (aUp.normalize() * f);
} }

View file

@ -714,7 +714,7 @@ namespace tp {
out[0] = { in[0][0], in[0][1], in[0][2], 0 }; out[0] = { in[0][0], in[0][1], in[0][2], 0 };
out[1] = { in[1][0], in[1][1], in[1][2], 0 }; out[1] = { in[1][0], in[1][1], in[1][2], 0 };
out[2] = { in[2][0], in[2][1], in[2][2], 0 }; out[2] = { in[2][0], in[2][1], in[2][2], 0 };
out[3] = Type(1); out[3] = { Type(0), Type(0), Type(0), Type(1) };
return out; return out;
} }
} }

View file

@ -3,20 +3,24 @@
using namespace tp; using namespace tp;
RasterRender::RasterRender() : RasterRender::RasterRender() {
mRenderBuffer({ 100, 100 })
{
mDefaultShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/default.frag", true); mDefaultShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/default.frag", true);
mSolidShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/solid.frag", true); mSolidShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/solid.frag", true);
} }
RasterRender::~RasterRender() {} RasterRender::~RasterRender() {}
void RasterRender::resize(const Vec2<tp::ualni>& size) {
auto sizeF = Vec2F(size.x, size.y);
mRenderBuffer.resize(sizeF);
mTempBuffer.resize(sizeF);
}
uint4 RasterRender::getRenderBufferID() { return mRenderBuffer.texId(); } uint4 RasterRender::getRenderBufferID() { return mRenderBuffer.texId(); }
Vec2F RasterRender::getBufferSize() { return mRenderBuffer.getSize(); } Vec2F RasterRender::getBufferSize() { return mRenderBuffer.getSize(); }
void RasterRender::bindCameraShaderAttributes(Mat4F cameraMat) { void RasterRender::bindCameraShaderAttributes(const Mat4F& cameraMat) {
static auto camera = (GLint) mDefaultShader.getu("Camera"); static auto camera = (GLint) mDefaultShader.getu("Camera");
glUniformMatrix4fv(camera, 1, true, &cameraMat[0][0]); glUniformMatrix4fv(camera, 1, true, &cameraMat[0][0]);
} }
@ -28,11 +32,18 @@ void RasterRender::bindObjectShaderAttributes(const Object& object) {
Mat4F basisMat = toMat4(object.mTopology.Basis); Mat4F basisMat = toMat4(object.mTopology.Basis);
Vec4F originPoint = toVec4(object.mTopology.Origin); Vec4F originPoint = toVec4(object.mTopology.Origin);
basisMat = basisMat.transpose();
glUniform4fv(origin, 1, &originPoint[0]); glUniform4fv(origin, 1, &originPoint[0]);
glUniformMatrix4fv(basis, 1, false, &basisMat[0][0]); glUniformMatrix4fv(basis, 1, false, &basisMat[0][0]);
} }
void RasterRender::renderDefault(const Scene& geometry) { void RasterRender::renderDefault(const Scene& geometry) {
mRenderBuffer.mClearCol = { 0.0f, 0.0f, 0.0f, 0.f };
mRenderBuffer.beginDraw();
mRenderBuffer.clear();
mDefaultShader.bind(); mDefaultShader.bind();
Mat4F cameraMat = geometry.mCamera.calculateTransformationMatrix(); Mat4F cameraMat = geometry.mCamera.calculateTransformationMatrix();
@ -55,10 +66,19 @@ void RasterRender::renderDefault(const Scene& geometry) {
} }
mDefaultShader.unbind(); mDefaultShader.unbind();
glDisable(GL_DEPTH_TEST);
// glPolygonMode(GL_FRONT, GL_FILL);
// glPolygonMode(GL_BACK, GL_FILL);
mRenderBuffer.endDraw();
} }
void RasterRender::renderOutline(const Camera& camera, const Object& object) { void RasterRender::renderOutline(const Camera& camera, const Object& object) {
glEnable(GL_STENCIL_TEST); mRenderBuffer.beginDraw();
// glEnable(GL_STENCIL_TEST);
mSolidShader.bind(); mSolidShader.bind();
@ -69,30 +89,23 @@ void RasterRender::renderOutline(const Camera& camera, const Object& object) {
mSolidShader.unbind(); mSolidShader.unbind();
glDisable(GL_STENCIL_TEST); // glDisable(GL_STENCIL_TEST);
mRenderBuffer.endDraw();
} }
void RasterRender::render(const Scene& geometry, const Vec2<ualni>& size) { void RasterRender::beginRender(const Scene& geometry, const Vec2<tp::ualni>& size) {
resize(size);
for (auto object : geometry.mObjects) { for (auto object : geometry.mObjects) {
if (!object->mGUPBuffers) { if (!object->mGUPBuffers) {
object->mGUPBuffers = new ObjectBuffers(&object.data()); object->mGUPBuffers = new ObjectBuffers(&object.data());
} }
} }
}
mRenderBuffer.mClearCol = { 0.0f, 0.0f, 0.0f, 0.f }; void RasterRender::endRender() {
// pass
mRenderBuffer.beginDraw();
mRenderBuffer.clear();
renderDefault(geometry);
// if (geometry.mObjects.size()) renderOutline(geometry.mCamera, geometry.mObjects.first());
// glPolygonMode(GL_FRONT, GL_FILL);
// glPolygonMode(GL_BACK, GL_FILL);
mRenderBuffer.endDraw();
} }
RenderBuffer* RasterRender::getRenderBuffer() { return &mRenderBuffer; } RenderBuffer* RasterRender::getRenderBuffer() { return &mRenderBuffer; }

View file

@ -7,7 +7,7 @@
namespace tp { namespace tp {
class RenderBuffer { class RenderBuffer {
public: public:
explicit RenderBuffer(const Vec2F& size); explicit RenderBuffer(const Vec2F& size = { 10, 10 });
RenderBuffer(const Vec2F& size, tp::uint1 samples); RenderBuffer(const Vec2F& size, tp::uint1 samples);
~RenderBuffer(); ~RenderBuffer();

View file

@ -12,20 +12,25 @@ namespace tp {
RasterRender(); RasterRender();
~RasterRender(); ~RasterRender();
void render(const Scene& geometry, const Vec2<ualni>& size); void beginRender(const Scene& geometry, const Vec2<ualni>& size);
void endRender();
void renderDefault(const Scene& geometry);
void renderOutline(const Camera& camera, const Object& object);
void resize(const Vec2<ualni>& size);
uint4 getRenderBufferID(); uint4 getRenderBufferID();
RenderBuffer* getRenderBuffer(); RenderBuffer* getRenderBuffer();
Vec2F getBufferSize(); Vec2F getBufferSize();
private: private:
void renderDefault(const Scene& geometry);
void renderOutline(const Camera& camera, const Object& object);
void bindObjectShaderAttributes(const Object& object); void bindObjectShaderAttributes(const Object& object);
void bindCameraShaderAttributes(Mat4F cameraMat); void bindCameraShaderAttributes(const Mat4F& cameraMat);
private: private:
RenderBuffer mRenderBuffer; RenderBuffer mRenderBuffer;
RenderBuffer mTempBuffer;
RenderShader mDefaultShader; RenderShader mDefaultShader;
RenderShader mSolidShader; RenderShader mSolidShader;

View file

@ -7,6 +7,7 @@ uniform mat4 Basis;
uniform mat4 Camera; uniform mat4 Camera;
void main() { void main() {
// vec4 transformed = vec4(Point.xyz, 1.0);
vec4 transformed = (Basis * vec4(Point.xyz, 1.0)) + Origin; vec4 transformed = (Basis * vec4(Point.xyz, 1.0)) + Origin;
gl_Position = Camera * transformed; gl_Position = Camera * transformed;
} }

View file

@ -43,6 +43,8 @@ normal = n1 * barycentric.x + n2 * barycentric.y + n3 * barycentric.z;
using namespace tp; using namespace tp;
// TODO : de-duplicate in Scene?
void RayTracer::castRay(const Ray& ray, RayCastData& out, alnf farVal) { void RayTracer::castRay(const Ray& ray, RayCastData& out, alnf farVal) {
out.hit = false; out.hit = false;
out.obj = nullptr; out.obj = nullptr;

View file

@ -30,14 +30,6 @@ namespace tp {
void render(const Scene& scene, OutputBuffers& out, const RenderSettings& settings); void render(const Scene& scene, OutputBuffers& out, const RenderSettings& settings);
private: private:
struct RayCastData {
const Object* obj = nullptr;
TrigCache* trig = nullptr;
Vec3F hitPos = { 0, 0, 0 };
bool hit = false;
bool inv = false;
};
struct LightData { struct LightData {
halnf intensity = 0; halnf intensity = 0;
}; };