PDA

View Full Version : Tga image save



Macros The Black
25-04-2009, 09:55
Hi
I have a few questions regarding image output from a tbgl/opengl window... i have been looking into this and it does seems quite possible..

1..I want to save an image in tga format....

2..I would need to get alpha channel working so only objects are rendered to the tga image with the
background being transparent....This is secondary objective...for now just saving to tga format is the main problem...

3.The reasons for doing this are many...but the main reason is the easy creation of tga image with alpha from any model
loaded into a tbgl/opengl scene...The images can then be used as billboards with alpha in realtime or in high end rendering
software....

Now for the million dollar question..
I have found an example of saving to tga format but the code is c++...I know nothing about c++ so i dont really know how to convert this to working tbgl/thinbasic code...

It should be possible to translate from c++ to tbgl/thinbasic shouldnt it ?

It seems that most of the code is opengl related and would translate easily for someone that understands c++...
Also i dont know if this code includes alpha or not...but it would be nice...

So i guess i am asking if anyone out there knows c++ and would be willing to translate this code to tbgl/thinbasic...

I post the code below in hope that someone can convert it (It would be of benifit to everyone to have tga output available)

Really only concerned about writing of tga files and the c++ code that writes tga has been
pasted into the thinbasic script named TGA SAVE....
The c++ source is there for anyone that would need it....
As well the compiled c++ app that loads an image then saves an image....

Petr Schreiber
25-04-2009, 10:44
Hi Macros,

here is one of possible approaches.

Please be warned it is really slow, but it shows the concept.
You just read RGB from screen pixels, if it is color of background then you set it transparent, in other cases not transparent.


'
' Saving TGA image
' Not optimized!
' Use SPACE to save image
'
' Petr Schreiber, 2009
'

Uses "TBGL", "console", "file"

global hWnd AS DWORD

TYPE TGAHeader
IDLength as BYTE
ColorMapType as BYTE
ImageType as BYTE
CMapStart as WORD
CMapLength as WORD
CMapDepth as BYTE
XOffset as WORD
YOffset as WORD
Width as WORD
Height as WORD
PixelDepth as BYTE
ImageDescriptor as BYTE
END TYPE

FUNCTION TBMAIN()
LOCAL FrameRate AS DOUBLE

' -- Create and show window
hWnd = TBGL_CreateWindowEx("TBGL script - press ESC to quit", 160, 120, 32, %TBGL_WS_WINDOWED or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow
TBGL_BackColor 255,255,255
' -- Initialize lighting
TBGL_UseLighting %TRUE
TBGL_UseLightSource %GL_LIGHT0, %TRUE

tbgl_SetLightParameter %GL_LIGHT0, %TBGL_LIGHT_POSITION, 15, 10, 15, 1

' -- Resets status of all keys
TBGL_ResetKeyState()

' -- Main loop
While TBGL_IsWindow(hWnd)
FrameRate = TBGL_GetFrameRate

TBGL_ClearFrame
TBGL_Camera 15, 15, 15, 0, 0, 0

TBGL_Color 255, 128, 0
TBGL_Box 5, 5, 5

TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
If TBGL_GetWindowKeyState(hWnd, %VK_SPACE) Then SaveTGA(APP_SOURCEPATH+"Image.TGA", 255, 255, 255)

Wend

TBGL_DestroyWindow
END FUNCTION

FUNCTION SaveTGA( fName as string, trR as long, trG as long, trB as long )

local w, h as long
local i, j as long
local r, g, b as long
TBGL_GetWindowClient(hWnd, w, h)

' -- Prepairing header
local header as TGAheader
local BGRAbuffer as string = repeat$(w*h*4, $NUL)
local position as long
local alpha as long

with header
.IDLength = 0
.ColorMapType = 0 ' -- No palette
.ImageType = 2 ' -- No compression, true color
.CMapStart = 0 ' -- No palette ... so zeros
.CMapLength = 0
.CMapDepth = 0
.XOffset = 0
.YOffset = 0
.Width = w
.Height = h
.PixelDepth = 32' -- BGR+A
.ImageDescriptor = 0
end with

' Saving header
file_save(fName, peek$(varptr(header), sizeof(TGAheader)))

printl "Reading BGRA..."
' -- Reading pixels
position = 1
for i = h to 1 step -1
for j = 1 to w
tbgl_GetPixelInfo(j, i, %TBGL_PINFO_RGB, r, g, b )
if r=trR and g= trG and b=trB then
alpha = 0
else
alpha = 255
end if
mid$(BGRAbuffer, position) = mkbyt$(b,g,r,alpha)
position += 4
next
printl "Line:"+STR$(i)+" /"+STR$(h)
next
printl "Saving BGRA..."
file_append(fName, BGRAbuffer)
printl "Saved"

END FUNCTION


Petr

P.S. The C++ code you attached contains only MSVS solution and project, but not the actual CPP files :)

Macros The Black
25-04-2009, 13:10
Sorry about the c++ script
i cannot get the rest of the files to upload...keep getting server time out error....
The original c++ script is from the resources of Addison Wesley OpenGL SuperBible 4th Edition...
The whole c++ resource file can be downloaded from http://www.starstonesoftware.com/OpenGL/

Also thanks for save tga script..
your right..............it does take a while
it also renders a bit weird with tree generator but i think i know how to fix that....

below is one approach i was trying but couldnt get to work...
the script is an experiment and i dont know if it currently works.....
Also the script has been edited and edited again and almost worked several times but i changed things too often and cant remember what i did to get it even partially working....
The main reason i post this is to see if you think this approach may have worked...

FUNCTION SaveFile( ) AS STRING
dim i as long
dim data as string
dim pBits as GLbyte
sFilter = "tga Export (*.tga)|*.tga|"
sFilter += "All Files (*.*)|*.*"
sFile = DIALOG_SAVEFILE( hDlg, _
"Open an file", _
DIR_GETCURRENT, _
sFilter, _
"tga", _
%OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY OR %OFN_ENABLESIZING )

IF sFile = "" THEN
MSGBOX 0, "No file selected.", %MB_ICONEXCLAMATION, "File confirmation"
ELSE
MSGBOX 0, sfile + "...." + "All done"
END IF


glFinish()
glPixelStorei(%GL_PACK_ALIGNMENT, 1)
glPixelStorei(%GL_PACK_ROW_LENGTH, 0)
glPixelStorei(%GL_PACK_SKIP_ROWS, 0)
glPixelStorei(%GL_PACK_SKIP_PIXELS, 0)
glReadPixels(0, 0, hdlg, hdlg, %GL_RGBA,%GL_UNSIGNED_BYTE,pbits)
data = pbits

return data

FileContents = data



FileContents += $CRLF
status = FILE_SAVE( sfile,FileContents )
FUNCTION = sfile
END FUNCTION

Petr Schreiber
25-04-2009, 14:37
Hi,

you were on the right track ;)

Here is working solution for saving:


FUNCTION SaveTGA()

local w, h as long
local i, j as long
local r, g, b as long
local sFilter as string = "tga Export (*.tga)|*.tga"
local sFile as string = DIALOG_SAVEFILE( hWnd, _
"Open an file", _
app_sourcepath, _
sFilter, _
"tga", _
%OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY OR %OFN_ENABLESIZING )

IF len(sFile) = 0 THEN MSGBOX hWnd, "No file selected.", %MB_ICONEXCLAMATION, "File confirmation"

TBGL_GetWindowClient(hWnd, w, h)

' -- Prepairing header
local header as TGAheader
local position as long
local alpha as long

with header
.IDLength = 0
.ColorMapType = 0 ' -- No palette
.ImageType = 2 ' -- No compression, true color
.CMapStart = 0 ' -- No palette ... so zeros
.CMapLength = 0
.CMapDepth = 0
.XOffset = 0
.YOffset = 0
.Width = w
.Height = h
.PixelDepth = 32' -- BGR+A
.ImageDescriptor = 0
end with

' Saving header
file_save(sFile, peek$(varptr(header), sizeof(TGAheader)))

' -- Reading pixels
local BGRAbuffer as string = repeat$(w * h * 4, $SPC)
local pBits as dword = strptr(BGRAbuffer)

glReadPixels(0, 0, w, h, %GL_BGRA, %GL_UNSIGNED_BYTE, pbits)

file_append(sFile, BGRAbuffer)

END FUNCTION


The dark side is that it needs special TBGL window initialization.
I attach for you special version of TBGL, which has alpha by default.

I still need to test how much this pixelformat affects performance and compatibility.


Petr

Macros The Black
25-04-2009, 17:00
i tried the script you posted and no success...
it exports an empty image....
i will keep trying to get it working but for now i am using the first script you posted...

Petr Schreiber
25-04-2009, 17:12
There can be following problems:

I forgot glPixelStoreI and glFinish commands
GL_BGRA might not be supported on your GC, try GL_RGBA


I am sorry, although weekend, I am in hurry, hope it helps,
Petr

Macros The Black
25-04-2009, 17:32
Nah my bad i posted without trying more....
Ended up i was just calling hwnd instead of hdlg...changed it ....problem solved...
thanks for the tips as well..