mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-08 13:44:56 +00:00
Lots of bug fixes (Windows still needs some fixes)
This commit is contained in:
@@ -59,20 +59,29 @@ static void UpdatePercent(float percent)
|
||||
VISIRenderer* m_renderer;
|
||||
NSWindow* m_window;
|
||||
NSOpenGLView* m_glView;
|
||||
int m_instanceIdx;
|
||||
}
|
||||
- (id)initWithRenderer:(VISIRenderer*)renderer;
|
||||
- (id)initWithRenderer:(VISIRenderer*)renderer instIdx:(int)instIdx;
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
- (id)initWithRenderer:(VISIRenderer*)renderer
|
||||
- (id)initWithRenderer:(VISIRenderer*)renderer instIdx:(int)instIdx
|
||||
{
|
||||
self = [super init];
|
||||
m_renderer = renderer;
|
||||
m_instanceIdx = instIdx;
|
||||
return self;
|
||||
}
|
||||
- (void)applicationDidFinishLaunching:(NSNotification*)notification
|
||||
{
|
||||
NSRect cRect = NSMakeRect(100, 100, 768, 512);
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (m_instanceIdx != -1)
|
||||
{
|
||||
x = (m_instanceIdx & 1) != 0;
|
||||
y = (m_instanceIdx & 2) != 0;
|
||||
}
|
||||
NSRect cRect = NSMakeRect(x * 768, y * 534, 768, 512);
|
||||
m_window = [[NSWindow alloc] initWithContentRect:cRect
|
||||
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable
|
||||
backing:NSBackingStoreBuffered
|
||||
@@ -109,12 +118,15 @@ int main(int argc, const char** argv)
|
||||
logvisor::RegisterConsoleLogger();
|
||||
atSetExceptionHandler(AthenaExc);
|
||||
VISIRenderer renderer(argc, argv);
|
||||
int instIdx = -1;
|
||||
if (argc > 3)
|
||||
instIdx = atoi(argv[3]);
|
||||
@autoreleasepool
|
||||
{
|
||||
[[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
|
||||
/* Delegate (OS X callbacks) */
|
||||
AppDelegate* appDelegate = [[AppDelegate alloc] initWithRenderer:&renderer];
|
||||
AppDelegate* appDelegate = [[AppDelegate alloc] initWithRenderer:&renderer instIdx:instIdx];
|
||||
[[NSApplication sharedApplication] setDelegate:appDelegate];
|
||||
[[NSApplication sharedApplication] run];
|
||||
}
|
||||
|
||||
@@ -56,6 +56,10 @@ int wmain(int argc, const hecl::SystemChar** argv)
|
||||
VISIRenderer renderer(argc, argv);
|
||||
s_Renderer = &renderer;
|
||||
|
||||
int instIdx = -1;
|
||||
if (argc > 3)
|
||||
instIdx = _wtoi(argv[3]);
|
||||
|
||||
WNDCLASS wndClass =
|
||||
{
|
||||
CS_NOCLOSE,
|
||||
@@ -74,8 +78,16 @@ int wmain(int argc, const hecl::SystemChar** argv)
|
||||
RECT clientRect = {0, 0, 768, 512};
|
||||
AdjustWindowRect(&clientRect, dwStyle, FALSE);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (instIdx != -1)
|
||||
{
|
||||
x = (instIdx & 1) != 0;
|
||||
y = (instIdx & 2) != 0;
|
||||
}
|
||||
|
||||
HWND window = CreateWindowW(L"VISIGenWindow", L"VISIGen", dwStyle,
|
||||
100, 100,
|
||||
x, y,
|
||||
clientRect.right - clientRect.left,
|
||||
clientRect.bottom - clientRect.top,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
@@ -194,7 +194,19 @@ int main(int argc, const char** argv)
|
||||
swa.border_pixmap = 0;
|
||||
swa.event_mask = 0;
|
||||
|
||||
windowId = XCreateWindow(xDisp, screen->root, 0, 0, 768, 512, 10,
|
||||
int instIdx = -1;
|
||||
if (argc > 3)
|
||||
instIdx = atoi(argv[3]);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (instIdx != -1)
|
||||
{
|
||||
x = (instIdx & 1) != 0;
|
||||
y = (instIdx & 2) != 0;
|
||||
}
|
||||
|
||||
windowId = XCreateWindow(xDisp, screen->root, x, y, 768, 512, 10,
|
||||
CopyFromParent, CopyFromParent, selectedVisual,
|
||||
CWBorderPixel | CWEventMask | CWColormap, &swa);
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#include "VISIBuilder.hpp"
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#define VISI_MAX_LEVEL 10
|
||||
#define VISI_MIN_LENGTH 8.0
|
||||
|
||||
@@ -31,8 +36,8 @@ const VISIBuilder::Leaf& VISIBuilder::PVSRenderCache::GetLeaf(const zeus::CVecto
|
||||
{
|
||||
const VISIRenderer::RGBA8& pixel = RGBABuf[i];
|
||||
uint32_t id = (pixel.b << 16) | (pixel.g << 8) | pixel.r;
|
||||
if (id != 0xffffff)
|
||||
leafOut->setBit(id);
|
||||
if (id != 0)
|
||||
leafOut->setBit(id - 1);
|
||||
}
|
||||
|
||||
auto setBitLambda = [&](int idx) { leafOut->setBit(idx); };
|
||||
@@ -51,16 +56,16 @@ const VISIBuilder::Leaf& VISIBuilder::PVSRenderCache::GetLeaf(const zeus::CVecto
|
||||
void VISIBuilder::Progress::report(int divisions)
|
||||
{
|
||||
m_prog += 1.f / divisions;
|
||||
printf(" %g%% \r", m_prog * 100.f);
|
||||
fflush(stdout);
|
||||
//printf(" %g%% \r", m_prog * 100.f);
|
||||
//fflush(stdout);
|
||||
if (m_updatePercent)
|
||||
m_updatePercent(m_prog);
|
||||
}
|
||||
|
||||
void VISIBuilder::Node::buildChildren(int level, int divisions, const zeus::CAABox& curAabb,
|
||||
PVSRenderCache& rc, Progress& prog, const bool& terminate)
|
||||
PVSRenderCache& rc, Progress& prog, const std::function<bool()>& terminate)
|
||||
{
|
||||
if (terminate)
|
||||
if (terminate())
|
||||
return;
|
||||
|
||||
// Recurse in while building node structure
|
||||
@@ -316,9 +321,10 @@ std::vector<uint8_t> VISIBuilder::build(const zeus::CAABox& fullAabb,
|
||||
renderCache.m_lightMetaBit = featureCount;
|
||||
|
||||
Progress prog(updatePercent);
|
||||
bool& terminate = renderCache.m_renderer.m_terminate;
|
||||
pid_t parentPid = getppid();
|
||||
auto terminate = [this, parentPid]() { return renderCache.m_renderer.m_terminate || kill(parentPid, 0); };
|
||||
rootNode.buildChildren(0, 1, fullAabb, renderCache, prog, terminate);
|
||||
if (terminate)
|
||||
if (terminate())
|
||||
return {};
|
||||
|
||||
// Lights cache their CPVSVisSet result enum as 2 bits
|
||||
@@ -365,7 +371,6 @@ std::vector<uint8_t> VISIBuilder::build(const zeus::CAABox& fullAabb,
|
||||
|
||||
w.seekAlign32();
|
||||
|
||||
printf("\n");
|
||||
Log.report(logvisor::Info, "Finished!");
|
||||
return dataOut;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ struct VISIBuilder
|
||||
uint8_t flags = 0;
|
||||
|
||||
void buildChildren(int level, int divisions, const zeus::CAABox& curAabb,
|
||||
PVSRenderCache& rc, Progress& prog, const bool& terminate);
|
||||
PVSRenderCache& rc, Progress& prog, const std::function<bool()>& terminate);
|
||||
void calculateSizesAndOffs(size_t& cur, size_t leafSz);
|
||||
void writeNodes(athena::io::MemoryWriter& w, size_t leafBytes) const;
|
||||
|
||||
|
||||
@@ -110,8 +110,6 @@ bool VISIRenderer::SetupShaders()
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_aabbIBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 20 * 4, AABBIdxs, GL_STATIC_DRAW);
|
||||
|
||||
glGenQueries(1, &m_query);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -138,6 +136,7 @@ std::vector<VISIRenderer::Model::Vert> VISIRenderer::AABBToVerts(const zeus::CAA
|
||||
|
||||
static zeus::CColor ColorForIndex(int i)
|
||||
{
|
||||
i += 1;
|
||||
return zeus::CColor((i & 0xff) / 255.f,
|
||||
((i >> 8) & 0xff) / 255.f,
|
||||
((i >> 16) & 0xff) / 255.f,
|
||||
@@ -202,6 +201,11 @@ bool VISIRenderer::SetupVertexBuffersAndFormats()
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Model::Vert), (void*)16);
|
||||
}
|
||||
|
||||
m_queryCount = m_models.size() + m_entities.size() + m_lights.size();
|
||||
m_queries.reset(new GLuint[m_queryCount]);
|
||||
m_queryBools.reset(new bool[m_queryCount]);
|
||||
glGenQueries(GLsizei(m_queryCount), m_queries.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -277,7 +281,7 @@ void VISIRenderer::RenderPVSOpaque(RGBA8* bufOut, const zeus::CVector3f& pos, bo
|
||||
glDepthMask(GL_TRUE);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearColor(1.f, 1.f, 1.f, 1.f);
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
for (int j=0 ; j<6 ; ++j)
|
||||
@@ -297,26 +301,6 @@ void VISIRenderer::RenderPVSOpaque(RGBA8* bufOut, const zeus::CVector3f& pos, bo
|
||||
zeus::CFrustum frustum;
|
||||
frustum.updatePlanes(mv, g_Proj);
|
||||
|
||||
// Fill depth buffer with backfaces initially
|
||||
glCullFace(GL_FRONT);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
|
||||
for (const Model& model : m_models)
|
||||
{
|
||||
if (!frustum.aabbFrustumTest(model.aabb))
|
||||
continue;
|
||||
glBindVertexArray(model.vao);
|
||||
for (const Model::Surface& surf : model.surfaces)
|
||||
{
|
||||
// Non-transparents first
|
||||
if (!surf.transparent)
|
||||
glDrawElements(model.topology, surf.count, GL_UNSIGNED_INT,
|
||||
reinterpret_cast<void*>(uintptr_t(surf.first * 4)));
|
||||
else
|
||||
needTransparent = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw frontfaces
|
||||
glCullFace(GL_BACK);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
@@ -362,6 +346,8 @@ void VISIRenderer::RenderPVSTransparent(const std::function<void(int)>& passFunc
|
||||
zeus::CFrustum frustum;
|
||||
frustum.updatePlanes(mv, g_Proj);
|
||||
|
||||
memset(m_queryBools.get(), 0, m_queryCount);
|
||||
|
||||
int idx = 0;
|
||||
for (const Model& model : m_models)
|
||||
{
|
||||
@@ -371,23 +357,29 @@ void VISIRenderer::RenderPVSTransparent(const std::function<void(int)>& passFunc
|
||||
continue;
|
||||
}
|
||||
glBindVertexArray(model.vao);
|
||||
glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_queries[idx]);
|
||||
m_queryBools[idx] = true;
|
||||
for (const Model::Surface& surf : model.surfaces)
|
||||
{
|
||||
// transparents
|
||||
if (surf.transparent)
|
||||
{
|
||||
glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query);
|
||||
glDrawElements(model.topology, surf.count, GL_UNSIGNED_INT,
|
||||
reinterpret_cast<void*>(uintptr_t(surf.first * 4)));
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
||||
GLint res;
|
||||
glGetQueryObjectiv(m_query, GL_QUERY_RESULT, &res);
|
||||
if (res)
|
||||
passFunc(idx);
|
||||
}
|
||||
}
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
|
||||
++idx;
|
||||
}
|
||||
|
||||
for (int i=0 ; i<idx ; ++i)
|
||||
{
|
||||
if (m_queryBools[i])
|
||||
{
|
||||
GLint res;
|
||||
glGetQueryObjectiv(m_queries[i], GL_QUERY_RESULT, &res);
|
||||
if (res)
|
||||
passFunc(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,6 +406,8 @@ void VISIRenderer::RenderPVSEntitiesAndLights(const std::function<void(int)>& pa
|
||||
zeus::CFrustum frustum;
|
||||
frustum.updatePlanes(mv, g_Proj);
|
||||
|
||||
memset(m_queryBools.get(), 0, m_queryCount);
|
||||
|
||||
int idx = m_models.size();
|
||||
for (const Entity& ent : m_entities)
|
||||
{
|
||||
@@ -423,36 +417,56 @@ void VISIRenderer::RenderPVSEntitiesAndLights(const std::function<void(int)>& pa
|
||||
continue;
|
||||
}
|
||||
glBindVertexArray(ent.vao);
|
||||
glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query);
|
||||
m_queryBools[idx] = true;
|
||||
glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_queries[idx]);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 20, GL_UNSIGNED_INT, 0);
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
||||
GLint res;
|
||||
glGetQueryObjectiv(m_query, GL_QUERY_RESULT, &res);
|
||||
if (res)
|
||||
passFunc(idx);
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
|
||||
++idx;
|
||||
}
|
||||
|
||||
for (const Light& light : m_lights)
|
||||
{
|
||||
if (!frustum.pointFrustumTest(light.point))
|
||||
{
|
||||
++idx;
|
||||
continue;
|
||||
}
|
||||
glBindVertexArray(light.vao);
|
||||
m_queryBools[idx] = true;
|
||||
glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_queries[idx]);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
|
||||
++idx;
|
||||
}
|
||||
|
||||
idx = m_models.size();
|
||||
for (const Entity& ent : m_entities)
|
||||
{
|
||||
if (m_queryBools[idx])
|
||||
{
|
||||
GLint res;
|
||||
glGetQueryObjectiv(m_queries[idx], GL_QUERY_RESULT, &res);
|
||||
if (res)
|
||||
passFunc(idx);
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
|
||||
int lightIdx = 0;
|
||||
for (const Light& light : m_lights)
|
||||
{
|
||||
if (!frustum.pointFrustumTest(light.point))
|
||||
if (m_queryBools[idx])
|
||||
{
|
||||
++lightIdx;
|
||||
continue;
|
||||
GLint res;
|
||||
glGetQueryObjectiv(m_queries[idx], GL_QUERY_RESULT, &res);
|
||||
EPVSVisSetState state = m_totalAABB.pointInside(light.point) ?
|
||||
EPVSVisSetState::EndOfTree : EPVSVisSetState::OutOfBounds;
|
||||
if (res && state == EPVSVisSetState::EndOfTree)
|
||||
state = EPVSVisSetState::NodeFound;
|
||||
lightPassFunc(lightIdx, state);
|
||||
}
|
||||
glBindVertexArray(light.vao);
|
||||
glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
||||
GLint res;
|
||||
glGetQueryObjectiv(m_query, GL_QUERY_RESULT, &res);
|
||||
EPVSVisSetState state = m_totalAABB.pointInside(light.point) ?
|
||||
EPVSVisSetState::EndOfTree : EPVSVisSetState::OutOfBounds;
|
||||
if (res && state == EPVSVisSetState::EndOfTree)
|
||||
state = EPVSVisSetState::NodeFound;
|
||||
lightPassFunc(lightIdx, state);
|
||||
++lightIdx;
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,9 @@ class VISIRenderer
|
||||
std::vector<Light> m_lights;
|
||||
bool SetupVertexBuffersAndFormats();
|
||||
|
||||
GLuint m_query;
|
||||
size_t m_queryCount;
|
||||
std::unique_ptr<GLuint[]> m_queries;
|
||||
std::unique_ptr<bool[]> m_queryBools;
|
||||
|
||||
FPercent m_updatePercent;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user