This commit is contained in:
1 parent
6d3b8e6ac5
commit
8ffff2f916
2 files changed
-134
No files matched your search
@@ -21,20 +21,8 @@ type
|
||||
|
||||
//General OpenGL handling
|
||||
TKMRender = class
|
||||
private class var
|
||||
fMaxViewportDim: Cardinal; // Max Viewport Dimensions, which could be used for FBO render
|
||||
private
|
||||
// Flag, True when FBO is inited. We don't need to init FBO for every run, since its only used in SaveMapToImageFile feature
|
||||
fFBOInited: Boolean;
|
||||
// Off-screen buffer, example from https://stackoverflow.com/questions/12157646/how-to-render-offscreen-on-opengl
|
||||
fFBO: Cardinal;
|
||||
fRenderBuf: Cardinal;
|
||||
|
||||
fScreenX, fScreenY: Word;
|
||||
|
||||
procedure InitFBO;
|
||||
procedure SaveBufferToFile(aUseFBOBuffer: Boolean; var aWidth, aHeight: Integer; var aPixelData: TKMCardinalArray);
|
||||
function GetMaxFBOSize: Cardinal;
|
||||
public
|
||||
constructor Create(aScreenX, aScreenY: Integer);
|
||||
destructor Destroy; override;
|
||||
@@ -46,7 +34,6 @@ type
|
||||
class function SampledProgramReady: Boolean; static;
|
||||
class procedure DrawSampledTriangles(const aVertices: array of TKMSampledVertex; const aColor: TKMColor4f); static;
|
||||
class function GetMaxTexSize: Cardinal; static;
|
||||
class function GetMaxViewportDim: Cardinal; static;
|
||||
class function GenerateTextureCommon(aMinFilter, aMagFilter: TKMFilterType): Cardinal;
|
||||
class function GenTexture(DestX, DestY: Word; const Data: Pointer; Mode: TKMTexFormat; aMinFilter, aMagFilter: TKMFilterType): Cardinal;
|
||||
class procedure DeleteTexture(aTex: Cardinal);
|
||||
@@ -55,14 +42,9 @@ type
|
||||
class procedure InvalidateTextureBindingCache; static;
|
||||
|
||||
class property MaxTextureSize: Cardinal read GetMaxTexSize;
|
||||
class property MaxViewportDim: Cardinal read GetMaxViewportDim;
|
||||
|
||||
property MaxFBOSize: Cardinal read GetMaxFBOSize;
|
||||
procedure Resize(aWidth, aHeight: Integer);
|
||||
|
||||
procedure ReadRenderedToScreenPixels(var aWidth, aHeight: Integer; var aPixelData: TKMCardinalArray);
|
||||
procedure ReadRenderedToFBOPixels(var aWidth, aHeight: Integer; var aPixelData: TKMCardinalArray);
|
||||
|
||||
property ScreenX: Word read fScreenX;
|
||||
property ScreenY: Word read fScreenY;
|
||||
|
||||
@@ -82,27 +64,10 @@ uses
|
||||
KM_Defaults, KM_IoPNG, KM_CommonClasses,
|
||||
KM_Render_Mobile;
|
||||
|
||||
const
|
||||
// We want to use off-screen FBO buffer to render full map to the file,
|
||||
// we are restricted with max file we are able to write via TBitmap or TJpegImage or TPNGImage atm
|
||||
// could check https://github.com/graphics32 package to solve this issue with saving ultra large images
|
||||
MAX_FBO_BUFFER_SIZE = CELL_SIZE_PX * (MAX_MAP_SIZE - 1); // (10200 = CELL_SIZE=40px)*255
|
||||
|
||||
{ TKMRender }
|
||||
constructor TKMRender.Create(aScreenX, aScreenY: Integer);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fFBOInited := False;
|
||||
if not fBlind then
|
||||
begin
|
||||
fMaxViewportDim := GetMaxViewportDim;
|
||||
|
||||
//glEnable(GL_CULL_FACE);
|
||||
//glCullFace(GL_FRONT);
|
||||
|
||||
|
||||
end;
|
||||
Resize(aScreenX, aScreenY);
|
||||
end;
|
||||
|
||||
@@ -110,34 +75,10 @@ end;
|
||||
destructor TKMRender.Destroy;
|
||||
begin
|
||||
KMRenderMobileInvalidateSampledProgram;
|
||||
if not fBlind then
|
||||
begin
|
||||
if fFBOInited then
|
||||
begin
|
||||
glDeleteFramebuffers(1,@fFBO);
|
||||
glDeleteRenderbuffers(1,@fRenderBuf);
|
||||
end;
|
||||
end;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
procedure TKMRender.InitFBO;
|
||||
begin
|
||||
if fFBOInited then Exit;
|
||||
|
||||
fFBOInited := True;
|
||||
|
||||
glGenFramebuffers(1, @fFBO);
|
||||
glGenRenderbuffers(1, @fRenderBuf);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, fRenderBuf);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, GetMaxFBOSize, GetMaxFBOSize);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fFBO);
|
||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fRenderBuf);
|
||||
end;
|
||||
|
||||
|
||||
//We have to use this method EVERY time we want to bind texture. Otherwise collisions could happen
|
||||
//
|
||||
//Do not bind same texture again, it can drastically change render performance
|
||||
@@ -198,12 +139,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function TKMRender.GetMaxFBOSize: Cardinal;
|
||||
begin
|
||||
Result := Min(fMaxViewportDim, MAX_FBO_BUFFER_SIZE);
|
||||
end;
|
||||
|
||||
|
||||
class procedure TKMRender.GraphicsContextChanged(aAvailable: Boolean);
|
||||
begin
|
||||
if aAvailable then
|
||||
@@ -251,16 +186,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
class function TKMRender.GetMaxViewportDim: Cardinal;
|
||||
begin
|
||||
if fMaxViewportDim > 0 then Exit(fMaxViewportDim);
|
||||
|
||||
//Get max supported dimensions for viewport (used in off-screen render, FBO)
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, @fMaxViewportDim);
|
||||
Result := fMaxViewportDim;
|
||||
end;
|
||||
|
||||
|
||||
//Update texture with TCardinalArray
|
||||
class procedure TKMRender.UpdateTexture(aTexture: Cardinal; DestX, DestY: Word; Mode: TKMTexFormat; const Data: Pointer);
|
||||
begin
|
||||
@@ -268,65 +193,8 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TKMRender.ReadRenderedToScreenPixels(var aWidth, aHeight: Integer; var aPixelData: TKMCardinalArray);
|
||||
begin
|
||||
SaveBufferToFile(False, aWidth, aHeight, aPixelData);
|
||||
end;
|
||||
|
||||
|
||||
procedure TKMRender.ReadRenderedToFBOPixels(var aWidth, aHeight: Integer; var aPixelData: TKMCardinalArray);
|
||||
begin
|
||||
SaveBufferToFile(True, aWidth, aHeight, aPixelData);
|
||||
end;
|
||||
|
||||
|
||||
procedure TKMRender.SaveBufferToFile(aUseFBOBuffer: Boolean; var aWidth, aHeight: Integer; var aPixelData: TKMCardinalArray);
|
||||
{$IFDEF WDC}
|
||||
var
|
||||
I, K: Integer;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF WDC}
|
||||
aWidth := ScreenX;
|
||||
aHeight := ScreenY;
|
||||
|
||||
if aUseFBOBuffer then
|
||||
begin
|
||||
// Read from offscreen buffer
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
// Bind to FBO framebuffer
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fFBO);
|
||||
end
|
||||
else
|
||||
// Read from onscreen buffer
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
SetLength(aPixelData, aWidth * aHeight + 1);
|
||||
glReadPixels(0, 0, aWidth, aHeight, GL_BGRA, GL_UNSIGNED_BYTE, @aPixelData[0]);
|
||||
|
||||
if aUseFBOBuffer then
|
||||
// Return to onscreen rendering:
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
//Mirror verticaly
|
||||
for i := 0 to (aHeight div 2) - 1 do
|
||||
for K := 0 to aWidth - 1 do
|
||||
SwapInt(aPixelData[i * aWidth + K], aPixelData[((aHeight - 1) - i) * aWidth + K]);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
|
||||
procedure TKMRender.BeginFrame;
|
||||
begin
|
||||
if SAVE_MAP_TO_FBO_RENDER then
|
||||
begin
|
||||
if not fFBOInited then
|
||||
// Init once
|
||||
InitFBO // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fFBO) is called while initialization
|
||||
else
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fFBO);
|
||||
end;
|
||||
|
||||
KMRenderMobileClearCurrentTarget;
|
||||
SetRenderMode(rm2D);
|
||||
|
||||
|
||||
Reference in new issue
Block a user