GLS.FilePGM.pas 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //
  2. // The graphics engine GLScene https://github.com/glscene
  3. //
  4. unit GLS.FilePGM;
  5. (* PGM image loader *)
  6. {$I GLScene.Defines.inc}
  7. interface
  8. uses
  9. Winapi.OpenGL,
  10. System.Classes,
  11. System.SysUtils,
  12. GLS.Context,
  13. GLS.Graphics,
  14. GLScene.TextureFormat,
  15. GLScene.Strings,
  16. GLS.ApplicationFileIO,
  17. CUDA.Utility;
  18. type
  19. TGLPGMImage = class(TGLBaseImage)
  20. public
  21. class function Capabilities: TGLDataFileCapabilities; override;
  22. procedure LoadFromFile(const filename: string); override;
  23. procedure SaveToFile(const filename: string); override;
  24. procedure LoadFromStream(stream: TStream); override;
  25. procedure SaveToStream(stream: TStream); override;
  26. procedure AssignFromTexture(textureContext: TGLContext; const textureHandle: Cardinal;
  27. textureTarget: TGLTextureTarget; const CurrentFormat: Boolean;
  28. const intFormat: TGLInternalFormat); reintroduce;
  29. end;
  30. // ------------------------------------------------------------------
  31. implementation
  32. // ------------------------------------------------------------------
  33. // ------------------
  34. // ------------------ TGLPGMImage ------------------
  35. // ------------------
  36. procedure TGLPGMImage.LoadFromFile(const filename: string);
  37. var
  38. w, h: Integer;
  39. cutBuffer: System.PSingle;
  40. begin
  41. if FileExists(filename) then
  42. begin
  43. if not IsCUTILInitialized then
  44. if not InitCUTIL then
  45. begin
  46. EInvalidRasterFile.Create(strCUTILFailed);
  47. exit;
  48. end;
  49. cutBuffer := nil;
  50. if cutLoadPGMf(PAnsiChar(AnsiString(filename)), cutBuffer, w, h) then
  51. begin
  52. ResourceName := filename;
  53. UnMipmap;
  54. FLOD[0].Width := w;
  55. FLOD[0].Height := h;
  56. FLOD[0].Depth := 0;
  57. fColorFormat := GL_LUMINANCE;
  58. fInternalFormat := tfLUMINANCE_FLOAT32;
  59. fDataType := GL_FLOAT;
  60. fCubeMap := false;
  61. fTextureArray := false;
  62. fElementSize := GetTextureElementSize(tfLUMINANCE_FLOAT32);
  63. ReallocMem(fData, DataSize);
  64. Move(cutBuffer^, fData^, DataSize);
  65. cutFree(cutBuffer);
  66. end;
  67. end
  68. else
  69. raise EInvalidRasterFile.CreateFmt('File %s not found', [filename]);
  70. end;
  71. procedure TGLPGMImage.SaveToFile(const filename: string);
  72. begin
  73. if not IsCUTILInitialized then
  74. if not InitCUTIL then
  75. begin
  76. EInvalidRasterFile.Create(strCUTILFailed);
  77. exit;
  78. end;
  79. if not cutSavePGMf(PAnsiChar(AnsiString(filename)), System.PSingle(fData), FLOD[0].Width,
  80. FLOD[0].Height) then
  81. raise EInvalidRasterFile.Create('Saving to file failed');
  82. end;
  83. procedure TGLPGMImage.LoadFromStream(stream: TStream);
  84. begin
  85. Assert(false, 'Stream loading not supported');
  86. end;
  87. procedure TGLPGMImage.SaveToStream(stream: TStream);
  88. begin
  89. Assert(false, 'Stream saving not supported');
  90. end;
  91. procedure TGLPGMImage.AssignFromTexture(textureContext: TGLContext; const textureHandle: Cardinal;
  92. textureTarget: TGLTextureTarget; const CurrentFormat: Boolean;
  93. const intFormat: TGLInternalFormat);
  94. var
  95. oldContext: TGLContext;
  96. contextActivate: Boolean;
  97. texFormat: Cardinal;
  98. residentFormat: TGLInternalFormat;
  99. glTarget: Cardinal;
  100. begin
  101. if not((textureTarget = ttTexture2D) or (textureTarget = ttTextureRect)) then
  102. exit;
  103. oldContext := CurrentGLContext;
  104. contextActivate := (oldContext <> textureContext);
  105. if contextActivate then
  106. begin
  107. if Assigned(oldContext) then
  108. oldContext.Deactivate;
  109. textureContext.Activate;
  110. end;
  111. glTarget := DecodeTextureTarget(textureTarget);
  112. try
  113. textureContext.GLStates.TextureBinding[0, textureTarget] := textureHandle;
  114. fLevelCount := 0;
  115. fCubeMap := false;
  116. fTextureArray := false;
  117. fColorFormat := GL_LUMINANCE;
  118. fDataType := GL_FLOAT;
  119. // Check level existence
  120. gl.GetTexLevelParameteriv(glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, @texFormat);
  121. if texFormat > 1 then
  122. begin
  123. gl.GetTexLevelParameteriv(glTarget, 0, GL_TEXTURE_WIDTH, @FLOD[0].Width);
  124. gl.GetTexLevelParameteriv(glTarget, 0, GL_TEXTURE_HEIGHT, @FLOD[0].Height);
  125. FLOD[0].Depth := 0;
  126. residentFormat := OpenGLFormatToInternalFormat(texFormat);
  127. if CurrentFormat then
  128. fInternalFormat := residentFormat
  129. else
  130. fInternalFormat := intFormat;
  131. Inc(fLevelCount);
  132. end;
  133. if fLevelCount > 0 then
  134. begin
  135. fElementSize := GetTextureElementSize(fColorFormat, fDataType);
  136. ReallocMem(fData, DataSize);
  137. gl.GetTexImage(glTarget, 0, fColorFormat, fDataType, fData);
  138. end
  139. else
  140. fLevelCount := 1;
  141. gl.CheckError;
  142. finally
  143. if contextActivate then
  144. begin
  145. textureContext.Deactivate;
  146. if Assigned(oldContext) then
  147. oldContext.Activate;
  148. end;
  149. end;
  150. end;
  151. class function TGLPGMImage.Capabilities: TGLDataFileCapabilities;
  152. begin
  153. Result := [dfcRead, dfcWrite];
  154. end;
  155. // ------------------------------------------------
  156. initialization
  157. // ------------------------------------------------
  158. RegisterRasterFormat('pgm', 'Portable Graymap', TGLPGMImage);
  159. end.