This commit is contained in:
romkazvo
2023-08-07 19:29:24 +08:00
commit 34d6c5d489
4832 changed files with 1389451 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
#pragma once
#include <d3d9.h>
#include <d3dx9.h>
#include <dxerr9.h>
#include "dds.h" //
#include "IConvertor.h" // IConvertor
#include "Properties.h" // CProperties
struct ImageObject; // forward decl
class CImageCompiler : public IConvertor
{
public:
//! constructor
CImageCompiler();
//! destructor
~CImageCompiler();
//!
bool Init( HWND inhWnd );
//!
void DeInit( void );
//!
bool Load( const char *lpszPathName );
//!
bool Save( const char *lpszPathName );
//! /param indwFilter D3DX_FILTER bitmask (see DirectX documentation): e.g. D3DX_FILTER_POINT|D3DX_FILTER_MIRROR, D3DX_FILTER_TRIANGLE
//! /return
LPDIRECT3DBASETEXTURE9 CreateUncompressedMipMaps( const DWORD indwFilter, const DWORD indwReduceResolution,
const bool inbRemoveMips );
//!
bool Compress( LPDIRECT3DBASETEXTURE9 inSrc, D3DFORMAT fmtTo, const DWORD indwFilter );
//! /param infOffsetX
//! /param infOffsetY
//! /param iniScale16 16=1:1, bigger values magnify more
//! /return true=blit was successful, false otherwise
bool BlitTo( HWND inHWND, RECT &inRect, const float infOffsetX, const float infOffsetY, const int iniScale16, const bool inbOrig );
//! textre for the info below the preview
CString GetInfoString( const bool inbOrig );
//!
//! /return true=x and y is bound to 0.5 because the texture is smaller than the preview area, false otherwise
bool ClampBlitOffset( const int iniWidth, const int iniHeight, float &inoutfX, float &inoutfY, const int iniScale16 ) const;
//!
DWORD GetWidth( void ) const;
//!
DWORD GetHeight( void ) const;
//! run with the user specified user properties in m_Prop
//! /param inbSave true=save the result, false=update only the internal structures for previewing
//! /return true=success, false otherwise(e.g. compression failed because of non power of two)
bool RunWithProperties( const bool inbSave );
//!
static char *GetPixelFormatName( const int iniNo );
//!
static char *GetPixelFormatDesc( const int iniNo );
//!
static int GetPixelFormatCount( void );
//! set the stored properties to the current file and save it
//! @return true=success, false otherwise
bool UpdateAndSaveConfigFile( void );
CString GetSourceFilename( void );
// interface IConvertor ----------------------------------------------------
virtual void Release( void );
virtual bool Process( ConvertContext &cc );
virtual bool GetOutputFile( ConvertContext& cc);
virtual int GetNumPlatforms() const;
virtual Platform GetPlatform( int index ) const;
virtual int GetNumExt() const;
virtual const char* GetExt( int index ) const;
virtual DWORD GetTimestamp() const;
// -------------------------------------------------------------------------
void SetPresetSettings();
CProperties m_Props; //!< user settings
ConvertContext * m_pCC; //!< pointer to the object give to Process (is 0 outside of the call)
private:
D3DPRESENT_PARAMETERS m_presentParams; //!< presentation parameters used on device creation and reset
LPDIRECT3DDEVICE9 m_pd3ddev; //!<
LPDIRECT3D9 m_pd3d; //!<
LPDIRECT3DBASETEXTURE9 m_ptexOrig; //!<
//LPDIRECT3DBASETEXTURE9 m_ptexNew; //!<
//unsigned char * m_pPalette;
ImageObject * m_pNewImage;
int m_iOrigPixelFormatNo; //!<
DWORD m_dwOrigWidth; //!<
DWORD m_dwOrigHeight; //!<
DWORD m_dwDepth; //!< For volume textures
DWORD m_dwCubeMapFlags; //!<
HWND m_hWnd; //!< DirectX needs a window to attach to
//!
bool IsCubeMap( void ) { return (m_dwCubeMapFlags > 0); }
//!
bool IsVolumeMap( void ) { return (m_dwDepth > 0); }
//!
//! /param indwFilter D3DX_FILTER bitmask (see DirectX documentation): e.g. D3DX_FILTER_POINT|D3DX_FILTER_MIRROR, D3DX_FILTER_TRIANGLE
HRESULT ChangeFormat( LPDIRECT3DBASETEXTURE9 ptexCur, D3DFORMAT fmtTo, ImageObject *&pNewImage,
const DWORD indwFilter, const DWORD indwReduceResolution );
//!
//! /param indwFilter D3DX_FILTER bitmask (see DirectX documentation): e.g. D3DX_FILTER_POINT|D3DX_FILTER_MIRROR, D3DX_FILTER_TRIANGLE
HRESULT BltAllLevels( D3DCUBEMAP_FACES FaceType, LPDIRECT3DBASETEXTURE9 ptexSrc, ImageObject *pNewImage,
const DWORD indwFilter, const DWORD indwReduceResolution, D3DFORMAT fmtTo );
//! convert to 8bit paletized texture
HRESULT PaletteQuantize(LPDIRECT3DSURFACE9 psurfSrc, LPDIRECT3DSURFACE9 psurfDest);
//! helper function
bool GetBoolParam( CString insName, const bool inbDefault ) const;
//! helper function
int GetIntParam( CString insName, const int iniDefault ) const;
//!
DWORD CalcTextureMemory( const bool inbOrig ) const;
//! \return pixelformat no which has same properties but is uncompressed
static int GetPixelFormatUncompressed( const int iniNo );
//! not case sensitive
//! /return -1 if the name was not recognized, otherwise no
static int GetNoFromName( const char *inszName );
//! /return -1 if the format was not recognized, otherwise no
static int GetNoFromD3DFormat( D3DFORMAT inFormat );
//! /param psurf has to be in the format A8R8G8B8
bool CopyAlphaToRGB( LPDIRECT3DSURFACE9 psurf ) const;
IDirect3DTexture9 *CopyP8ToXRGB(LPDIRECT3DBASETEXTURE9 texp8);
//!
bool LoadConfigFile( void );
//! /return
static DWORD _CalcMipCount( const DWORD indwWidth, const DWORD indwHeight );
bool IsPowerOfTwo( const DWORD indwValue );
};
#define DXERRORCHECK(cmt,exp) { HRESULT _hr = (exp); /*assert(!_hr);*/ if(_hr) CCLOG->LogError("'%s' DX ERROR: %s", cmt,DXGetErrorString9A(_hr)); }

View File

@@ -0,0 +1,2 @@
EXPORTS
RegisterConvertors @1

View File

@@ -0,0 +1,207 @@
//
#include "stdafx.h"
#include <assert.h> // assert()
#include <Dbghelp.h> // GetTimestampForLoadedLibrary
#include "IRCLog.h" // IRCLog
#include "IConfig.h" // IConfig
#include "PathUtil.h" // ReplaceExtension
#include "ImageCompiler.h" // CImageCompiler
#include "UserDialog.h" // CUserDialog
#include "ICfgFile.h" // ICfgFile
#include <ddraw.h>
#include "neuquant.h"
#include "ImageObject.h"
HRESULT P8Image::Convert(LPDIRECT3DSURFACE9 psurfSrc, int mip, int filter, D3DCUBEMAP_FACES facetype, LPDIRECT3DDEVICE9 pd3ddev)
{
assert(psurfSrc);
D3DSURFACE_DESC sd;
psurfSrc->GetDesc(&sd);
LPDIRECT3DSURFACE9 psurfTarget;
HRESULT hr = pd3ddev->CreateOffscreenPlainSurface(sd.Width, sd.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &psurfTarget, NULL);
if(FAILED(hr)) return hr;
hr = D3DXLoadSurfaceFromSurface(psurfTarget, NULL, NULL, psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
if(FAILED(hr)) return hr;
unsigned char *pic = (unsigned char*)malloc(3*sd.Width*sd.Height+1);
assert(pic);
{
D3DLOCKED_RECT lrTarg;
hr = psurfTarget->LockRect(&lrTarg, NULL, 0);
if(FAILED(hr)) return hr;
DWORD* pdwRowTarg = (DWORD*)lrTarg.pBits;
unsigned char *p = pic;
for (DWORD yp = 0; yp < sd.Height; yp++)
{
DWORD* pdwPtrTarg = pdwRowTarg;
for (DWORD xp = 0; xp < sd.Width; xp++)
{
*((DWORD *)p) = *pdwPtrTarg++; // both use BGR order
p += 3; // quick and dirty: only works correctly on x86 cpus
}
pdwRowTarg += lrTarg.Pitch / 4;
};
psurfTarget->UnlockRect();
};
ReleasePpo(&psurfTarget);
if(!m_pPalette) // FIXME: for now, generate palette based solely on main image, may give better result if mipmaps are taken into account
{
initnet(pic, 3*sd.Width*sd.Height, 1); // can use 1 instead of 10 for gold master :)
learn();
unbiasnet();
m_pPalette = (unsigned char *)malloc(256*3);
writecolourmap(m_pPalette);
inxbuild();
};
{
unsigned char *d = (unsigned char*)malloc(sd.Width*sd.Height);
assert(d);
m_ppIndices[mip] = d;
unsigned char *p = pic;
for (unsigned int yp = 0; yp < sd.Height; yp++)
{
for (unsigned int xp = 0; xp < sd.Width; xp++)
{
*d++ = inxsearch(p[0], p[1], p[2]);
p += 3;
}
};
};
free(pic);
return S_OK;
};
bool P8Image::Save(const char *name)
{
// FIXME: do this extension hacking somewhere else, it is not appropriate here
CString filename = name;
filename.Truncate(filename.GetLength()-4);
filename += ".tga";
FILE *fh = fopen(filename.GetString(), "wb");
if(!fh) return false;
SavePaletizedTextureHeader(fh);
/*
for(unsigned int mip = 0; mip<tex->GetLevelCount(); mip++)
{
LPDIRECT3DSURFACE9 psurf = NULL;
DXERRORCHECK(tex->GetSurfaceLevel(mip, &psurf));
D3DSURFACE_DESC sd;
psurf->GetDesc(&sd);
D3DLOCKED_RECT lr;
DXERRORCHECK(psurf->LockRect(&lr, NULL, 0));
SavePaletizedTextureMip(fh, (unsigned char *)lr.pBits, sd.Width, sd.Height, lr.Pitch, mip);
psurf->UnlockRect();
ReleasePpo(&psurf);
};
*/
fclose(fh);
return true;
};
void P8Image::SavePaletizedTextureHeader(FILE *fh)
{
/*
// DDS P8 appearently not supported
fwrite("DDS ", 4, 1, fh);
DDSURFACEDESC2 sd2 =
{
124,
DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH,
sd.Height,
sd.Width,
(sd.Width+3)&3,
0,
tex->GetLevelCount(),
0,0,0,0,0,0,0,0,0,0,0,
{ 32, DDPF_PALETTEINDEXED8, 0, 8, 0, 0, 0, 0 },
{ DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX, 0, 0, 0 },
0
};
*/
unsigned char tgaheader[] =
{
0, 1, 1,
0, 0, 0, 1,
24,
0, 0, 0, 0,
(m_nWidth & 0x00FF), (m_nWidth & 0xFF00) / 256,
(m_nHeight & 0x00FF), (m_nHeight & 0xFF00) / 256,
8, 0,
};
fwrite(&tgaheader, 18, 1, fh);
fwrite(m_pPalette, 3*256, 1, fh);
};
void P8Image::SavePaletizedTextureMip(FILE *fh, unsigned char *buf, int mip)
{
// if this line is commented, it will save an "extended TGA" with mipmaps following the main picture
//if(mip) return;
for(int y = m_nHeight-1; y>=0; y--)
{
fwrite(buf+y*m_nWidth, 1, m_nWidth, fh);
//if(xs&3) fwrite(" ", 4-(xs&3), 1, fh); // dword align for dds
};
};
IDirect3DTexture9 *P8Image::CopyToXRGB(LPDIRECT3DDEVICE9 pd3ddev)
{
assert(m_pPalette);
IDirect3DTexture9 *ptexNew = NULL;
if(FAILED(pd3ddev->CreateTexture(m_nWidth, m_nHeight, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &ptexNew, NULL))) return NULL;
LPDIRECT3DSURFACE9 psurfd = NULL;
if(FAILED(ptexNew->GetSurfaceLevel(0, &psurfd))) return NULL;
D3DLOCKED_RECT lrd;
if(FAILED(psurfd->LockRect(&lrd, NULL, 0))) return NULL;
for(int y = m_nHeight-1; y>=0; y--)
{
for(int x = 0; x<m_nHeight; x++)
{
int index = *(m_ppIndices[0]+y*m_nWidth+x);
unsigned char *rgb = m_pPalette+index*3;
unsigned char *dest = ((unsigned char *)lrd.pBits)+y*lrd.Pitch+x*4;
dest[0] = rgb[0];
dest[1] = rgb[1];
dest[2] = rgb[2];
dest[3] = 0xFF;
};
};
psurfd->UnlockRect();
ReleasePpo(&psurfd);
return ptexNew;
};

View File

@@ -0,0 +1,113 @@
// ImageObject allows the abstraction of different kinds of
// images generated during conversion
struct ImageObject
{
//! write image to disk, overwrites any existing file
virtual bool Save(const char *filename) = 0;
//! converts the psurfSrc to the native format for this object and stores it as the right mip
virtual HRESULT Convert(LPDIRECT3DSURFACE9 psurfSrc, int mip, int filter, D3DCUBEMAP_FACES facetype, LPDIRECT3DDEVICE9 pd3ddev) = 0;
//! creates a new XRGB texture of this image for images that can't be directly displayed (caller dealocates)
virtual IDirect3DTexture9 *CopyToXRGB(LPDIRECT3DDEVICE9 pd3ddev) { return NULL; };
//! gets the internal DX texture, if the object has one
virtual LPDIRECT3DBASETEXTURE9 GetDXTex() { return NULL; };
virtual void GetDXTexI(IDirect3DTexture9 *&pTexture) { pTexture = NULL; };
//! deallocates all internally held texture objects
virtual ~ImageObject() {};
};
// base DX Image, used for normal textures with mipmaps
struct DXImage : ImageObject
{
LPDIRECT3DBASETEXTURE9 m_pTex;
DXImage(LPDIRECT3DBASETEXTURE9 tex) : m_pTex(tex) {};
~DXImage() { m_pTex->Release(); };
bool Save(const char *filename)
{
return D3DXSaveTextureToFile(filename, D3DXIFF_DDS, m_pTex, NULL)==S_OK;
};
HRESULT Convert(LPDIRECT3DSURFACE9 psurfSrc, int mip, int filter, D3DCUBEMAP_FACES facetype, LPDIRECT3DDEVICE9 pd3ddev)
{
LPDIRECT3DSURFACE9 psurfDest = NULL;
HRESULT hr = ((LPDIRECT3DTEXTURE9)m_pTex)->GetSurfaceLevel(mip, &psurfDest);
if(hr==S_OK) hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, filter, 0);
ReleasePpo(&psurfDest);
return hr;
};
LPDIRECT3DBASETEXTURE9 GetDXTex() { return m_pTex; };
virtual void GetDXTexI(IDirect3DTexture9 *&pTexture) { m_pTex->QueryInterface(IID_IDirect3DTexture9,(void **)&pTexture); };
};
// specialized for cubemaps
struct DXImageCube : DXImage
{
DXImageCube(LPDIRECT3DCUBETEXTURE9 tex) : DXImage(tex) {};
HRESULT Convert(LPDIRECT3DSURFACE9 psurfSrc, int mip, int filter, D3DCUBEMAP_FACES facetype, LPDIRECT3DDEVICE9 pd3ddev)
{
LPDIRECT3DSURFACE9 pcubeDest = NULL;
HRESULT hr = ((LPDIRECT3DCUBETEXTURE9)m_pTex)->GetCubeMapSurface(facetype, mip, &pcubeDest);
if(hr==S_OK) hr = D3DXLoadSurfaceFromSurface(pcubeDest, NULL, NULL, psurfSrc, NULL, NULL, filter, 0);
ReleasePpo(&pcubeDest);
return hr;
};
};
// specialized for volumetric textures
struct DXImageVol : DXImage
{
DXImageVol(LPDIRECT3DVOLUMETEXTURE9 tex) : DXImage(tex) {};
HRESULT Convert(LPDIRECT3DSURFACE9 psurfSrc, int mip, int filter, D3DCUBEMAP_FACES facetype, LPDIRECT3DDEVICE9 pd3ddev)
{
LPDIRECT3DVOLUME9 pvolDest = NULL;
HRESULT hr = ((LPDIRECT3DVOLUMETEXTURE9)m_pTex)->GetVolumeLevel(mip, &pvolDest);
if(hr==S_OK) hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, (LPDIRECT3DVOLUME9)psurfSrc, NULL, NULL, filter, 0);
ReleasePpo(&pvolDest);
return hr;
};
};
// palettized 8 bit image, doesn't use DX internally at all
struct P8Image : ImageObject
{
unsigned char *m_pPalette;
unsigned char **m_ppIndices;
int m_nWidth, m_nHeight, m_nMips;
P8Image(int w, int h, int m) : m_pPalette(NULL), m_nWidth(w), m_nHeight(h), m_nMips(m)
{
m_ppIndices = new unsigned char *[m];
for(int i = 0; i<m_nMips; i++) m_ppIndices[i] = NULL;
};
~P8Image()
{
for(int i = 0; i<m_nMips; i++) if(m_ppIndices[i]) free(m_ppIndices[i]);
delete[] m_ppIndices;
};
bool Save(const char *filename);
void SavePaletizedTextureHeader(FILE *fh);
void SavePaletizedTextureMip(FILE *fh, unsigned char *buf, int mip);
HRESULT Convert(LPDIRECT3DSURFACE9 psurfSrc, int mip, int filter, D3DCUBEMAP_FACES facetype, LPDIRECT3DDEVICE9 pd3ddev);
IDirect3DTexture9 *CopyToXRGB(LPDIRECT3DDEVICE9 pd3ddev);
};

View File

@@ -0,0 +1,34 @@
#pragma once
class CProperties
{
public:
CProperties( void )
{
m_bMipmaps=true;
m_bMipMirror=true;
m_bUserDialog=true;
m_iDestPixelFormat=0;
m_bPreviewAlpha=false;
m_dwReduceResolution=0;
m_bPreviewFiltered=false;
m_bPreviewTiled=true;
m_dwDitherMode=0;
}
// config properties
bool m_bMipmaps; //!< about +1/3 more memoyr
bool m_bMipMirror; //!< for tiled texture (only )
bool m_bUserDialog; //!< show the user dialog for interactive tweaking
int m_iDestPixelFormat; //!< index in the g_pixelformats table [0..GetPixelFormatCount()-1]
DWORD m_dwReduceResolution; //!< [0..[ to remove the top mipmap levels
DWORD m_dwDitherMode; //!< 0:none, 1:simple
CString m_sPreset;
// preview properties
bool m_bPreviewAlpha; //!< replicate the alpha channel as greyscale value
bool m_bPreviewFiltered; //!< activate the bilinear filter in the preview
bool m_bPreviewTiled; //!<
};

View File

@@ -0,0 +1,123 @@
// RelativeMouseInput.cpp: implementation of the CRelativeMouseInput class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RelativeMouseInput.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// constuctor
CRelativeMouseInput::CRelativeMouseInput()
{
m_Captured=false;
}
// destructor
CRelativeMouseInput::~CRelativeMouseInput()
{
}
void CRelativeMouseInput::OnButtonDown( HWND inHwnd ) // call in OnLButtonDown/OnMButtonDown/OnRButtonDown
{
if(!m_Captured)
{
SetCapture(inHwnd);m_Captured=true;
GetCursorPos(&m_savedpos);
int midx=GetSystemMetrics(SM_CXSCREEN)/2;
int midy=GetSystemMetrics(SM_CYSCREEN)/2;
SetCursorPos(midx,midy);m_oldx=midx;m_oldy=midy;
ShowCursor(false);
}
}
void CRelativeMouseInput::OnButtonUp( void ) // call in OnLButtonUp/OnMButtonUp/OnRButtonUp
{
if(m_Captured)
{
SetCursorPos(m_savedpos.x,m_savedpos.y);
ShowCursor(true);
m_Captured=false;
ReleaseCapture();
}
}
bool CRelativeMouseInput::OnMouseMove( HWND inHwnd, bool inbButtonDown, int &outRelx, int &outRely ) // call in OnMouseMove
{
outRelx=0;outRely=0;
if(m_Captured)
{
if(!inbButtonDown)OnButtonUp();
}
else
{
if(inbButtonDown)OnButtonDown(inHwnd);
}
if(m_Captured)
{
POINT point;
GetCursorPos(&point);
int midx=GetSystemMetrics(SM_CXSCREEN)/2;
int midy=GetSystemMetrics(SM_CYSCREEN)/2;
int relx=point.x-m_oldx;
int rely=point.y-m_oldy;
int absx=point.x-midx;
int absy=point.y-midy;
// GetDC()->SetPixel(relx+300,rely+200,0x000000);
outRelx=relx;
outRely=rely;
bool reset=false;
if(absx<-200){ reset=true;absx+=200; }
if(absx>200){ reset=true;absx-=200; }
if(absy<-200){ reset=true;absy+=200; }
if(absy>200){ reset=true;absy-=200; }
if(reset)
{
SetCursorPos(midx+absx,midy+absy);
m_oldx=midx+absx;m_oldy=midy+absy;
}
else
{
m_oldx=point.x;m_oldy=point.y;
}
if(outRelx==0 && outRely==0)return(false);
return(true);
}
else return(false);
}
bool CRelativeMouseInput::IsCaptured( void )
{
return(m_Captured);
}

View File

@@ -0,0 +1,42 @@
// RelativeMouseInput.h: interface for the CRelativeMouseInput class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_RELATIVEMOUSEINPUT_H__FB763154_32E5_4857_B51E_C7EB1F946812__INCLUDED_)
#define AFX_RELATIVEMOUSEINPUT_H__FB763154_32E5_4857_B51E_C7EB1F946812__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// hides the mouse cursor,
// returns relative mouse movement
class CRelativeMouseInput
{
public:
//! constructor
CRelativeMouseInput( void );
//! destructor
virtual ~CRelativeMouseInput( void );
//! call in OnLButtonDown/OnMButtonDown/OnRButtonDown
void OnButtonDown( HWND inHwnd );
//! call in OnLButtonUp/OnMButtonUp/OnRButtonUp
void OnButtonUp( void );
//! call in OnMouseMove
//! return true=mouse is captured an there was movement, false otherwise
bool OnMouseMove( HWND inHwnd, bool inbButtonDown, int &outRelx, int &outRely );
//!
bool IsCaptured( void );
private:
bool m_Captured; //!<
int m_oldx; //!<
int m_oldy; //!<
POINT m_savedpos; //!<
};
#endif // !defined(AFX_RELATIVEMOUSEINPUT_H__FB763154_32E5_4857_B51E_C7EB1F946812__INCLUDED_)

View File

@@ -0,0 +1,40 @@
// ResourceCompilerImage.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <assert.h>
#include "ResourceCompilerImage.h"
#include "IResCompiler.h"
#include "ImageCompiler.h" // CImageCompiler
HMODULE g_hInst;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = (HMODULE)hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported function.
void __stdcall RegisterConvertors( IResourceCompiler *pRC )
{
CImageCompiler *pImageComp=new CImageCompiler();
pImageComp->Init(pRC->GetEmptyWindow());
pRC->RegisterConvertor(pImageComp);
}

View File

@@ -0,0 +1,13 @@
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the RESOURCECOMPILERIMAGE_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// RESOURCECOMPILERIMAGE_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef RESOURCECOMPILERIMAGE_EXPORTS
#define RESOURCECOMPILERIMAGE_API __declspec(dllexport)
#else
#define RESOURCECOMPILERIMAGE_API __declspec(dllimport)
#endif

View File

@@ -0,0 +1,150 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_TAB_SAVEFORMAT DIALOGEX 0, 0, 308, 55
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
EXSTYLE WS_EX_TRANSPARENT
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
COMBOBOX IDC_PIXELFORMAT,4,10,69,230,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Static",IDC_PIXELFORMATDESC,76,8,226,18
LTEXT "Pixelformat:",IDC_STATIC,5,2,40,8
COMBOBOX IDC_MIPMAPS,4,35,69,230,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
LTEXT "Mipmaps:",IDC_STATIC,6,27,31,8
COMBOBOX IDC_REDUCERES,80,35,69,230,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
LTEXT "Reduce Resolution:",IDC_STATIC,82,27,63,8
COMBOBOX IDC_DITHERMODE,156,35,69,230,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Dithering:",IDC_STATIC,157,27,32,8
END
IDD_TAB_NORMALMAPGEN DIALOGEX 0, 0, 285, 42
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
EXSTYLE WS_EX_TRANSPARENT
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
COMBOBOX IDC_NM_FILTERTYPE,4,4,78,30,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
END
IDD_USERDIALOG DIALOGEX 0, 0, 347, 348
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,229,328,50,14
PUSHBUTTON "Cancel",IDCANCEL,291,328,50,14
CONTROL "Show UserDialog next time",IDC_SHOWUSERDIALOG,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,330,102,10
LTEXT "Static",IDC_LEFTPREVIEWINFO,2,158,165,16
LTEXT "Static",IDC_RIGHTPREVIEWINFO,178,158,165,16
GROUPBOX "Preset (Current template preset file is defined in rc.ini)",
IDC_STATIC,6,201,335,27
COMBOBOX IDC_TEMPLATECOMBO,11,210,148,230,CBS_DROPDOWNLIST |
WS_VSCROLL
PUSHBUTTON "Zoom In",IDC_ZOOMIN,11,179,39,11
PUSHBUTTON "Zoom Out",IDC_ZOOMOUT,52,179,39,11
CONTROL "Preview Alpha",IDC_PREVIEWALPHA,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,96,180,61,10
CONTROL "Bilinear Filter",IDC_PREVIEWFILTERED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,163,180,57,10
CONTROL "Tiled",IDC_PREVIEWTILED,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,224,180,31,10
CONTROL "",IDC_PROPTAB,"SysTabControl32",0x0,7,233,334,83
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_TAB_SAVEFORMAT, DIALOG
BEGIN
RIGHTMARGIN, 302
END
IDD_TAB_NORMALMAPGEN, DIALOG
BEGIN
RIGHTMARGIN, 278
END
IDD_USERDIALOG, DIALOG
BEGIN
HORZGUIDE, 166
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,43 @@
Microsoft Visual Studio Solution File, Format Version 7.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResourceCompilerImage", "ResourceCompilerImage.vcproj", "{D14A0696-91EE-4B82-A07C-895871E9DE13}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResourceCompiler", "..\ResourceCompiler\ResourceCompiler.vcproj", "{2F21D2A8-925B-4A73-A32B-D111580614C3}"
EndProject
Global
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 3
SccProjectUniqueName0 = ..\\ResourceCompiler\\ResourceCompiler.vcproj
SccProjectName0 = \u0022$/Tools\u0022,\u0020UPQBAAAA
SccLocalPath0 = ..
CanCheckoutShared = false
SccProjectFilePathRelativizedFromConnection0 = ResourceCompiler\\
SccProjectName1 = \u0022$/Tools/ResourceCompilerImage\u0022,\u0020IQYBAAAA
SccLocalPath1 = .
SccProvider1 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
CanCheckoutShared = false
SolutionUniqueID = {24EA7B82-80F7-44C1-91EF-EAC2382F4C8C}
SccProjectUniqueName2 = ResourceCompilerImage.vcproj
SccLocalPath2 = .
CanCheckoutShared = false
EndGlobalSection
GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug
ConfigName.1 = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{D14A0696-91EE-4B82-A07C-895871E9DE13}.Debug.ActiveCfg = Debug|Win32
{D14A0696-91EE-4B82-A07C-895871E9DE13}.Debug.Build.0 = Debug|Win32
{D14A0696-91EE-4B82-A07C-895871E9DE13}.Release.ActiveCfg = Release|Win32
{D14A0696-91EE-4B82-A07C-895871E9DE13}.Release.Build.0 = Release|Win32
{2F21D2A8-925B-4A73-A32B-D111580614C3}.Debug.ActiveCfg = Debug|Win32
{2F21D2A8-925B-4A73-A32B-D111580614C3}.Debug.Build.0 = Debug|Win32
{2F21D2A8-925B-4A73-A32B-D111580614C3}.Release.ActiveCfg = Release|Win32
{2F21D2A8-925B-4A73-A32B-D111580614C3}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,227 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="ResourceCompilerImage"
ProjectGUID="{D14A0696-91EE-4B82-A07C-895871E9DE13}"
SccProjectName="&quot;$/Tools/ResourceCompilerImage&quot;, IQYBAAAA"
SccAuxPath=""
SccLocalPath="."
SccProvider="MSSCCI:Microsoft Visual SourceSafe"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="C:\masterCD"
IntermediateDirectory="Debug"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\ResourceCompiler,..\CryCommon"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;RESOURCECOMPILERIMAGE_EXPORTS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dxerr9.lib dbghelp.lib d3d9.lib d3dx9dt.lib dxguid.lib version.lib"
OutputFile="c:\mastercd\ResourceCompilerImage.dll"
LinkIncremental="2"
ModuleDefinitionFile="ImageExports.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/ResourceCompilerImage.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/ResourceCompilerImage.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="C:\masterCD"
IntermediateDirectory="Release"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="TRUE"
AdditionalIncludeDirectories="..\ResourceCompiler,..\CryCommon"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;RESOURCECOMPILERIMAGE_EXPORTS"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dxerr9.lib dbghelp.lib d3d9.lib d3dx9dt.lib dxguid.lib version.lib"
OutputFile="c:\mastercd\ResourceCompilerImage.dll"
LinkIncremental="1"
ModuleDefinitionFile="ImageExports.def"
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/ResourceCompilerImage.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
<File
RelativePath="ImageCompiler.cpp">
</File>
<File
RelativePath="ImageExports.def">
</File>
<File
RelativePath="ImageObject.cpp">
</File>
<File
RelativePath="neuquant.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="RelativeMouseInput.cpp">
</File>
<File
RelativePath="ResourceCompilerImage.cpp">
</File>
<File
RelativePath="stdafx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
<File
RelativePath="UserDialog.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc">
<File
RelativePath="dds.h">
</File>
<File
RelativePath="ImageCompiler.h">
</File>
<File
RelativePath="ImageObject.h">
</File>
<File
RelativePath="neuquant.h">
</File>
<File
RelativePath="Properties.h">
</File>
<File
RelativePath="RelativeMouseInput.h">
</File>
<File
RelativePath="ResourceCompilerImage.h">
</File>
<File
RelativePath="stdafx.h">
</File>
<File
RelativePath="UserDialog.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
<File
RelativePath="resource.h">
</File>
<File
RelativePath="ResourceCompilerImage.rc">
</File>
</Filter>
<File
RelativePath="readme.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
}

View File

@@ -0,0 +1,674 @@
#include "StdAfx.h"
#include "userdialog.h" // CUserDialog
#include "resource.h" // IDD_ ...
#include <assert.h> // assert()
#include "ImageCompiler.h" // CImageCompiler
#include "RelativeMouseInput.h" // CRelativeMouseInput
#include <windowsx.h> // ComboBox_GetCurSel
#include <commctrl.h> // TCITEM
#include <vector>
#include "ICfgFile.h"
// Class name for this application's window class.
#define WINDOW_CLASSNAME "UserDialog"
// constructor
CUserDialog::CUserDialog( void ) :m_iPreviewWidth(256), m_iPreviewHeight(256)
{
m_pImageCompiler=0;
m_fShiftX=0.5f;m_fShiftY=0.5f;
m_iScale16=16;
m_hTab_Normalmapgen=0;
m_hTab_Saveformat=0;
m_hWindow=0;
}
// destructor
CUserDialog::~CUserDialog( void )
{
assert(!m_pImageCompiler); // should be 0 outside of DoModal call
}
//****************************************************************************
// // FUNCTION: CenterWindow (HWND, HWND)
// // PURPOSE: Center one window over another
// // COMMENTS:
// // Dialog boxes take on the screen position that they were designed at,
// which is not always appropriate. Centering the dialog over a particular
// window usually results in a better position.
// //***************************************************************************
void CenterWindow( HWND hwndChild, HWND hwndParent=0 )
{
RECT rChild, rParent;
int wChild, hChild, wParent, hParent;
int wScreen, hScreen, xNew, yNew;
HDC hdc;
// Get the Height and Width of the child window
GetWindowRect (hwndChild, &rChild);
wChild = rChild.right - rChild.left;
hChild = rChild.bottom - rChild.top;
// Get the display limits
hdc = GetDC (hwndChild);
wScreen = GetDeviceCaps (hdc, HORZRES);
hScreen = GetDeviceCaps (hdc, VERTRES);
ReleaseDC (hwndChild, hdc);
// Get the Height and Width of the parent window
if(hwndParent)
{
GetWindowRect (hwndParent, &rParent);
wParent = rParent.right - rParent.left;
hParent = rParent.bottom - rParent.top;
}
else // 0 means it's the screen
{
wParent = wScreen;
hParent = hScreen;
rParent.left=0;
rParent.top=0;
}
// Calculate new X position, then adjust for screen
xNew = rParent.left + ((wParent - wChild) /2);
if(xNew<0) xNew = 0;
else if((xNew+wChild)>wScreen)
xNew = wScreen - wChild;
// Calculate new Y position, then adjust for screen
yNew = rParent.top + ((hParent - hChild) /2);
if(yNew<0) yNew = 0;
else if((yNew+hChild)>hScreen) yNew = hScreen - hChild;
// Set it, and return
// SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
MoveWindow(hwndChild, xNew, yNew, wChild, hChild, TRUE);
}
bool CUserDialog::DoModal( CImageCompiler *inpImageCompiler )
{
m_pImageCompiler=inpImageCompiler;
m_fShiftX=0.5f;
m_fShiftY=0.5f;
m_iScale16=16; // 1:1
// zoom out if image is too big
{
int iTexWidth=(int)m_pImageCompiler->GetWidth(), iTexHeight=(int)m_pImageCompiler->GetHeight();
while((iTexWidth>256 || iTexHeight>256) && m_iScale16!=1)
{
iTexWidth>>=1;
iTexHeight>>=1;
m_iScale16>>=1;
}
}
m_hWindow=CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_USERDIALOG),0,CUserDialog::WndProc);
if( !m_hWindow )
{
DWORD h=GetLastError();
m_pImageCompiler=0;
return(false);
}
// store this pointer
SetWindowLongPtr(m_hWindow,DWL_USER,(LONG)(LONG_PTR)this);
// CenterWindow(m_hWindow); // here I can't see my tab items
CreateDialogItems();
CenterWindow(m_hWindow); // here it's moving
SetDataToDialog();
UpdateWindowTitle();
UpdatePreview(); // call after IDC_PIXELFORMAT is created and image conversion is done
ShowWindow(m_hWindow,SW_SHOW);
// message loop
{
MSG Msg;
while(GetMessage(&Msg, NULL, 0, WM_USER))
{
if (WM_CLOSE == Msg.message) break;
else
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
DestroyWindow(m_hWindow);
m_hWindow=0;
m_pImageCompiler=0;
return(true);
}
void CUserDialog::CreateDialogItems( void )
{
// tab control
{
HWND hwnd=GetDlgItem(m_hWindow,IDC_PROPTAB);assert(hwnd);
TCITEM tie;
RECT wnp;
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
tie.pszText = "Normalmap";
TabCtrl_InsertItem(hwnd,0,&tie);
tie.pszText = "File Output";
TabCtrl_InsertItem(hwnd,1,&tie);
TabCtrl_SetCurSel(hwnd,1);
GetWindowRect(hwnd,&wnp);
// sub windows
m_hTab_Normalmapgen=CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_TAB_NORMALMAPGEN),m_hWindow,CUserDialog::WndProcRedirect);assert(m_hTab_Normalmapgen);
SetWindowPos(m_hTab_Normalmapgen, HWND_TOP, wnp.left, wnp.top, 0,0,SWP_NOSIZE);
m_hTab_Saveformat=CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_TAB_SAVEFORMAT),m_hWindow,CUserDialog::WndProcRedirect); assert(m_hTab_Saveformat);
SetWindowPos(m_hTab_Saveformat, HWND_TOP, wnp.left, wnp.top, 0,0,SWP_NOSIZE);
// make dialog visible and set right tab
SetPropertyTab(1);
}
// templates
{
HWND hwnd=GetDlgItem(m_hWindow,IDC_TEMPLATECOMBO);assert(hwnd);
// Baustelle
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"<CUSTOM>");
for(int i = 1;; i++)
{
const char *name = m_pImageCompiler->m_pCC->presets->GetSectionName(i);
if(!name) break;
SendMessage(hwnd, CB_ADDSTRING, 0,(LPARAM)name);
};
/*
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"Skybox");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"Normalmap_low");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"Normalmap_high");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"Texture_low");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"Texture_high");
*/
SendMessage(hwnd,CB_SETCURSEL,0,0); // first 0 is setting the used template
}
// pixelformats
{
HWND hwnd=GetDlgItem(m_hTab_Saveformat,IDC_PIXELFORMAT);assert(hwnd);
CString sEntry;
int iCount=m_pImageCompiler->GetPixelFormatCount();
for(int i=0;i<iCount;i++)
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)m_pImageCompiler->GetPixelFormatName(i));
UpdatePixelFormatDesc();
}
// mipmaps
{
HWND hwnd=GetDlgItem(m_hTab_Saveformat,IDC_MIPMAPS);assert(hwnd);
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"max(1)");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"none(0)");
}
// reduce resolution
{
HWND hwnd=GetDlgItem(m_hTab_Saveformat,IDC_REDUCERES);assert(hwnd);
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"none");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"1 (1/4 memory)");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"2 (1/16 memory)");
}
// dither mode
{
HWND hwnd=GetDlgItem(m_hTab_Saveformat,IDC_DITHERMODE);assert(hwnd);
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"none(0)");
SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"simple(1)");
}
}
void CUserDialog::SetDataToDialog( void )
{
HWND hwnd;
bool isnotpreset = m_pImageCompiler->m_Props.m_sPreset=="";
// preview part in main window
hwnd=GetDlgItem(m_hWindow,IDC_PREVIEWALPHA);assert(hwnd);
Button_SetCheck(hwnd,m_pImageCompiler->m_Props.m_bPreviewAlpha?1:0);
hwnd=GetDlgItem(m_hWindow,IDC_PREVIEWFILTERED);assert(hwnd);
Button_SetCheck(hwnd,m_pImageCompiler->m_Props.m_bPreviewFiltered?1:0);
hwnd=GetDlgItem(m_hWindow,IDC_PREVIEWTILED);assert(hwnd);
Button_SetCheck(hwnd,m_pImageCompiler->m_Props.m_bPreviewTiled?1:0);
// main window:
hwnd=GetDlgItem(m_hWindow,IDC_SHOWUSERDIALOG);assert(hwnd);
Button_SetCheck(hwnd,m_pImageCompiler->m_Props.m_bUserDialog?1:0);
EnableWindow(hwnd, isnotpreset);
hwnd=GetDlgItem(m_hWindow,IDC_TEMPLATECOMBO);assert(hwnd);
SendMessage(hwnd,CB_SETCURSEL,m_pImageCompiler->m_pCC->presets->Find(m_pImageCompiler->m_Props.m_sPreset),0);
// sub window: save format
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_DITHERMODE);assert(hwnd);
SendMessage(hwnd,CB_SETCURSEL,m_pImageCompiler->m_Props.m_dwDitherMode,0);
EnableWindow(hwnd, isnotpreset);
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_MIPMAPS);assert(hwnd);
SendMessage(hwnd,CB_SETCURSEL,m_pImageCompiler->m_Props.m_bMipmaps?0:1,0);
EnableWindow(hwnd, isnotpreset);
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_REDUCERES);assert(hwnd);
SendMessage(hwnd,CB_SETCURSEL,m_pImageCompiler->m_Props.m_dwReduceResolution,0);
EnableWindow(hwnd, isnotpreset);
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_PIXELFORMAT);assert(hwnd);
SendMessage(hwnd,CB_SETCURSEL,m_pImageCompiler->m_Props.m_iDestPixelFormat,0);
EnableWindow(hwnd, isnotpreset);
}
void CUserDialog::GetDataFromDialog( void )
{
HWND hwnd;
// preview part in main window
hwnd=GetDlgItem(m_hWindow,IDC_PREVIEWALPHA);assert(hwnd);
m_pImageCompiler->m_Props.m_bPreviewAlpha=Button_GetCheck(hwnd)!=0;
hwnd=GetDlgItem(m_hWindow,IDC_PREVIEWFILTERED);assert(hwnd);
m_pImageCompiler->m_Props.m_bPreviewFiltered=Button_GetCheck(hwnd)!=0;
hwnd=GetDlgItem(m_hWindow,IDC_PREVIEWTILED);assert(hwnd);
m_pImageCompiler->m_Props.m_bPreviewTiled=Button_GetCheck(hwnd)!=0;
// main window:
hwnd=GetDlgItem(m_hWindow,IDC_SHOWUSERDIALOG);assert(hwnd);
m_pImageCompiler->m_Props.m_bUserDialog=Button_GetCheck(hwnd)!=0;
hwnd=GetDlgItem(m_hWindow,IDC_TEMPLATECOMBO);assert(hwnd);
const char *pname = m_pImageCompiler->m_pCC->presets->GetSectionName(ComboBox_GetCurSel(hwnd));
m_pImageCompiler->m_Props.m_sPreset = pname ? pname : "";
// sub window: save format
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_PIXELFORMAT);assert(hwnd);
m_pImageCompiler->m_Props.m_iDestPixelFormat=ComboBox_GetCurSel(hwnd);
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_MIPMAPS);assert(hwnd);
m_pImageCompiler->m_Props.m_bMipmaps=(ComboBox_GetCurSel(hwnd)==0);
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_REDUCERES);assert(hwnd);
m_pImageCompiler->m_Props.m_dwReduceResolution=ComboBox_GetCurSel(hwnd);
hwnd=GetDlgItem(m_hTab_Saveformat,IDC_DITHERMODE);assert(hwnd);
m_pImageCompiler->m_Props.m_dwDitherMode=ComboBox_GetCurSel(hwnd);
m_pImageCompiler->SetPresetSettings();
}
void CUserDialog::UpdateWindowTitle( void )
{
assert(m_pImageCompiler);
CString Zoom; Zoom.Format(" Zoom:%d%%",(100*m_iScale16)/16);
CString title=m_pImageCompiler->GetSourceFilename() + Zoom;
SetWindowText(m_hWindow,title.GetBuffer());
}
//
void CUserDialog::Draw( HDC inHdc )
{
int iGap=4;
int iTexWidth=(int)m_pImageCompiler->GetWidth();
int iTexHeight=(int)m_pImageCompiler->GetHeight();
RECT rec;
rec.left=0;
rec.top=0;
rec.right=rec.left+m_iPreviewWidth;
rec.bottom=rec.top+m_iPreviewHeight;
// left side = original
assert(m_pImageCompiler);
if(!m_pImageCompiler->BlitTo(m_hWindow,rec,m_fShiftX,m_fShiftY,m_iScale16,true))
FillRect(inHdc,&rec,GetSysColorBrush(COLOR_3DFACE));
rec.left=m_iPreviewWidth+iGap*2+1;
rec.right=rec.left+m_iPreviewWidth;
// right side = destination
assert(m_pImageCompiler);
if(!m_pImageCompiler->BlitTo(m_hWindow,rec,m_fShiftX,m_fShiftY,m_iScale16,false))
FillRect(inHdc,&rec,GetSysColorBrush(COLOR_3DFACE));
}
void CUserDialog::MouseMessage( const DWORD indwButtons, const int iniRelX , const int iniRelY, int iniRelZ )
{
assert(m_pImageCompiler);
int iWidth=(int)m_pImageCompiler->GetWidth(),iHeight=(int)m_pImageCompiler->GetHeight();
float fOldShiftX=m_fShiftX,fOldShiftY=m_fShiftY;
int iOldScale16=m_iScale16;
m_fShiftX-=iniRelX*(16.0f/m_iScale16/iWidth);
m_fShiftY-=iniRelY*(16.0f/m_iScale16/iHeight);
while(iniRelZ)
{
if(iniRelZ>0)
{
m_iScale16/=2;
iniRelZ-=WHEEL_DELTA;
}
else
{
m_iScale16*=2;
iniRelZ+=WHEEL_DELTA;
}
}
if(m_iScale16<4) m_iScale16=4;
if(m_iScale16>16*16) m_iScale16=16*16;
bool bNoMovementPossible = m_pImageCompiler->ClampBlitOffset(m_iPreviewWidth,m_iPreviewHeight,m_fShiftX,m_fShiftY,m_iScale16);
if(fOldShiftX!=m_fShiftX || fOldShiftY!=m_fShiftY || iOldScale16!=m_iScale16)
{
UpdateWindowTitle(); // Zoom:%d
RECT rect;
GetClientRect(m_hWindow,&rect);
rect.bottom=m_iPreviewHeight;
// update window
InvalidateRect(m_hWindow,&rect,bNoMovementPossible);
UpdateWindow(m_hWindow);
}
}
void CUserDialog::UpdatePixelFormatDesc( void )
{
HWND hwnds=GetDlgItem(m_hTab_Saveformat,IDC_PIXELFORMATDESC); assert(hwnds);
SetWindowText(hwnds,m_pImageCompiler->GetPixelFormatDesc(m_pImageCompiler->m_Props.m_iDestPixelFormat));
}
void CUserDialog::UpdatePreview( void )
{
// preview images
{
RECT rect;
GetClientRect(m_hWindow,&rect);
rect.bottom=m_iPreviewHeight;
// do image conversion
if(m_pImageCompiler->RunWithProperties(false))
InvalidateRect(m_hWindow,&rect,false); // don't erase background
else
InvalidateRect(m_hWindow,&rect,true); // erase background
}
// info text
{
HWND hwndc=GetDlgItem(m_hTab_Saveformat,IDC_PIXELFORMAT); assert(hwndc);
int iNo=ComboBox_GetCurSel(hwndc);
CString sLeftInfo=m_pImageCompiler->GetInfoString(true);
CString sRightInfo=m_pImageCompiler->GetInfoString(false);
HWND hwnd1=GetDlgItem(m_hWindow,IDC_LEFTPREVIEWINFO); assert(hwnd1);
HWND hwnd2=GetDlgItem(m_hWindow,IDC_RIGHTPREVIEWINFO); assert(hwnd2);
SetWindowText(hwnd1,sLeftInfo.GetBuffer());
SetWindowText(hwnd2,sRightInfo.GetBuffer());
}
}
void CUserDialog::SetPropertyTab( const int iniNo )
{
assert(iniNo>=0 && iniNo<=1);
assert(m_hTab_Normalmapgen);
assert(m_hTab_Saveformat);
ShowWindow(m_hTab_Normalmapgen,iniNo==0 ? SW_SHOW:SW_HIDE);
ShowWindow(m_hTab_Saveformat,iniNo==1 ? SW_SHOW:SW_HIDE);
}
/*
//-----------------------------------------------------------------------------
// Name: WndProc()
// Desc: Static msg handler which passes messages to the application class.
//-----------------------------------------------------------------------------
LRESULT CALLBACK CUserDialog::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
*/
// WndProc vom Treiber auswahl Dialog
BOOL CALLBACK CUserDialog::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
CUserDialog *This=(CUserDialog *)(LONG_PTR)GetWindowLongPtr(hWnd,DWL_USER);
switch(uMsg)
{
case WM_NOTIFY:
{
WORD wID=LOWORD(wParam);
switch(wID)
{
case IDC_PROPTAB:
{
HWND hwnd=GetDlgItem(hWnd,IDC_PROPTAB); assert(hwnd);
int iPage = TabCtrl_GetCurSel(hwnd);
This->SetPropertyTab(iPage);
}
return(TRUE);
}
}
return(FALSE);
case WM_COMMAND: //
{
WORD wID=LOWORD(wParam);
switch(wID)
{
case IDOK:
This->GetDataFromDialog();
This->m_pImageCompiler->RunWithProperties(true);
if(!This->m_pImageCompiler->UpdateAndSaveConfigFile())
MessageBox(0,"Error while saving the config file (write protected?)","ResourceCompiler Image Error",MB_OK);
SendMessage(hWnd,WM_CLOSE,0,0);
return(TRUE);
case IDCANCEL:
PostQuitMessage(0);
return(TRUE);
case IDC_ZOOMIN:
This->MouseMessage(0,0,0,-WHEEL_DELTA);
return(TRUE);
case IDC_ZOOMOUT:
This->MouseMessage(0,0,0,WHEEL_DELTA);
return(TRUE);
case IDC_TEMPLATECOMBO:
case IDC_DITHERMODE: // dithering mode has changed
case IDC_REDUCERES: // reduce resolution has changed
case IDC_MIPMAPS: // mipmaps has changed
case IDC_PIXELFORMAT: // pixelformat has changed
if(HIWORD(wParam)==CBN_SELCHANGE)
{
This->GetDataFromDialog();
This->UpdatePixelFormatDesc();
This->SetDataToDialog();
This->UpdatePreview();
UpdateWindow(This->m_hWindow);
}
return(TRUE);
case IDC_PREVIEWALPHA:
case IDC_PREVIEWTILED:
case IDC_PREVIEWFILTERED:
{
This->GetDataFromDialog();
This->UpdatePreview();
UpdateWindow(This->m_hWindow);
}
return(TRUE);
}
}
return(TRUE);
case WM_PAINT: //
{
assert(This); if(!This)return(FALSE);
PAINTSTRUCT ps;
HDC hdc = BeginPaint (hWnd, &ps);
This->Draw(hdc); //,ps.rcPaint);
// This->Draw(hdc,rChild.right-rChild.left,rChild.bottom-rChild.top); //,ps.rcPaint);
EndPaint (hWnd, &ps);
}
return(TRUE);
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
{
assert(This); if(!This)return(FALSE);
int iY=(int)HIWORD(lParam);
if(iY<=This->m_iPreviewHeight)
{
This->m_RelMouse.OnButtonDown(hWnd);
SetFocus(This->m_hWindow);
}
}
return(TRUE);
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
{
assert(This); if(!This)return(FALSE);
if(wParam==0)
This->m_RelMouse.OnButtonUp();
}
return(TRUE);
case WM_MOUSEMOVE:
{
assert(This); if(!This)return(FALSE);
bool bButtonDown=(wParam&MK_LBUTTON)!=0 || (wParam&MK_MBUTTON)!=0 || (wParam&MK_RBUTTON)!=0;
int iY=(int)HIWORD(lParam);
if(iY<=This->m_iPreviewHeight || This->m_RelMouse.IsCaptured())
{
int relX,relY;
This->m_RelMouse.OnMouseMove(hWnd,bButtonDown,relX,relY);
This->MouseMessage((DWORD)wParam,relX,relY,0);
}
}
return(TRUE);
case WM_MOUSEWHEEL:
{
assert(This); if(!This)return(FALSE);
int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
This->MouseMessage(0,0,0,-zDelta);
}
return(TRUE);
case WM_CLOSE:
PostQuitMessage(0);
return (TRUE);
// case WM_ERASEBKGND: //
// return(TRUE);
}
// return DefWindowProc( hWnd, uMsg, wParam, lParam );
return(FALSE);
}
// redirect to the parent window
BOOL CALLBACK CUserDialog::WndProcRedirect( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
HWND hParent=GetParent(hWnd);
if(hParent)
return(SendMessage(hParent,uMsg,wParam,lParam)!=0?TRUE:FALSE);
// return DefWindowProc( hWnd, uMsg, wParam, lParam );
return(FALSE);
}

View File

@@ -0,0 +1,66 @@
#pragma once
class CImageCompiler;
#include "RelativeMouseInput.h" // CRelativeMouseInput
class CUserDialog
{
public:
//! constructor
CUserDialog( void );
//! destructor
virtual ~CUserDialog( void );
//!
bool DoModal( CImageCompiler *inpImageCompiler );
// ---------------------------------------------------------------------------------------
private:
CImageCompiler * m_pImageCompiler; //!<
float m_fShiftX; //!< in texture coordinates [0..1] initially 0.5
float m_fShiftY; //!< in texture coordinates [0..1] initially 0.5
int m_iScale16; //!< 16 is the default
HWND m_hWindow; //!< main window handle
// sub windows (in the tab control)
HWND m_hTab_Normalmapgen;//!< window handle
HWND m_hTab_Saveformat; //!< window handle
const int m_iPreviewWidth; //!<
const int m_iPreviewHeight; //!<
CRelativeMouseInput m_RelMouse; //!< for relative mouse movement
//!
static BOOL CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
//! redirect to the parent window
static BOOL CALLBACK WndProcRedirect( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
//!
void Draw( HDC inHdc );
//!
void MouseMessage( const DWORD indwButtons, const int iniRelX , const int iniRelY, int iniRelZ );
//!
void UpdateWindowTitle( void );
void UpdatePixelFormatDesc( void );
void UpdatePreview( void );
void CreateDialogItems( void );
void GetDataFromDialog( void );
//! makes the dialog visible too
void SetDataToDialog( void );
void SetPropertyTab( const int iniNo );
};

100
ResourceCompilerImage/dds.h Normal file
View File

@@ -0,0 +1,100 @@
// dds.h (from DirectX DXTex)
//
// This header defines constants and structures that are useful when parsing
// DDS files. DDS files were originally designed to use several structures
// and constants that are native to DirectDraw and are defined in ddraw.h,
// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar
// (compatible) constants and structures so that one can use DDS files
// without needing to include ddraw.h.
#ifndef _DDS_H_
#define _DDS_H_
struct DDS_PIXELFORMAT
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwFourCC;
DWORD dwRGBBitCount;
DWORD dwRBitMask;
DWORD dwGBitMask;
DWORD dwBBitMask;
DWORD dwABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS
const DDS_PIXELFORMAT DDSPF_DXT1 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT2 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT3 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT4 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_DXT5 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 };
const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };
const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };
const DDS_PIXELFORMAT DDSPF_R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
const DDS_PIXELFORMAT DDSPF_R5G6B5 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };
#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT
#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH
#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE
#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME
struct DDS_HEADER
{
DWORD dwSize;
DWORD dwHeaderFlags;
DWORD dwHeight;
DWORD dwWidth;
DWORD dwPitchOrLinearSize;
DWORD dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags
DWORD dwMipMapCount;
DWORD dwReserved1[11];
DDS_PIXELFORMAT ddspf;
DWORD dwSurfaceFlags;
DWORD dwCubemapFlags;
DWORD dwReserved2[3];
};
#endif

View File

@@ -0,0 +1,396 @@
// WOUTER
// - made it compile as C++
// - fixed /0 bug with small image sizes
/* NeuQuant Neural-Net Quantization Algorithm
* ------------------------------------------
*
* Copyright (c) 1994 Anthony Dekker
*
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
* See "Kohonen neural networks for optimal colour quantization"
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
* for a discussion of the algorithm.
* See also http://www.acm.org/~dekker/NEUQUANT.HTML
*
* Any party obtaining a copy of these files from the author, directly or
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
* in this software and documentation files (the "Software"), including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons who receive
* copies from any such party to do so, with the only requirement being
* that this copyright notice remain intact.
*/
#include "neuquant.h"
#include <assert.h>
/* Network Definitions
------------------- */
#define maxnetpos (netsize-1)
#define netbiasshift 4 /* bias for colour values */
#define ncycles 100 /* no. of learning cycles */
/* defs for freq and bias */
#define intbiasshift 16 /* bias for fractions */
#define intbias (((int) 1)<<intbiasshift)
#define gammashift 10 /* gamma = 1024 */
#define gamma (((int) 1)<<gammashift)
#define betashift 10
#define beta (intbias>>betashift) /* beta = 1/1024 */
#define betagamma (intbias<<(gammashift-betashift))
/* defs for decreasing radius factor */
#define initrad (netsize>>3) /* for 256 cols, radius starts */
#define radiusbiasshift 6 /* at 32.0 biased by 6 bits */
#define radiusbias (((int) 1)<<radiusbiasshift)
#define initradius (initrad*radiusbias) /* and decreases by a */
#define radiusdec 30 /* factor of 1/30 each cycle */
/* defs for decreasing alpha factor */
#define alphabiasshift 10 /* alpha starts at 1.0 */
#define initalpha (((int) 1)<<alphabiasshift)
int alphadec; /* biased by 10 bits */
/* radbias and alpharadbias used for radpower calculation */
#define radbiasshift 8
#define radbias (((int) 1)<<radbiasshift)
#define alpharadbshift (alphabiasshift+radbiasshift)
#define alpharadbias (((int) 1)<<alpharadbshift)
/* Types and Global Variables
-------------------------- */
static unsigned char *thepicture; /* the input image itself */
static int lengthcount; /* lengthcount = H*W*3 */
static int samplefac; /* sampling factor 1..30 */
typedef int pixel[4]; /* BGRc */
static pixel network[netsize]; /* the network itself */
static int netindex[256]; /* for network lookup - really 256 */
static int bias [netsize]; /* bias and freq arrays for learning */
static int freq [netsize];
static int radpower[initrad]; /* radpower for precomputation */
/* Initialise network in range (0,0,0) to (255,255,255) and set parameters
----------------------------------------------------------------------- */
void initnet(unsigned char *thepic, int len, int sample)
{
register int i;
register int *p;
thepicture = thepic;
lengthcount = len;
samplefac = sample;
for (i=0; i<netsize; i++) {
p = network[i];
p[0] = p[1] = p[2] = (i << (netbiasshift+8))/netsize;
freq[i] = intbias/netsize; /* 1/netsize */
bias[i] = 0;
}
}
/* Unbias network to give byte values 0..255 and record position i to prepare for sort
----------------------------------------------------------------------------------- */
void unbiasnet()
{
int i,j,temp;
for (i=0; i<netsize; i++) {
for (j=0; j<3; j++) {
/* OLD CODE: network[i][j] >>= netbiasshift; */
/* Fix based on bug report by Juergen Weigert jw@suse.de */
temp = (network[i][j] + (1 << (netbiasshift - 1))) >> netbiasshift;
if (temp > 255) temp = 255;
network[i][j] = temp;
}
network[i][3] = i; /* record colour no */
}
}
/* Output colour map
----------------- */
void writecolourmap(unsigned char *p)
{
int i,j;
for (j=0; j<netsize; j++)
for (i=0; i<3; i++)
*p++ = network[j][i];
}
/* Insertion sort of network and building of netindex[0..255] (to do after unbias)
------------------------------------------------------------------------------- */
void inxbuild()
{
register int i,j,smallpos,smallval;
register int *p,*q;
int previouscol,startpos;
previouscol = 0;
startpos = 0;
for (i=0; i<netsize; i++) {
p = network[i];
smallpos = i;
smallval = p[1]; /* index on g */
/* find smallest in i..netsize-1 */
for (j=i+1; j<netsize; j++) {
q = network[j];
if (q[1] < smallval) { /* index on g */
smallpos = j;
smallval = q[1]; /* index on g */
}
}
q = network[smallpos];
/* swap p (i) and q (smallpos) entries */
if (i != smallpos) {
j = q[0]; q[0] = p[0]; p[0] = j;
j = q[1]; q[1] = p[1]; p[1] = j;
j = q[2]; q[2] = p[2]; p[2] = j;
j = q[3]; q[3] = p[3]; p[3] = j;
}
/* smallval entry is now in position i */
if (smallval != previouscol) {
netindex[previouscol] = (startpos+i)>>1;
for (j=previouscol+1; j<smallval; j++) netindex[j] = i;
previouscol = smallval;
startpos = i;
}
}
netindex[previouscol] = (startpos+maxnetpos)>>1;
for (j=previouscol+1; j<256; j++) netindex[j] = maxnetpos; /* really 256 */
}
/* Search for BGR values 0..255 (after net is unbiased) and return colour index
---------------------------------------------------------------------------- */
int inxsearch(int b, int g, int r)
{
register int i,j,dist,a,bestd;
register int *p;
int best;
bestd = 1000; /* biggest possible dist is 256*3 */
best = -1;
i = netindex[g]; /* index on g */
j = i-1; /* start at netindex[g] and work outwards */
while ((i<netsize) || (j>=0)) {
if (i<netsize) {
p = network[i];
dist = p[1] - g; /* inx key */
if (dist >= bestd) i = netsize; /* stop iter */
else {
i++;
if (dist<0) dist = -dist;
a = p[0] - b; if (a<0) a = -a;
dist += a;
if (dist<bestd) {
a = p[2] - r; if (a<0) a = -a;
dist += a;
if (dist<bestd) {bestd=dist; best=p[3];}
}
}
}
if (j>=0) {
p = network[j];
dist = g - p[1]; /* inx key - reverse dif */
if (dist >= bestd) j = -1; /* stop iter */
else {
j--;
if (dist<0) dist = -dist;
a = p[0] - b; if (a<0) a = -a;
dist += a;
if (dist<bestd) {
a = p[2] - r; if (a<0) a = -a;
dist += a;
if (dist<bestd) {bestd=dist; best=p[3];}
}
}
}
}
return(best);
}
/* Search for biased BGR values
---------------------------- */
int contest(int b, int g, int r)
{
/* finds closest neuron (min dist) and updates freq */
/* finds best neuron (min dist-bias) and returns position */
/* for frequently chosen neurons, freq[i] is high and bias[i] is negative */
/* bias[i] = gamma*((1/netsize)-freq[i]) */
register int i,dist,a,biasdist,betafreq;
int bestpos,bestbiaspos,bestd,bestbiasd;
register int *p,*f, *n;
bestd = ~(((int) 1)<<31);
bestbiasd = bestd;
bestpos = -1;
bestbiaspos = bestpos;
p = bias;
f = freq;
for (i=0; i<netsize; i++) {
n = network[i];
dist = n[0] - b; if (dist<0) dist = -dist;
a = n[1] - g; if (a<0) a = -a;
dist += a;
a = n[2] - r; if (a<0) a = -a;
dist += a;
if (dist<bestd) {bestd=dist; bestpos=i;}
biasdist = dist - ((*p)>>(intbiasshift-netbiasshift));
if (biasdist<bestbiasd) {bestbiasd=biasdist; bestbiaspos=i;}
betafreq = (*f >> betashift);
*f++ -= betafreq;
*p++ += (betafreq<<gammashift);
}
freq[bestpos] += beta;
bias[bestpos] -= betagamma;
return(bestbiaspos);
}
/* Move neuron i towards biased (b,g,r) by factor alpha
---------------------------------------------------- */
void altersingle(int alpha, int i, int b, int g, int r)
{
register int *n;
n = network[i]; /* alter hit neuron */
*n -= (alpha*(*n - b)) / initalpha;
n++;
*n -= (alpha*(*n - g)) / initalpha;
n++;
*n -= (alpha*(*n - r)) / initalpha;
}
/* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
--------------------------------------------------------------------------------- */
void alterneigh(int rad, int i, int b, int g, int r)
{
register int j,k,lo,hi,a;
register int *p, *q;
lo = i-rad; if (lo<-1) lo=-1;
hi = i+rad; if (hi>netsize) hi=netsize;
j = i+1;
k = i-1;
q = radpower;
while ((j<hi) || (k>lo)) {
a = (*(++q));
if (j<hi) {
p = network[j];
*p -= (a*(*p - b)) / alpharadbias;
p++;
*p -= (a*(*p - g)) / alpharadbias;
p++;
*p -= (a*(*p - r)) / alpharadbias;
j++;
}
if (k>lo) {
p = network[k];
*p -= (a*(*p - b)) / alpharadbias;
p++;
*p -= (a*(*p - g)) / alpharadbias;
p++;
*p -= (a*(*p - r)) / alpharadbias;
k--;
}
}
}
/* Main Learning Loop
------------------ */
void learn()
{
register int i,j,b,g,r;
int radius,rad,alpha,step,delta,samplepixels;
register unsigned char *p;
unsigned char *lim;
alphadec = 30 + ((samplefac-1)/3);
p = thepicture;
lim = thepicture + lengthcount;
samplepixels = lengthcount/(3*samplefac);
//if(samplepixels<ncycles) samplepixels = ncycles;
//assert(lengthcount>=ncycles);
delta = samplepixels/ncycles;
if(!delta) delta = 1; // WOUTER: I guess noone ever tested with small images (mipmaps)
alpha = initalpha;
radius = initradius;
rad = radius >> radiusbiasshift;
if (rad <= 1) rad = 0;
for (i=0; i<rad; i++)
radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));
//fprintf(stderr,"beginning 1D learning: initial radius=%d\n", rad);
if ((lengthcount%prime1) != 0) step = 3*prime1;
else {
if ((lengthcount%prime2) !=0) step = 3*prime2;
else {
if ((lengthcount%prime3) !=0) step = 3*prime3;
else step = 3*prime4;
}
}
i = 0;
while (i < samplepixels) {
b = p[0] << netbiasshift;
g = p[1] << netbiasshift;
r = p[2] << netbiasshift;
j = contest(b,g,r);
altersingle(alpha,j,b,g,r);
if (rad) alterneigh(rad,j,b,g,r); /* alter neighbours */
p += step;
while (p >= lim) p -= lengthcount; // wouter: was: if (p >= lim)
i++;
if (i%delta == 0) {
alpha -= alpha / alphadec;
radius -= radius / radiusdec;
rad = radius >> radiusbiasshift;
if (rad <= 1) rad = 0;
for (j=0; j<rad; j++)
radpower[j] = alpha*(((rad*rad - j*j)*radbias)/(rad*rad));
}
}
//fprintf(stderr,"finished 1D learning: final alpha=%f !\n",((float)alpha)/initalpha);
}

View File

@@ -0,0 +1,78 @@
/* NeuQuant Neural-Net Quantization Algorithm Interface
* ----------------------------------------------------
*
* Copyright (c) 1994 Anthony Dekker
*
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
* See "Kohonen neural networks for optimal colour quantization"
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
* for a discussion of the algorithm.
* See also http://www.acm.org/~dekker/NEUQUANT.HTML
*
* Any party obtaining a copy of these files from the author, directly or
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
* in this software and documentation files (the "Software"), including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons who receive
* copies from any such party to do so, with the only requirement being
* that this copyright notice remain intact.
*/
#include <stdio.h>
#define netsize 256 /* number of colours used */
/* For 256 colours, fixed arrays need 8kb, plus space for the image
---------------------------------------------------------------- */
/* four primes near 500 - assume no image has a length so large */
/* that it is divisible by all four primes */
#define prime1 499
#define prime2 491
#define prime3 487
#define prime4 503
#define minpicturebytes (3*prime4) /* minimum size for input image */
/* Initialise network in range (0,0,0) to (255,255,255) and set parameters
----------------------------------------------------------------------- */
void initnet(unsigned char *thepic, int len, int sample);
/* Unbias network to give byte values 0..255 and record position i to prepare for sort
----------------------------------------------------------------------------------- */
void unbiasnet(); /* can edit this function to do output of colour map */
/* Output colour map
----------------- */
void writecolourmap(unsigned char *p);
/* Insertion sort of network and building of netindex[0..255] (to do after unbias)
------------------------------------------------------------------------------- */
void inxbuild();
/* Search for BGR values 0..255 (after net is unbiased) and return colour index
---------------------------------------------------------------------------- */
int inxsearch(register int b, register int g, register int r);
/* Main Learning Loop
------------------ */
void learn();
/* Program Skeleton
----------------
[select samplefac in range 1..30]
pic = (unsigned char*) malloc(3*width*height);
[read image from input file into pic]
initnet(pic,3*width*height,samplefac);
learn();
unbiasnet();
[write output image header, using writecolourmap(f),
possibly editing the loops in that function]
inxbuild();
[write output image using inxsearch(b,g,r)] */

View File

@@ -0,0 +1,71 @@
template examples:
* normalmap_high
* normalmap_low
* skybox
todo:
* reduce resolution with add and sub
* presets
* platform settings (low mem, compressed normalmaps, high quality version, ...)
* apply greyscale bumpmap to normalmap
* D3DXComputeNormalMap
* test reduce resolution bejond 1:1 result
* directory specific parameters
* extract data from the huge polybump output file
* close window = cancel
* non power of two warning
* check for resource compiler (is gfx support enougth)
* Init() with access to log, error and info
future todo:
* gamma, brightness
* support premultiplied alpha (DXT2 and DXT4)
* 8bit, 4bit indexed colors (with or without luminance)
* statistics (frequency)
* ifdef for localization and special versions
* mask color for lightmaps and border colors
* better mipmap filter kernel
----------------------------------------------------------------------------------------------------
e.g.
template=skybox_texture
e.g.
pixelformat=DXT1 ; default
mipmaps=none
e.g.
pixelformat=R8G8B8
mipmaps=max ; default
mipmirror=0
e.g.
pixelformat=DXT3
mipmaps=3
mipmirror=1 ; default

View File

@@ -0,0 +1,34 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ResourceCompilerImage.rc
//
#define IDD_USERDIALOG 101
#define IDD_TAB_SAVEFORMAT 102
#define IDD_TAB_NORMALMAPGEN 103
#define IDC_SHOWUSERDIALOG 1001
#define IDC_LEFTPREVIEWINFO 1002
#define IDC_RIGHTPREVIEWINFO 1003
#define IDC_TEMPLATECOMBO 1004
#define IDC_PIXELFORMAT 1005
#define IDC_PIXELFORMATDESC 1006
#define IDC_MIPMAPS 1007
#define IDC_ZOOMIN 1008
#define IDC_ZOOMOUT 1009
#define IDC_PREVIEWALPHA 1010
#define IDC_PREVIEWFILTERED 1011
#define IDC_REDUCERES 1012
#define IDC_PREVIEWTILED 1013
#define IDC_DITHERMODE 1014
#define IDC_PROPTAB 1015
#define IDC_NM_FILTERTYPE 1016
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1017
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,9 @@
// stdafx.cpp : source file that includes just the standard includes
// ResourceCompilerImage.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
#pragma comment(lib,"comctl32.lib")
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@@ -0,0 +1,44 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _WIN32_WINNT 0x0500 // min Win2000 for GetConsoleWindow() Baustelle
// Windows Header Files:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
#include <atlbase.h>
#include <atlstr.h>
#include <vector>
extern HMODULE g_hInst;
#ifndef ReleasePpo
#define ReleasePpo(ppo) \
if (*(ppo) != NULL) \
{ \
(*(ppo))->Release(); \
*(ppo) = NULL; \
} \
else (VOID)0
#endif
// TODO: reference additional headers your program requires here