- moved the render interface functions out of FGLRenderer into OpenGLFrameBuffer.
These need some consolidation among the backends, and the additional indirection in the OpenGL backend made it harder than necessary.
This commit is contained in:
parent
ab16cbe298
commit
70d30feb4c
5 changed files with 147 additions and 158 deletions
|
|
@ -30,6 +30,7 @@
|
|||
#include "v_video.h"
|
||||
#include "m_png.h"
|
||||
#include "templates.h"
|
||||
#include "i_time.h"
|
||||
|
||||
#include "gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
|
|
@ -40,18 +41,25 @@
|
|||
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||
#include "hwrenderer/models/hw_models.h"
|
||||
#include "hwrenderer/scene/hw_skydome.h"
|
||||
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
#include "hwrenderer/dynlights/hw_lightbuffer.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl_debug.h"
|
||||
#include "r_videoscale.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "swrenderer/r_swscene.h"
|
||||
|
||||
#include "hwrenderer/data/flatvertices.h"
|
||||
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||
EXTERN_CVAR(Int, gl_tonemap)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
|
||||
void DoWriteSavePic(FileWriter* file, ESSType ssformat, uint8_t* scr, int width, int height, sector_t* viewsector, bool upsidedown);
|
||||
|
||||
extern bool NoInterpolateView;
|
||||
|
||||
void gl_LoadExtensions();
|
||||
void gl_PrintStartupLog();
|
||||
|
|
@ -193,9 +201,79 @@ void OpenGLFrameBuffer::Update()
|
|||
void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
|
||||
{
|
||||
if (!V_IsHardwareRenderer())
|
||||
{
|
||||
Super::WriteSavePic(player, file, width, height);
|
||||
}
|
||||
else if (GLRenderer != nullptr)
|
||||
GLRenderer->WriteSavePic(player, file, width, height);
|
||||
{
|
||||
IntRect bounds;
|
||||
bounds.left = 0;
|
||||
bounds.top = 0;
|
||||
bounds.width = width;
|
||||
bounds.height = height;
|
||||
|
||||
// we must be sure the GPU finished reading from the buffer before we fill it with new data.
|
||||
glFinish();
|
||||
|
||||
// Switch to render buffers dimensioned for the savepic
|
||||
GLRenderer->mBuffers = GLRenderer->mSaveBuffers;
|
||||
|
||||
hw_ClearFakeFlat();
|
||||
gl_RenderState.SetVertexBuffer(screen->mVertexData);
|
||||
screen->mVertexData->Reset();
|
||||
screen->mLights->Clear();
|
||||
screen->mViewpoints->Clear();
|
||||
|
||||
// This shouldn't overwrite the global viewpoint even for a short time.
|
||||
FRenderViewpoint savevp;
|
||||
sector_t* viewsector = GLRenderer->RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
gl_RenderState.SetNoSoftLightLevel();
|
||||
GLRenderer->CopyToBackbuffer(&bounds, false);
|
||||
|
||||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||
glFinish();
|
||||
|
||||
int numpixels = width * height;
|
||||
uint8_t* scr = (uint8_t*)M_Malloc(numpixels * 3);
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, scr);
|
||||
|
||||
DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, true);
|
||||
M_Free(scr);
|
||||
|
||||
// Switch back the screen render buffers
|
||||
screen->SetViewportRects(nullptr);
|
||||
GLRenderer->mBuffers = GLRenderer->mScreenBuffers;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Camera texture rendering
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture* tex, AActor* Viewpoint, double FOV)
|
||||
{
|
||||
// This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene.
|
||||
|
||||
float ratio = tex->aspectRatio;
|
||||
|
||||
GLRenderer->StartOffscreen();
|
||||
GLRenderer->BindToFrameBuffer(tex);
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
bounds.width = FHardwareTexture::GetTexDimension(tex->GetWidth());
|
||||
bounds.height = FHardwareTexture::GetTexDimension(tex->GetHeight());
|
||||
|
||||
FRenderViewpoint texvp;
|
||||
GLRenderer->RenderViewpoint(texvp, Viewpoint, &bounds, FOV, ratio, ratio, false, false);
|
||||
|
||||
GLRenderer->EndOffscreen();
|
||||
|
||||
tex->SetUpdated(true);
|
||||
static_cast<OpenGLFrameBuffer*>(screen)->camtexcount++;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -207,7 +285,70 @@ void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int wid
|
|||
sector_t *OpenGLFrameBuffer::RenderView(player_t *player)
|
||||
{
|
||||
if (GLRenderer != nullptr)
|
||||
return GLRenderer->RenderView(player);
|
||||
{
|
||||
gl_RenderState.SetVertexBuffer(screen->mVertexData);
|
||||
screen->mVertexData->Reset();
|
||||
sector_t* retsec;
|
||||
|
||||
if (!V_IsHardwareRenderer())
|
||||
{
|
||||
if (GLRenderer->swdrawer == nullptr) GLRenderer->swdrawer = new SWSceneDrawer;
|
||||
retsec = GLRenderer->swdrawer->RenderView(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
hw_ClearFakeFlat();
|
||||
|
||||
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||
|
||||
checkBenchActive();
|
||||
|
||||
// reset statistics counters
|
||||
ResetProfilingData();
|
||||
|
||||
// Get this before everything else
|
||||
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
|
||||
else r_viewpoint.TicFrac = I_GetTimeFrac();
|
||||
|
||||
screen->mLights->Clear();
|
||||
screen->mViewpoints->Clear();
|
||||
|
||||
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
|
||||
bool saved_niv = NoInterpolateView;
|
||||
NoInterpolateView = false;
|
||||
|
||||
// Shader start time does not need to be handled per level. Just use the one from the camera to render from.
|
||||
if (player->camera)
|
||||
gl_RenderState.CheckTimer(player->camera->Level->ShaderStartTime);
|
||||
// prepare all camera textures that have been used in the last frame.
|
||||
// This must be done for all levels, not just the primary one!
|
||||
for (auto Level : AllLevels())
|
||||
{
|
||||
Level->canvasTextureInfo.UpdateAll([&](AActor* camera, FCanvasTexture* camtex, double fov)
|
||||
{
|
||||
RenderTextureView(camtex, camera, fov);
|
||||
});
|
||||
}
|
||||
NoInterpolateView = saved_niv;
|
||||
|
||||
|
||||
// now render the main view
|
||||
float fovratio;
|
||||
float ratio = r_viewwindow.WidescreenRatio;
|
||||
if (r_viewwindow.WidescreenRatio >= 1.3f)
|
||||
{
|
||||
fovratio = 1.333333f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fovratio = ratio;
|
||||
}
|
||||
|
||||
retsec = GLRenderer->RenderViewpoint(r_viewpoint, player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
|
||||
}
|
||||
All.Unclock();
|
||||
return retsec;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue