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;
Bookmarks