2
0
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:
Jack Andersen
2017-10-21 20:11:22 -10:00
parent 5e88b99769
commit 15d60493f2
53 changed files with 620 additions and 313 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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