Fixed rendering for decoupled target texture

This commit is contained in:
Jack Andersen 2015-11-03 15:58:36 -10:00
parent 30898c6549
commit bc17d5aba8
5 changed files with 175 additions and 82 deletions

View File

@ -145,7 +145,19 @@ public:
virtual void setWindowFrameDefault()=0;
virtual void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const=0;
virtual void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const=0;
virtual SWindowRect getWindowFrame() const
{
SWindowRect retval;
getWindowFrame(retval.location[0], retval.location[1], retval.size[0], retval.size[1]);
return retval;
}
virtual void setWindowFrame(float x, float y, float w, float h)=0;
virtual void setWindowFrame(int x, int y, int w, int h)=0;
virtual void getWindowFrame(const SWindowRect& rect)
{
setWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]);
}
virtual float getVirtualPixelFactor() const=0;
virtual bool isFullscreen() const=0;

View File

@ -23,6 +23,8 @@ struct IGraphicsCommandQueue
virtual void setShaderDataBinding(IShaderDataBinding* binding)=0;
virtual void setRenderTarget(ITextureR* target)=0;
virtual void setViewport(const SWindowRect& rect)=0;
virtual void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)=0;
virtual void setClearColor(const float rgba[4])=0;
virtual void clearTarget(bool render=true, bool depth=true)=0;

View File

@ -154,8 +154,6 @@ class GLTextureR : public ITextureR
struct GLCommandQueue* m_q;
GLuint m_texs[2];
GLuint m_fbo = 0;
void* m_mappedBuf = nullptr;
size_t m_mappedSize = 0;
size_t m_width = 0;
size_t m_height = 0;
size_t m_samples = 0;
@ -168,6 +166,16 @@ public:
glActiveTexture(GL_TEXTURE0 + idx);
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
}
void resize(size_t width, size_t height)
{
m_width = width;
m_height = height;
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
}
};
ITextureS*
@ -499,6 +507,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
OpSetShaderDataBinding,
OpSetRenderTarget,
OpSetViewport,
OpResizeRenderTexture,
OpSetClearColor,
OpClearTarget,
OpSetDrawPrimitive,
@ -523,6 +532,12 @@ struct GLCommandQueue : IGraphicsCommandQueue
size_t count;
size_t instCount;
};
struct
{
ITextureR* tex;
size_t width;
size_t height;
} resize;
};
Command(Op op) : m_op(op) {}
};
@ -655,6 +670,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
glViewport(cmd.rect.location[0], cmd.rect.location[1],
cmd.rect.size[0], cmd.rect.size[1]);
break;
case Command::OpResizeRenderTexture:
{
GLTextureR* tex = static_cast<GLTextureR*>(cmd.resize.tex);
tex->resize(cmd.resize.width, cmd.resize.height);
}
case Command::OpSetClearColor:
glClearColor(cmd.rgba[0], cmd.rgba[1], cmd.rgba[2], cmd.rgba[3]);
break;
@ -732,6 +752,15 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.emplace_back(Command::OpSetViewport);
cmds.back().rect = rect;
}
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpResizeRenderTexture);
cmds.back().resize.tex = tex;
cmds.back().resize.width = width;
cmds.back().resize.height = height;
}
void setClearColor(const float rgba[4])
{

View File

@ -193,7 +193,7 @@ public:
IGraphicsDataFactory* getDataFactory()
{
if (!m_dataFactory)
m_dataFactory = new GLES3DataFactory(this);
m_dataFactory = new GLDataFactory(this);
return m_dataFactory;
}
@ -275,35 +275,43 @@ IGraphicsContext* _GraphicsContextCocoaNew(IGraphicsContext::EGraphicsAPI api,
return self;
}
- (void)reshape
{
boo::SWindowRect rect = {{int(self.frame.origin.x), int(self.frame.origin.y)},
{int(self.frame.size.width), int(self.frame.size.height)}};
booContext->m_callback->resized(rect);
[super reshape];
}
- (BOOL)acceptsTouchEvents
{
return YES;
}
static inline boo::IWindowCallback::EModifierKey getMod(NSUInteger flags)
static inline boo::EModifierKey getMod(NSUInteger flags)
{
int ret = boo::IWindowCallback::MKEY_NONE;
int ret = boo::MKEY_NONE;
if (flags & NSControlKeyMask)
ret |= boo::IWindowCallback::MKEY_CTRL;
ret |= boo::MKEY_CTRL;
if (flags & NSAlternateKeyMask)
ret |= boo::IWindowCallback::MKEY_ALT;
ret |= boo::MKEY_ALT;
if (flags & NSShiftKeyMask)
ret |= boo::IWindowCallback::MKEY_SHIFT;
ret |= boo::MKEY_SHIFT;
if (flags & NSCommandKeyMask)
ret |= boo::IWindowCallback::MKEY_COMMAND;
return static_cast<boo::IWindowCallback::EModifierKey>(ret);
ret |= boo::MKEY_COMMAND;
return static_cast<boo::EModifierKey>(ret);
}
static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
static inline boo::EMouseButton getButton(NSEvent* event)
{
NSInteger buttonNumber = event.buttonNumber;
if (buttonNumber == 3)
return boo::IWindowCallback::BUTTON_MIDDLE;
return boo::BUTTON_MIDDLE;
else if (buttonNumber == 4)
return boo::IWindowCallback::BUTTON_AUX1;
return boo::BUTTON_AUX1;
else if (buttonNumber == 5)
return boo::IWindowCallback::BUTTON_AUX2;
return boo::IWindowCallback::BUTTON_NONE;
return boo::BUTTON_AUX2;
return boo::BUTTON_NONE;
}
- (void)mouseDown:(NSEvent*)theEvent
@ -313,13 +321,13 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseDown(coord, boo::IWindowCallback::BUTTON_PRIMARY,
booContext->m_callback->mouseDown(coord, boo::BUTTON_PRIMARY,
getMod([theEvent modifierFlags]));
}
@ -330,13 +338,13 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseUp(coord, boo::IWindowCallback::BUTTON_PRIMARY,
booContext->m_callback->mouseUp(coord, boo::BUTTON_PRIMARY,
getMod([theEvent modifierFlags]));
}
@ -347,13 +355,13 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseDown(coord, boo::IWindowCallback::BUTTON_SECONDARY,
booContext->m_callback->mouseDown(coord, boo::BUTTON_SECONDARY,
getMod([theEvent modifierFlags]));
}
@ -364,13 +372,13 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseUp(coord, boo::IWindowCallback::BUTTON_SECONDARY,
booContext->m_callback->mouseUp(coord, boo::BUTTON_SECONDARY,
getMod([theEvent modifierFlags]));
}
@ -378,13 +386,13 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
{
if (!booContext->m_callback)
return;
boo::IWindowCallback::EMouseButton button = getButton(theEvent);
boo::EMouseButton button = getButton(theEvent);
if (!button)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
@ -397,13 +405,13 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
{
if (!booContext->m_callback)
return;
boo::IWindowCallback::EMouseButton button = getButton(theEvent);
boo::EMouseButton button = getButton(theEvent);
if (!button)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
@ -419,7 +427,7 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
@ -447,13 +455,13 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
boo::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
boo::IWindowCallback::SScrollDelta scroll =
boo::SScrollDelta scroll =
{
{(float)[theEvent scrollingDeltaX], (float)[theEvent scrollingDeltaY]},
(bool)[theEvent hasPreciseScrollingDeltas]
@ -468,7 +476,7 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseBegan inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::STouchCoord coord =
boo::STouchCoord coord =
{
{(float)pos.x, (float)pos.y}
};
@ -483,7 +491,7 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseEnded inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::STouchCoord coord =
boo::STouchCoord coord =
{
{(float)pos.x, (float)pos.y}
};
@ -498,7 +506,7 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseMoved inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::STouchCoord coord =
boo::STouchCoord coord =
{
{(float)pos.x, (float)pos.y}
};
@ -513,7 +521,7 @@ static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseCancelled inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::STouchCoord coord =
boo::STouchCoord coord =
{
{(float)pos.x, (float)pos.y}
};
@ -572,59 +580,59 @@ enum
kVK_DownArrow = 0x7D,
kVK_UpArrow = 0x7E
};
static boo::IWindowCallback::ESpecialKey translateKeycode(short code)
static boo::ESpecialKey translateKeycode(short code)
{
switch (code) {
case kVK_F1:
return boo::IWindowCallback::KEY_F1;
return boo::KEY_F1;
case kVK_F2:
return boo::IWindowCallback::KEY_F2;
return boo::KEY_F2;
case kVK_F3:
return boo::IWindowCallback::KEY_F3;
return boo::KEY_F3;
case kVK_F4:
return boo::IWindowCallback::KEY_F4;
return boo::KEY_F4;
case kVK_F5:
return boo::IWindowCallback::KEY_F5;
return boo::KEY_F5;
case kVK_F6:
return boo::IWindowCallback::KEY_F6;
return boo::KEY_F6;
case kVK_F7:
return boo::IWindowCallback::KEY_F7;
return boo::KEY_F7;
case kVK_F8:
return boo::IWindowCallback::KEY_F8;
return boo::KEY_F8;
case kVK_F9:
return boo::IWindowCallback::KEY_F9;
return boo::KEY_F9;
case kVK_F10:
return boo::IWindowCallback::KEY_F10;
return boo::KEY_F10;
case kVK_F11:
return boo::IWindowCallback::KEY_F11;
return boo::KEY_F11;
case kVK_F12:
return boo::IWindowCallback::KEY_F12;
return boo::KEY_F12;
case kVK_Escape:
return boo::IWindowCallback::KEY_ESC;
return boo::KEY_ESC;
case kVK_Return:
return boo::IWindowCallback::KEY_ENTER;
return boo::KEY_ENTER;
case kVK_Delete:
return boo::IWindowCallback::KEY_BACKSPACE;
return boo::KEY_BACKSPACE;
case kVK_ForwardDelete:
return boo::IWindowCallback::KEY_DELETE;
return boo::KEY_DELETE;
case kVK_Home:
return boo::IWindowCallback::KEY_HOME;
return boo::KEY_HOME;
case kVK_End:
return boo::IWindowCallback::KEY_END;
return boo::KEY_END;
case kVK_PageUp:
return boo::IWindowCallback::KEY_PGUP;
return boo::KEY_PGUP;
case kVK_PageDown:
return boo::IWindowCallback::KEY_PGDOWN;
return boo::KEY_PGDOWN;
case kVK_LeftArrow:
return boo::IWindowCallback::KEY_LEFT;
return boo::KEY_LEFT;
case kVK_RightArrow:
return boo::IWindowCallback::KEY_RIGHT;
return boo::KEY_RIGHT;
case kVK_UpArrow:
return boo::IWindowCallback::KEY_UP;
return boo::KEY_UP;
case kVK_DownArrow:
return boo::IWindowCallback::KEY_DOWN;
return boo::KEY_DOWN;
default:
return boo::IWindowCallback::KEY_NONE;
return boo::KEY_NONE;
}
}
@ -668,23 +676,23 @@ static boo::IWindowCallback::ESpecialKey translateKeycode(short code)
NSUInteger downFlags = changedFlags & modFlags;
if (downFlags & NSControlKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_CTRL, isRepeat);
booContext->m_callback->modKeyDown(boo::MKEY_CTRL, isRepeat);
if (downFlags & NSAlternateKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_ALT, isRepeat);
booContext->m_callback->modKeyDown(boo::MKEY_ALT, isRepeat);
if (downFlags & NSShiftKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_SHIFT, isRepeat);
booContext->m_callback->modKeyDown(boo::MKEY_SHIFT, isRepeat);
if (downFlags & NSCommandKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_COMMAND, isRepeat);
booContext->m_callback->modKeyDown(boo::MKEY_COMMAND, isRepeat);
NSUInteger upFlags = changedFlags & ~modFlags;
if (upFlags & NSControlKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_CTRL);
booContext->m_callback->modKeyUp(boo::MKEY_CTRL);
if (upFlags & NSAlternateKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_ALT);
booContext->m_callback->modKeyUp(boo::MKEY_ALT);
if (upFlags & NSShiftKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_SHIFT);
booContext->m_callback->modKeyUp(boo::MKEY_SHIFT);
if (upFlags & NSCommandKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_COMMAND);
booContext->m_callback->modKeyUp(boo::MKEY_COMMAND);
lastModifiers = modFlags;
}
@ -781,6 +789,15 @@ public:
hOut = wFrame.size.height;
}
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const
{
NSRect wFrame = m_nsWindow.frame;
xOut = wFrame.origin.x;
yOut = wFrame.origin.y;
wOut = wFrame.size.width;
hOut = wFrame.size.height;
}
void setWindowFrame(float x, float y, float w, float h)
{
dispatch_sync(dispatch_get_main_queue(),
@ -790,6 +807,15 @@ public:
});
}
void setWindowFrame(int x, int y, int w, int h)
{
dispatch_sync(dispatch_get_main_queue(),
^{
NSRect wFrame = NSMakeRect(x, y, w, h);
[m_nsWindow setFrame:wFrame display:NO];
});
}
float getVirtualPixelFactor() const
{
return [m_nsWindow backingScaleFactor];

View File

@ -115,8 +115,15 @@ public:
struct CTestWindowCallback : IWindowCallback
{
SWindowRect m_lastRect;
bool m_rectDirty = false;
void resized(const SWindowRect& rect)
{ fprintf(stderr, "Resized %d, %d (%d, %d)\n", rect.size[0], rect.size[1], rect.location[0], rect.location[1]); }
{
m_lastRect = rect;
m_rectDirty = true;
fprintf(stderr, "Resized %d, %d (%d, %d)\n", rect.size[0], rect.size[1], rect.location[0], rect.location[1]);
}
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
{
@ -183,13 +190,25 @@ struct TestApplicationCallback : IApplicationCallback
bool running = true;
IShaderDataBinding* m_binding = nullptr;
ITextureR* m_renderTarget = nullptr;
std::mutex m_mt;
std::condition_variable m_cv;
std::mutex m_initmt;
std::condition_variable m_initcv;
static void LoaderProc(TestApplicationCallback* self)
{
std::unique_lock<std::mutex> lk(self->m_initmt);
GLDataFactory* factory =
dynamic_cast<GLDataFactory*>(self->mainWindow->getLoadContextDataFactory());
/* Create render target */
int x, y, w, h;
self->mainWindow->getWindowFrame(x, y, w, h);
self->m_renderTarget = factory->newRenderTexture(w, h, 1);
/* Make Tri-strip VBO */
struct Vert
@ -263,6 +282,10 @@ struct TestApplicationCallback : IApplicationCallback
/* Commit objects */
IGraphicsData* data = factory->commit();
/* Return control to client */
lk.unlock();
self->m_initcv.notify_one();
/* Wait for exit */
while (self->running)
@ -281,34 +304,35 @@ struct TestApplicationCallback : IApplicationCallback
mainWindow = app->newWindow(_S("YAY!"));
mainWindow->setCallback(&windowCallback);
mainWindow->showWindow();
windowCallback.m_lastRect = mainWindow->getWindowFrame();
//mainWindow->setFullscreen(true);
devFinder.startScanning();
IGraphicsCommandQueue* gfxQ = mainWindow->getCommandQueue();
IGraphicsDataFactory* gfxF = mainWindow->getDataFactory();
ITextureR* renderTarget = gfxF->newRenderTexture(640, 480, 1);
gfxF->commit();
std::unique_lock<std::mutex> lk(m_initmt);
std::thread loaderThread(LoaderProc, this);
m_initcv.wait(lk);
size_t frameIdx = 0;
size_t lastCheck = 0;
while (running)
{
mainWindow->waitForRetrace();
gfxQ->setRenderTarget(renderTarget);
gfxQ->setViewport({{0, 0}, {640, 480}});
gfxQ->setRenderTarget(m_renderTarget);
gfxQ->setViewport(windowCallback.m_lastRect);
if (windowCallback.m_rectDirty)
{
gfxQ->resizeRenderTexture(m_renderTarget, windowCallback.m_lastRect.size[0], windowCallback.m_lastRect.size[1]);
windowCallback.m_rectDirty = false;
}
float rgba[] = {sinf(frameIdx / 60.0), cosf(frameIdx / 60.0), 0.0, 1.0};
gfxQ->setClearColor(rgba);
gfxQ->clearTarget();
if (m_binding)
{
gfxQ->setDrawPrimitive(PrimitiveTriStrips);
gfxQ->setShaderDataBinding(m_binding);
gfxQ->draw(0, 4);
}
gfxQ->resolveDisplay(renderTarget);
gfxQ->setDrawPrimitive(PrimitiveTriStrips);
gfxQ->setShaderDataBinding(m_binding);
gfxQ->draw(0, 4);
gfxQ->resolveDisplay(m_renderTarget);
gfxQ->execute();
//fprintf(stderr, "%zu\n", frameIdx);