Results 1 to 5 of 5

Thread: GL: format, internal format, pixel format - my slightly stale research

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Now, when I want to load image into texture I call these helpers, the calling code is identical across GL and GLES:

    Code:
             format:= TGAPI.SupportedTexFormat(texformat_DXT5, texformat_LA8,
                                                      texformat_RGBA4, texformat_RGBA8);
    
             file_name:= UnmangleFilename('{$INSDIR}modules/chentrah/img/consolefont.png');
             if not FileExists(file_name)
               then Die(MI_ERROR_FILE_NOT_FOUND, [file_name]);
             p:= LoadPicAs(PFileNameChar(file_name), [format]);
             CheckForGuardedException;
             glGenTextures(1, @f_texture);
             glBindTexture(GL_TEXTURE_2D, f_texture);
             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
             TGAPI.TexImage2d(p, format);
             DeletePic(p);
    where:
    Code:
    function LoadPicAs (FileName: PFileNameChar;
                              ValidFormats: TGAPITextureFormatSet): pointer; cdecl;
    var
      n: TFileNameString;
      w: UnicodeString;
      i: PImageData;
      s: TFileStream = nil;
      p: pointer = nil;
      size: longint;
    begin
     if Mother^.Image.CorrectThreadId <> GetCurrentThreadId()
       then Die(MI_ERROR_PROGRAMMER_NO_BAKA, ['Imaging API called from a wrong thread']);
     try
      n:= UnmangleFileName(FileName);
      w:= FileNameToUnicode(n);
      i:=GetMem(SizeOf(TImageData));
      VyCheckFileNameLoad(w);
      if not FileExists(n)
        then Die(MI_ERROR_FILE_NOT_FOUND, [n]);
        { Whoops... vampyre is not unicode, have to load the file by ourselves! }
        try
          try
           s:= TFileStream.Create(n, fmOpenRead);
            size:= s.Size;
            p:= GetMem(size);
            s.ReadBuffer(p^, size);
            if not LoadImageFromMemory(p, size, i^) //Vampyre call
            then begin
              FreeMem(i);
              i:= nil;
              Die(FailedToDecodeMessage() ,[]);
            end;
          finally
            s.Free;
            FreeMem(p);
          end;
    
          ClearDyingEvents(GetExceptionState());
          //Vampyre often litters the dying events log with screened exceptions that
          //  my SEH still dutifully logs.
    
        except
          Die(
             'Не удалось прочитать "%0".'#10#13'  Скорее всего, файл повреждён.',
             'Cannot  read file "%0".'#10#13'  It''s probaly corrupt.', [w]);
        end;
      if Assigned(i) then ConvertImageIfNecessary (i, ValidFormats);
      Result:= i;
     except
      ProcessGuardedException();
     end;
    end;
    Code:
    procedure ConvertImageIfNecessary(var i: PImageData; ValidFormats: TGAPITextureFormatSet);
    var
      gf: TGapiTextureFormat;
      vy , nvy: TImageFormat;
      unnecessary: boolean;
    begin
     nvy:= ifUnknown;
     unnecessary:= false;
     for gf in ValidFormats do begin
       vy:= TGAPI.ImageFormatForTextureFormat[gf];
       if vy = i^.Format then begin
         unnecessary:= true;
         break;
       end;
       if nvy = ifUnknown then nvy:= vy;
       if unnecessary then break; // Why oh why there is no such thing as break 2 :(
     end;
    
     if unnecessary then begin
       if Mother^.Debug.Verbose then AddLog (
         '  There is no need to convert image as %0 already matches [%1]',
         [VyFormatName(i^.Format)  ,
          SetToString(dword((@ValidFormats)^), typeinfo(TGAPITextureFormatSet))]);
     end
     else begin
       if nvy = ifUnknown then Die(RuEn(
          'Невозможно привести изображение к набору абстрактных текстурных форматов [%0], т.к. ему не сопоставлен ни один формат изображения Vampyre Imaging',
          'Unable to convert image to the abstract texture formats set [%0] because it has no Vampyre Imaging image formats associated with it'
          ), [SetToString(dword((@ValidFormats)^), typeinfo(TGAPITextureFormatSet))]);
        if Mother^.Debug.Verbose then AddLog (
          '  Converting image from %0 to %1 to match [%2]',
          [ VyFormatName(i^.Format),// GetEnumName(typeinfo(TImageFormat), ord(i^.Format)),
              // cl_mother_api_imaging.inc(399,21) Error: No type info available for this type
              // ****.
    
            VyFormatname(nvy), //GetEnumName(typeinfo(TImageFormat), ord(nvy)), //cl_mother_api_imaging.inc(403,42) Error: No type info available for this type
            SetToString(dword((@ValidFormats)^), typeinfo(TGAPITextureFormatSet))]);
        ConvertImage(i^, nvy);
     end;
    end;
    Code:
    class function TGAPI.SupportedTexFormat(f1: TGAPITextureFormat;
      f2: TGAPITextureFormat = texformat_NONE;
      f3: TGAPITextureFormat = texformat_NONE;
      f4: TGAPITextureFormat = texformat_NONE;
      f5: TGAPITextureFormat = texformat_NONE
    ): TGAPITextureFormat;
    begin
      with Mother^.GAPI do begin
        if TexFormats^[f1].actual <> 0 then Exit(f1);
        if TexFormats^[f2].actual <> 0 then Exit(f2);
        if TexFormats^[f3].actual <> 0 then Exit(f3);
        if TexFormats^[f4].actual <> 0 then Exit(f4);
        if TexFormats^[f5].actual <> 0 then Exit(f5);
      end;
      Result:= texformat_NONE;
    end;
    Code:
    / Will evoke Die if image format is not in ImageFormatsPerTextureFormat
    //   for the given texture format.
    // Pass nil to i to load uninitialized image.
    // The caller is responsible for all sanity checks (if NPOT supported, etc.)
    class function TGAPI.TexImage2d(
          image: pointer;
          format: TGAPITextureFormat;
          level: GLuint = 0;
          width: GLuint = 0; // 0 = get from image
          height: GLuint = 0; // 0 = get from image
          CreateTextureObject: boolean = false
        ): GLuint; //no return value unless CreateTextureObject is true
    var
      sset: TGAPITextureFormatSet;
      e: GLenum;
    begin
      try
        sset:= Mother^.Image.GetFmt(image);
    //      CheckForGuardedException;
    
        if not (format in sset)
        then
       {$ifdef cgekernel}
         ConvertImageIfNecessary (image, [format]);
       {$else}
         // CANNOT convert on the fly.
         // Because converting should be a threaded task in a different thread.
         Die(RuEn(
           'Попытка загрузить в текстуру %0 изображение, совместимое с [%1]',
           'Attempt to upload image compatible with [%1] into texture %0'),
           [GetEnumName(typeinfo(TGAPITextureFormat), ord(format)),
            mo_cge.SetToString(pdword(@sset)^, typeinfo(TGAPITextureFormatSet))]);
       {$endif}
        case  Mother^.GAPI.Mode of
         {$ifndef glesonly}
          gapi_GL21,
         {$endif}
          gapi_GLES2 : begin
            if CreateTextureObject then begin
              glGenTextures(1, @Result);
              glBindTexture(GL_TEXTURE_2D, Result);
              CheckGLError;
            end;
            with Mother^.Image
              do with Mother^.GAPI.TexFormats^[format]
                do glTexImage2D (GL_TEXTURE_2D, level, actual,
                  GetWidth(image), GetHeight(image), 0, general, _type,
                  GetPixels(image));
            e:= glGetError();
            if e <> GL_NO_ERROR
              then with Mother^.GAPI.TexFormats^[format]
                do Die('%0 with %1 / %2 / %3 / %4', [
                  GlErrorCodeToString(e),
                  GetEnumName(typeinfo(TGAPITextureFormat), ord(format)),
                  GlTextureFormatToString(actual),
                  GlTextureFormatToString(general),
                  GlTextureFormatToString(_type)
                ]);
          end;
        else
          DieUnsupportedGLMode;
        end;
      except
        Die(RuEn(
          'Сбой при закачке текстуры в видеодрайвер',
          'Failed to upload texture image'));
      end;
    end;

  2. #2
    This web page pretty much explains what formats are always supported ("Required Formats" section).

    For others, you can use glGetInternalFormat to check for a particular internal format at run-time, which might be hardware-dependent.

    To find our overall support for some specific compressed formats there's a nice database site (which also has very useful information regarding OpenGL extensions):
    http://opengl.gpuinfo.org

    Edit: Raspberry PI doesn't support OpenGL ES 3, nor https://www.khronos.org/registry/OpenGL/extensions/OES/OES_texture_float.txt, which would explain your results regarding floating-point formats. For OpenGL ES, there is also ARB_internalformat_query2, although RPi doesn't seem to support it either, so you are pretty much limited to almost minimal OpenGL ES 2.0 spec (see Table 3.1 - Texture Image Formats and Types, on page 20).
    Last edited by LP; 24-01-2018 at 09:24 PM.

  3. #3
    Thank you for the links! When I try serach for GLES 2 documentation most websites force-feed me GLES 3 documentation in the form of "this link is obsolete, go that-a-ways" or auto-redirects.

    ..I'm going to feel the pain, ain't I...? With Raspberry...? No reading from depth, only one color attachment, maximum color depth is RGBA8...

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •