分离VKDebugOut以及VKProperties
This commit is contained in:
parent
dbfa2ec526
commit
19be1c4d9f
@ -52,6 +52,8 @@ int main(int,char **)
|
||||
|
||||
InitNativeWindowSystem();
|
||||
|
||||
InitVulkanProperties();
|
||||
|
||||
win=CreateRenderWindow(OS_TEXT("VulkanTest"));
|
||||
if(!win)
|
||||
return(false);
|
||||
|
196
inc/hgl/graph/Spline.cpp
Normal file
196
inc/hgl/graph/Spline.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
template<typename Point_t, typename Real_t>
|
||||
Spline<Point_t, Real_t>::Spline(
|
||||
int k,
|
||||
SplineNode node_type)
|
||||
:
|
||||
_node_type(node_type),
|
||||
_k(k),
|
||||
_point( _k ),
|
||||
_vec( _k-1 ),
|
||||
_node( _k + _point.size() )
|
||||
{
|
||||
assert_splines();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
void Spline<Point_t, Real_t>::set_ctrl_points(const std::vector<Point_t>& point)
|
||||
{
|
||||
_point = point;
|
||||
_vec.resize(_point.size() - 1);
|
||||
for(int i = 0; i < (int)_vec.size(); ++i)
|
||||
_vec[i] = _point[i + 1] - _point[i];
|
||||
set_nodal_vector();
|
||||
assert_splines();
|
||||
|
||||
for(int i = 0; i < (int)_vec.size(); ++i)
|
||||
_vec[i] /= _node[_k+i] - _node[i+1];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
void Spline<Point_t, Real_t>::get_ctrl_points(std::vector<Point_t>& points) const
|
||||
{
|
||||
points = _point;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// The the nodal vector type
|
||||
template<typename Point_t, typename Real_t>
|
||||
void Spline<Point_t, Real_t>::set_node_type( SplineNode type)
|
||||
{
|
||||
_node_type = type;
|
||||
set_nodal_vector();
|
||||
assert_splines();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
Point_t Spline<Point_t, Real_t>::eval_f(Real_t u) const
|
||||
{
|
||||
u = std::max(std::min(u, (Real_t)1), (Real_t)0); // clamp between [0 1]
|
||||
return eval(u, _point, _k, _node);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
Point_t Spline<Point_t, Real_t>::eval_df(Real_t u) const
|
||||
{
|
||||
u = std::max(std::min(u, (Real_t)1), (Real_t)0); // clamp between [0 1]
|
||||
return eval(u, _vec, (_k-1), _node, 1) * (Real_t)(_k-1);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
void Spline<Point_t, Real_t>::assert_splines() const
|
||||
{
|
||||
assert( _k > 1);
|
||||
assert((int)_point.size() >= _k );
|
||||
assert(_node. size() == (_k + _point.size()) );
|
||||
assert(_point.size() == (_vec.size() + 1) );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
void Spline<Point_t, Real_t>::set_nodal_vector()
|
||||
{
|
||||
if( _node_type == SplineNode::OPEN_UNIFORM)
|
||||
set_node_to_open_uniform();
|
||||
else if( _node_type == spline::eUNIFORM )
|
||||
set_node_to_uniform();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
void Spline<Point_t, Real_t>::set_node_to_uniform()
|
||||
{
|
||||
const int n = _point.size() - 1;
|
||||
_node.resize( _k + n + 1 );
|
||||
|
||||
Real_t step = (Real_t)1 / (Real_t)(n-_k+2);
|
||||
for (int i = 0; i < (int)_node.size(); ++i){
|
||||
_node[i] = ((Real_t)i) * step - step * (Real_t)(_k-1);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
void Spline<Point_t, Real_t>::set_node_to_open_uniform()
|
||||
{
|
||||
_node.resize( _k + _point.size() );
|
||||
|
||||
int acc = 1;
|
||||
for (int i = 0; i < (int)_node.size(); ++i)
|
||||
{
|
||||
if(i < _k)
|
||||
_node[i] = 0.;
|
||||
else if( i >= ((int)_point.size() + 1) )
|
||||
_node[i] = 1.;
|
||||
else{
|
||||
_node[i] = (Real_t)acc / (Real_t)(_point.size() + 1 - _k);
|
||||
acc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
Point_t Spline<Point_t, Real_t>::
|
||||
|
||||
eval(Real_t u,
|
||||
const std::vector<Point_t>& point,
|
||||
int k,
|
||||
const std::vector<Real_t>& node,
|
||||
int off) const
|
||||
{
|
||||
assert( k > 1);
|
||||
assert((int)point.size() >= k );
|
||||
assert_splines();
|
||||
int dec = 0;
|
||||
// TODO: better search with dychotomi ?
|
||||
// TODO: check for overflow
|
||||
while( u > node[dec + k + off] )
|
||||
dec++;
|
||||
|
||||
// TODO: use buffers in attributes for better performances ?
|
||||
std::vector<Point_t> p_rec(k, Point_t());
|
||||
for(int i = dec, j = 0; i < (dec + k); ++i, ++j)
|
||||
p_rec[j] = point[i];
|
||||
|
||||
std::vector<Real_t> node_rec(k + k - 2, (Real_t)0);
|
||||
for(int i = (dec + 1), j = 0; i < (dec + k + k - 1); ++i, ++j)
|
||||
node_rec[j] = node[i + off];
|
||||
|
||||
return eval_rec(u, p_rec, k, node_rec);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename Point_t, typename Real_t>
|
||||
Point_t Spline<Point_t, Real_t>::
|
||||
|
||||
eval_rec(Real_t u,
|
||||
std::vector<Point_t> p_in,
|
||||
int k,
|
||||
std::vector<Real_t> node_in) const
|
||||
{
|
||||
if(p_in.size() == 1)
|
||||
return p_in[0];
|
||||
|
||||
// TODO: use buffers in attributes for better performances ?
|
||||
std::vector<Point_t> p_out(k - 1, Point_t());
|
||||
for(int i = 0; i < (k - 1); ++i)
|
||||
{
|
||||
const Real_t n0 = node_in[i + k - 1];
|
||||
const Real_t n1 = node_in[i];
|
||||
const Real_t f0 = (n0 - u) / (n0 - n1);
|
||||
const Real_t f1 = (u - n1) / (n0 - n1);
|
||||
|
||||
p_out[i] = p_in[i] * f0 + p_in[i + 1] * f1;
|
||||
}
|
||||
|
||||
std::vector<Real_t> node_out(node_in.size() - 2);
|
||||
for(int i = 1, j = 0; i < ((int)node_in.size()-1); ++i, ++j)
|
||||
node_out[j] = node_in[i];
|
||||
|
||||
return eval_rec(u, p_out, (k - 1), node_out);
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
100
inc/hgl/graph/Spline.h
Normal file
100
inc/hgl/graph/Spline.h
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef HGL_GRAPH_SPLINE_INCLUDE
|
||||
#define HGL_GRAPH_SPLINE_INCLUDE
|
||||
|
||||
#include<hgl/math/Vector.h>
|
||||
#include<vector>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
enum class SplineNode
|
||||
{
|
||||
UNIFORM,
|
||||
OPEN_UNIFORM ///< Connected to the first and last control points
|
||||
};
|
||||
|
||||
template<typename Point_t, typename Real_t> class Spline
|
||||
{
|
||||
public:
|
||||
|
||||
/// Type of the nodal vector
|
||||
/// @param k : order of the spline (minimum is two)
|
||||
/// @param node_type : nodal vector type (uniform, open_uniform)
|
||||
/// This will define the behavior of the spline with its control points
|
||||
/// as well as its speed according to its parameter.
|
||||
Spline(int k = 2, SplineNode node_type = SplineNode::OPEN_UNIFORM);
|
||||
|
||||
/// Set the position of the spline control points.
|
||||
void set_ctrl_points(const std::vector<Point_t>& point);
|
||||
|
||||
/// Get the control points of the spline
|
||||
void get_ctrl_points(std::vector<Point_t>& points) const;
|
||||
|
||||
/// The the nodal vector type
|
||||
void set_node_type( SplineNode type);
|
||||
|
||||
/// Evaluate position of the spline
|
||||
/// @param u : curve parameter ranging from [0; 1]
|
||||
Point_t eval_f(Real_t u) const;
|
||||
|
||||
/// Evaluate speed of the spline
|
||||
Point_t eval_df(Real_t u) const;
|
||||
|
||||
int get_order() const { return _k; }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------------
|
||||
/// @name Class tools
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
void assert_splines() const;
|
||||
|
||||
/// set value and size of the nodal vector depending on the current number
|
||||
/// of control points
|
||||
void set_nodal_vector();
|
||||
|
||||
/// Set values of the nodal vector to be uniform
|
||||
void set_node_to_uniform();
|
||||
|
||||
/// Set values of the nodal vector to be open uniform
|
||||
void set_node_to_open_uniform();
|
||||
|
||||
/// Evaluate the equation of a splines using the blossom algorithm
|
||||
/// @param u : the curve parameter which range from the values
|
||||
/// [node[k-1]; node[point.size()]]
|
||||
/// @param point : the control points which size must be at least equal to
|
||||
/// the order of the spline (point.size() >= k)
|
||||
/// @param k : the spline order (degree == k-1)
|
||||
/// @param node : the nodal vector which defines the speed of the spline
|
||||
/// parameter u. The nodal vector size must be equal to (k + point.size())
|
||||
/// @param off : offset to apply to the nodal vector 'node' before reading
|
||||
/// from it. this is useful to compute derivatives.
|
||||
Point_t eval(Real_t u,
|
||||
const std::vector<Point_t>& point,
|
||||
int k,
|
||||
const std::vector<Real_t>& node,
|
||||
int off = 0) const;
|
||||
|
||||
Point_t eval_rec(Real_t u,
|
||||
std::vector<Point_t> p_in,
|
||||
int k,
|
||||
std::vector<Real_t> node_in) const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// @name attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
SplineNode _node_type; ///< Nodal vector type
|
||||
int _k; ///< spline order
|
||||
std::vector<Point_t> _point; ///< Control points
|
||||
std::vector<Point_t> _vec; ///< Control points differences
|
||||
std::vector<Real_t> _node; ///< Nodal vector
|
||||
};//class Spline
|
||||
|
||||
using Spline2f=Spline<Vector2f,float>;
|
||||
using Spline3f=Spline<Vector3f,float>;
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
#include<hgl/graph/Spline.cpp>
|
||||
#endif//HGL_GRAPH_SPLINE_INCLUDE
|
103
inc/hgl/graph/TileData.h
Normal file
103
inc/hgl/graph/TileData.h
Normal file
@ -0,0 +1,103 @@
|
||||
#ifndef HGL_GRAPH_TILE_DATA_INCLUDE
|
||||
#define HGL_GRAPH_TILE_DATA_INCLUDE
|
||||
|
||||
#include<hgl/graph/TextureFormat.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
class Texture2D;
|
||||
class Renderable;
|
||||
class Bitmap2D;
|
||||
|
||||
/**
|
||||
* TileData是一种处理将大量等同贴图的管理机制,程序会自动根据显卡最大贴图处理能力来创建尽可能符合的贴图。(注意:Tile的宽高不必是2的幂)。<br>
|
||||
* Tile的增加删除,程序会做自动排序,尽可能小的影响效能。
|
||||
*/
|
||||
class TileData ///Tile数据管理
|
||||
{
|
||||
public:
|
||||
|
||||
struct Object ///Tile对象
|
||||
{
|
||||
int index;
|
||||
|
||||
double fl,ft;
|
||||
double fw,fh;
|
||||
|
||||
int width,height;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
Texture2D *tile_texture; ///<Tile所用贴图
|
||||
|
||||
TileData::Object **tile_object; ///<所有Tile对象指针
|
||||
|
||||
int tile_width,tile_height; ///<tile的宽和高
|
||||
int tile_count,tile_total; ///<当前tile数量与最大数量
|
||||
int tile_rows,tile_cols; ///<贴图中可用的tile行数和列数
|
||||
|
||||
protected:
|
||||
|
||||
int FindSpace(); ///<寻找一个空位
|
||||
void WriteTile(int,TileData::Object *,void *,unsigned int,TextureSourceFormat,int,int); ///<写入一个Tile
|
||||
|
||||
public:
|
||||
|
||||
int GetWidth ()const{return tile_width;} ///<取得Tile宽
|
||||
int GetHeight ()const{return tile_height;} ///<取得Tile高
|
||||
int GetCount ()const{return tile_count;} ///<取得Tile数量
|
||||
int GetMaxCount ()const{return tile_total;} ///<取得Tile最大数量
|
||||
int GetFreeCount()const{return tile_total-tile_count;} ///<取得空余Tile数量
|
||||
|
||||
Texture2D * GetTexture ()const{return tile_texture;} ///<取得贴图
|
||||
|
||||
public:
|
||||
|
||||
TileData(int,int,int, TextureSourceFormat);
|
||||
virtual ~TileData();
|
||||
|
||||
TileData::Object *Add(void *,unsigned int,TextureSourceFormat,int=-1,int=-1); ///<增加一个Tile
|
||||
|
||||
bool Delete(TileData::Object *); ///<删除一个Tile
|
||||
bool Change(TileData::Object *,void *,unsigned int,TextureSourceFormat,int=-1,int=-1); ///<更改一个Tile的数据内容
|
||||
void Clear(); ///<清除Tile数据
|
||||
};//class TileData
|
||||
|
||||
template<typename T> class VertexBuffer2;
|
||||
|
||||
/**
|
||||
* 渲染Tile为一个2D矩形数据到顶点缓冲区上
|
||||
* @param obj 要渲制的Tile对象
|
||||
* @param vertex 渲染到的2d顶点坐标缓冲区
|
||||
* @param tex_coord 渲染到的贴图坐标缓冲区
|
||||
* @param left 显示的左边界
|
||||
* @param top 显示的上边界
|
||||
* @param scale_width 宽度缩放比
|
||||
* @param scale_height 高度缩放比
|
||||
*/
|
||||
template<typename T1,typename T2>
|
||||
__inline void RenderToVB2DRect( VertexBuffer2<T1> *vertex,
|
||||
VertexBuffer2<T2> *tex_coord,
|
||||
const TileData::Object *obj,
|
||||
const float left,
|
||||
const float top,
|
||||
const float scale_width=1.0f,
|
||||
const float scale_height=1.0f)
|
||||
{
|
||||
if(!obj||!vertex||!tex_coord)return;
|
||||
|
||||
tex_coord->WriteRect( obj->fl,
|
||||
obj->ft,
|
||||
obj->fw,
|
||||
obj->fh);
|
||||
|
||||
vertex->WriteRect( left,
|
||||
top,
|
||||
scale_width*float(obj->width),
|
||||
scale_height*float(obj->height));
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
#endif//HGL_GRAPH_TILE_DATA_INCLUDE
|
25
inc/hgl/graph/text/FontInfo.Attrib.h
Normal file
25
inc/hgl/graph/text/FontInfo.Attrib.h
Normal file
@ -0,0 +1,25 @@
|
||||
static FontInfo *DefaultFont;
|
||||
|
||||
private:
|
||||
|
||||
UTF16String name;
|
||||
|
||||
int width,height;
|
||||
bool bold,italic;
|
||||
|
||||
protected:
|
||||
|
||||
UTF16String &GetName(){return name;}
|
||||
void SetName(UTF16String &);
|
||||
|
||||
int GetWidth(){return width;}
|
||||
int GetHeight(){return height;}
|
||||
bool GetBold(){return bold;}
|
||||
bool GetItalic(){return italic;}
|
||||
|
||||
void SetWidth(int);
|
||||
void SetHeight(int);
|
||||
void SetBold(bool);
|
||||
void SetItalic(bool);
|
||||
|
||||
void InitPrivate();
|
51
inc/hgl/graph/text/FontInfo.h
Normal file
51
inc/hgl/graph/text/FontInfo.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef HGL_FONT_INFO_INCLUDE
|
||||
#define HGL_FONT_INFO_INCLUDE
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/type/Color4f.h>
|
||||
#include<hgl/type/BaseString.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 字体数据结构<br>
|
||||
* 用于记录字体名称,粗体,斜体,下划线等等信息
|
||||
*/
|
||||
class FontInfo ///字体数据结构
|
||||
{
|
||||
#include<hgl/graph/FontInfo.Attrib.h>
|
||||
|
||||
public: //属性
|
||||
|
||||
Property<UTF16String> Name; ///<字体名称
|
||||
|
||||
Property<int> Width; ///<平均字体宽度
|
||||
Property<int> Height; ///<字体高度
|
||||
|
||||
Property<bool> Bold; ///<是否粗体
|
||||
Property<bool> Italic; ///<是否斜体
|
||||
|
||||
public: //事件
|
||||
|
||||
DefEvent(void,OnChange,(FontInfo *)); ///<字体改变事件
|
||||
|
||||
public: //方法
|
||||
|
||||
FontInfo();
|
||||
FontInfo(const FontInfo &);
|
||||
FontInfo(const UTF16String &,int,int,bool=false,bool=false);
|
||||
|
||||
static void SetDefaultFont(const UTF16String &,int,int,bool,bool); ///<设置缺省字体
|
||||
static void SetDefaultFont(const FontInfo &); ///<设置缺省字体
|
||||
static void ClearDefaultFont(); ///<清除缺省字体
|
||||
|
||||
void Set(const UTF16String &,int,int,bool=false,bool=false); ///<设置字体
|
||||
|
||||
public: //操作符重载
|
||||
|
||||
bool operator == (const FontInfo &);
|
||||
bool operator != (const FontInfo &);
|
||||
|
||||
void operator = (const FontInfo &);
|
||||
};//class FontInfo
|
||||
}//namespace hgl
|
||||
#endif//HGL_FONT_INFO_INCLUDE
|
50
inc/hgl/graph/text/FontSource.h
Normal file
50
inc/hgl/graph/text/FontSource.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef HGL_GRAPH_FONT_SOURCE_INCLUDE
|
||||
#define HGL_GRAPH_FONT_SOURCE_INCLUDE
|
||||
|
||||
#include<hgl/graph/FontInfo.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
/**
|
||||
* 字体数据源抽像基类<br>
|
||||
* 主要提供点阵字体的数据产生管理
|
||||
*/
|
||||
class FontSource
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 字体位图数据
|
||||
*/
|
||||
struct Bitmap
|
||||
{
|
||||
int x,y; //图像显示偏移
|
||||
int w,h; //图像尺寸
|
||||
|
||||
int adv_x,adv_y;//字符尺寸
|
||||
|
||||
unsigned char *data;
|
||||
};//struct Bitmap
|
||||
|
||||
protected:
|
||||
|
||||
FontInfo fnt;
|
||||
|
||||
FontSource::Bitmap char_bitmap[0xFFFF]; ///<字符位图数据
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool MakeCharBitmap(u16char)=0; ///<产生字体数据
|
||||
virtual int GetLineHeight()const=0; ///<取得行高
|
||||
|
||||
public:
|
||||
|
||||
FontSource(const FontInfo &);
|
||||
virtual ~FontSource();
|
||||
|
||||
FontSource::Bitmap *GetCharBitmap(u16char); ///<取得字体数据
|
||||
};//class FontSource
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
#endif//HGL_GRAPH_FONT_SOURCE_INCLUDE
|
175
inc/hgl/graph/text/TileFont.h
Normal file
175
inc/hgl/graph/text/TileFont.h
Normal file
@ -0,0 +1,175 @@
|
||||
#ifndef HGL_GRAPH_TILE_FONT_INCLUDE
|
||||
#define HGL_GRAPH_TILE_FONT_INCLUDE
|
||||
|
||||
#include<hgl/algorithm/VectorMath.h>
|
||||
#include<hgl/type/Color4f.h>
|
||||
#include<hgl/type/ActiveChain.h>
|
||||
#include<hgl/graph/TileData.h>
|
||||
#include<hgl/graph/FontSource.h>
|
||||
#include<hgl/graph/Makeup.h>
|
||||
#include<hgl/graph/VertexBuffer.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
struct FontInfo;
|
||||
class Renderable;
|
||||
class Material;
|
||||
|
||||
/**
|
||||
* 使用每个Tile代表一个字符的管理模块<br>
|
||||
* 即可以使用系统字体,由程序实时生成字符;也可以使用由美术制作好的字体图片。
|
||||
*/
|
||||
class TileFont ///Tile字体
|
||||
{
|
||||
protected:
|
||||
|
||||
TileData *tile_data; ///<Tile管理器
|
||||
FontSource *chs_source,*eng_source; ///<字体数据源
|
||||
|
||||
ActiveChain<u16char,TileData::Object *> fud; ///<字体缓冲管理
|
||||
|
||||
uint8 *char_bitmap_buffer; ///<字符位图缓冲区
|
||||
uint char_bitmap_bytes; ///<字符位图字节数
|
||||
|
||||
VB2f *vertex2d; ///<绘制用顶点坐标
|
||||
VB2f *tex_coord; ///<绘制用顶点坐标
|
||||
// VB1ui *vertex_color; ///<绘制用顶点色
|
||||
Material *fnt_mtl; ///<绘制用材质
|
||||
Renderable *fnt_draw; ///<绘制用对象
|
||||
|
||||
int tile_width,tile_height; ///<所使用的Tile宽高
|
||||
int font_height;
|
||||
int line_distance;
|
||||
|
||||
protected:
|
||||
|
||||
void Clear(const u16char &,TileData::Object *&); ///<清除某个字
|
||||
|
||||
FontSource::Bitmap *GetCharBitmap(const u16char &ch) ///<取得字符位图数据
|
||||
{return ((ch<=0xFF?eng_source:chs_source)->GetCharBitmap(ch));}
|
||||
|
||||
FontSource::Bitmap *MakeCharBitmap(const u16char &ch); ///<生成字符位图数据
|
||||
|
||||
TileData::Object *GetCharData(const u16char &); ///<取得字符数据
|
||||
|
||||
bool MakeupText(Makeup &,int,int,const u16char *,int); ///<排版字符串
|
||||
|
||||
public:
|
||||
|
||||
int GetHeight ()const {return font_height;} ///<取得字符高度
|
||||
int GetLineDistance ()const {return line_distance;} ///<取得行间距
|
||||
|
||||
void SetLineDistance(int n) {line_distance=n;}
|
||||
|
||||
public: //属性
|
||||
|
||||
Color4f Color; ///<颜色
|
||||
|
||||
public:
|
||||
|
||||
TileFont(int,TileData *,FontSource *,FontSource *);
|
||||
virtual ~TileFont();
|
||||
|
||||
float CharWidth(u16char); ///<指定字符宽度
|
||||
float GetStringWidth(const u16char *,int=-1); ///<求字符串宽度
|
||||
|
||||
public:
|
||||
|
||||
bool MakeupText(Makeup &,const u16char *,int=-1); ///<排版字符串
|
||||
bool MakeupText(Makeup &,const u16char *,int,TextAlignment); ///<排版字符串
|
||||
|
||||
void Draw(const Matrix4f *,const Makeup &,int=-1); ///<根据排版进行绘制
|
||||
|
||||
void Draw(float l,float t,const Makeup &makeup,int limit_char=-1) ///<根据排版进行绘制
|
||||
{
|
||||
const Matrix4f mat=translate(l,t,0);
|
||||
|
||||
Draw(&mat,makeup,limit_char);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制一个字符串,可限制字数,并且处理\n
|
||||
* @param mat modelview变换矩阵
|
||||
* @param str 字符串
|
||||
* @param limit_char 限制的字数,-1表示不限制
|
||||
* @return 字符串的象素级宽度
|
||||
* @return <0 错误
|
||||
*/
|
||||
float DrawString(const Matrix4f *mat,const u16char *str,int limit_char=-1) ///<绘制一个字符串,可限制字数,并且处理\n
|
||||
{
|
||||
Makeup m;
|
||||
|
||||
if(!MakeupText(m,str,limit_char))
|
||||
return(-1);
|
||||
|
||||
Draw(mat,m,limit_char);
|
||||
|
||||
return m.Width;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制一个字符串,可限制字数,并且处理\n
|
||||
* @param x X坐标
|
||||
* @param y Y坐标
|
||||
* @param str 字符串
|
||||
* @param limit_char 限制的字数,-1表示不限制
|
||||
* @return 字符串的象素级宽度
|
||||
* @return <0 错误
|
||||
*/
|
||||
float DrawString(float x,float y,const u16char *str,int limit_char=-1) ///<绘制一个字符串,可限制字数,并且处理\n
|
||||
{
|
||||
const Matrix4f mat=translate(x,y,0);
|
||||
|
||||
return DrawString(&mat,str,limit_char);
|
||||
}
|
||||
|
||||
float DrawFormat(const Matrix4f *mat,const u16char *,...); ///<绘制一个格式化的字符串
|
||||
float DrawFormat(float,float,const u16char *,...); ///<绘制一个格式化的字符串
|
||||
};//class TileFont
|
||||
|
||||
TileFont *CreateTileFont(const FontInfo &,const FontInfo &,int=-1); ///<创建一个字体,使用系统字体
|
||||
|
||||
/**
|
||||
* 通过系统字体创建一个Tile字体
|
||||
* @param chs_fontname 中文字体名称
|
||||
* @param eng_fontname 英文字体名称
|
||||
* @param width 宽,可以为0,表示默认。
|
||||
* @param height 高
|
||||
* @param bold 加粗,默认false
|
||||
* @param italic 斜体,默认false
|
||||
* @param anti 是否抗矩齿,默认true
|
||||
* @param count 缓冲区内保存的字符个数
|
||||
*/
|
||||
TileFont *CreateTileFont(const u16char *chs_fontname,const u16char *eng_fontname,int width,int height,bool bold=false,bool italic=false,bool anti=true,int count=-1);
|
||||
|
||||
/**
|
||||
* 通过系统字体创建一个Tile字体,中英文字体相同
|
||||
* @param fontname 字体名称
|
||||
* @param width 宽,可以为0,表示默认。
|
||||
* @param height 高
|
||||
* @param bold 加粗,默认false
|
||||
* @param italic 斜体,默认false
|
||||
* @param anti 是否抗矩齿,默认true
|
||||
* @param count 缓冲区内保存的字符个数
|
||||
*/
|
||||
__inline TileFont *CreateTileFont(const u16char *fontname,int width,int height,bool bold=false,bool italic=false,bool anti=true,int count=-1)
|
||||
{
|
||||
return CreateTileFont(fontname,fontname,width,height,bold,italic,anti,count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过系统字体创建一个Tile字体,无斜体,无加粗
|
||||
* @param chs_fontname 中文字体名称
|
||||
* @param eng_fontname 英文字体名称
|
||||
* @param width 宽,可以为0,表示默认。
|
||||
* @param height 高
|
||||
* @param count 缓冲区内保存的字符个数
|
||||
*/
|
||||
__inline TileFont *CreateTileFont(const u16char *chs_fontname,const u16char *eng_fontname,int width,int height,int count=-1)
|
||||
{
|
||||
return CreateTileFont(chs_fontname,eng_fontname,width,height,false,false,true,count);
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
#endif//HGL_GRAPH_TILE_FONT_INCLUDE
|
@ -104,5 +104,11 @@ inline void debug_out(const hgl::List<VkExtensionProperties> &extension_properti
|
||||
++ep;
|
||||
}
|
||||
}
|
||||
|
||||
void InitVulkanProperties();
|
||||
const List<VkLayerProperties> & GetLayerProperties();
|
||||
const List<VkExtensionProperties> & GetExtensionProperties();
|
||||
const bool CheckLayerSupport(const char *);
|
||||
|
||||
VK_NAMESPACE_END
|
||||
#endif//HGL_GRAPH_VULKAN_INCLUDE
|
||||
|
23
inc/hgl/graph/vulkan/VKDebugOut.h
Normal file
23
inc/hgl/graph/vulkan/VKDebugOut.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef HGL_GRAPH_VULKAN_DEBUG_OUT_INCLUDE
|
||||
#define HGL_GRAPH_VULKAN_DEBUG_OUT_INCLUDE
|
||||
|
||||
#include<hgl/graph/vulkan/VK.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
|
||||
class VKDebugOut
|
||||
{
|
||||
VkInstance inst=nullptr;
|
||||
|
||||
VkDebugUtilsMessengerEXT debug_messenger;
|
||||
VkDebugReportCallbackEXT debug_report_callback;
|
||||
|
||||
public:
|
||||
|
||||
VKDebugOut();
|
||||
virtual ~VKDebugOut();
|
||||
|
||||
virtual bool Init(VkInstance);
|
||||
};//class VKDebugOut
|
||||
VK_NAMESPACE_END
|
||||
#endif//HGL_GRAPH_VULKAN_DEBUG_OUT_INCLUDE
|
@ -5,17 +5,14 @@
|
||||
#include<hgl/type/List.h>
|
||||
#include<hgl/platform/Window.h>
|
||||
#include<hgl/graph/vulkan/VKPhysicalDevice.h>
|
||||
#include<hgl/graph/vulkan/VKDebugOut.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
class Instance
|
||||
{
|
||||
VkInstance inst;
|
||||
|
||||
List<VkLayerProperties> layer_properties;
|
||||
List<VkExtensionProperties> extension_properties;
|
||||
|
||||
VkDebugUtilsMessengerEXT debug_messenger;
|
||||
VkDebugReportCallbackEXT debug_report_callback;
|
||||
VKDebugOut *debug_out;
|
||||
|
||||
CharPointerList ext_list;
|
||||
|
||||
@ -23,9 +20,9 @@ VK_NAMESPACE_BEGIN
|
||||
|
||||
private:
|
||||
|
||||
friend Instance *CreateInstance(const UTF8String &app_name);
|
||||
friend Instance *CreateInstance(const UTF8String &app_name,VKDebugOut *do=nullptr);
|
||||
|
||||
Instance(VkInstance,CharPointerList &);
|
||||
Instance(VkInstance,VKDebugOut *,CharPointerList &);
|
||||
|
||||
public:
|
||||
|
||||
@ -33,13 +30,11 @@ VK_NAMESPACE_BEGIN
|
||||
|
||||
operator VkInstance (){return inst;}
|
||||
|
||||
const List<VkLayerProperties> & GetLayerProperties ()const {return layer_properties;}
|
||||
const bool CheckLayerSupport (const UTF8String &)const;
|
||||
const CharPointerList & GetExtList ()const {return ext_list;}
|
||||
const ObjectList<PhysicalDevice> &GetDeviceList ()const {return physical_devices;}
|
||||
const PhysicalDevice * GetDevice (VkPhysicalDeviceType)const;
|
||||
};//class Instance
|
||||
|
||||
Instance *CreateInstance(const UTF8String &); ///<创建一个Vulkan实例
|
||||
Instance *CreateInstance(const UTF8String &,VKDebugOut *do=nullptr); ///<创建一个Vulkan实例
|
||||
VK_NAMESPACE_END
|
||||
#endif//HGL_GRAPH_VULKAN_INSTANCE_INCLUDE
|
||||
|
68
inc/hgl/input/Event.h
Normal file
68
inc/hgl/input/Event.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
#include<hgl/type/DataType.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace device_input
|
||||
{
|
||||
#pragma pack(push,1)
|
||||
union InputEvent
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 key;
|
||||
}key_push;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 key;
|
||||
}key_pop;
|
||||
|
||||
struct
|
||||
{
|
||||
uint16 x, y;
|
||||
}mouse_move;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 key;
|
||||
}mouse_key_push;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 key;
|
||||
}mouse_key_pop;
|
||||
|
||||
struct
|
||||
{
|
||||
int16 x, y;
|
||||
}mouse_wheel;
|
||||
|
||||
struct
|
||||
{
|
||||
int8 x, y;
|
||||
}joystick_axis;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 key;
|
||||
}joystick_key_push;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 key;
|
||||
}joystick_key_pop;
|
||||
|
||||
struct
|
||||
{
|
||||
uint16 x, y;
|
||||
uint16 power;
|
||||
}wacom;
|
||||
|
||||
struct
|
||||
{
|
||||
u16char ch;
|
||||
}char_input;
|
||||
};//union InputEvent
|
||||
#pragma pack(pop)
|
||||
}//namespace device_input
|
||||
}//namespace hgl
|
15
res/shader/test.geom
Normal file
15
res/shader/test.geom
Normal file
@ -0,0 +1,15 @@
|
||||
#version 450 core
|
||||
|
||||
layout(binding = 0) uniform WorldMatrix
|
||||
{
|
||||
mat4 two_dim;
|
||||
mat4 projection;
|
||||
mat4 modelview;
|
||||
mat4 mvp;
|
||||
mat3 normal;
|
||||
} world;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position=vec4(1.0)*world.mvp;
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
SET(RENDER_DEVICE_VULKAN_SOURCE VKFormat.cpp
|
||||
VKMemory.cpp
|
||||
VKProperties.cpp
|
||||
VKInstance.cpp
|
||||
VKPhysicalDevice.cpp
|
||||
VKImageView.cpp
|
||||
|
171
src/RenderDevice/Vulkan/VKDebugOut.cpp
Normal file
171
src/RenderDevice/Vulkan/VKDebugOut.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include<hgl/graph/vulkan/VK.h>
|
||||
#include<iostream>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
namespace
|
||||
{
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,const VkAllocationCallbacks *pAllocator,VkDebugUtilsMessengerEXT *pDebugMessenger)
|
||||
{
|
||||
auto func=(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance,"vkCreateDebugUtilsMessengerEXT");
|
||||
if(func)
|
||||
{
|
||||
return func(instance,pCreateInfo,pAllocator,pDebugMessenger);
|
||||
}
|
||||
else
|
||||
{
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyDebugUtilsMessengerEXT(VkInstance instance,VkDebugUtilsMessengerEXT debugMessenger,const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
auto func=(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance,"vkDestroyDebugUtilsMessengerEXT");
|
||||
if(func)
|
||||
{
|
||||
func(instance,debugMessenger,pAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageType,const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,void *pUserData)
|
||||
{
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||
{
|
||||
std::cout<<"ERROR: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
|
||||
{
|
||||
std::cout<<"WARNING: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
|
||||
{
|
||||
std::cout<<"INFO: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
|
||||
{
|
||||
std::cout<<"VERBOSE: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
std::cerr<<"validation layer: "<<pCallbackData->pMessage<<std::endl;
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
bool CreateDebugReportCallbackEXT(VkInstance instance,const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,const VkAllocationCallbacks *pAllocator,VkDebugReportCallbackEXT *pCallback)
|
||||
{
|
||||
auto func=(PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance,"vkCreateDebugReportCallbackEXT");
|
||||
if(func)
|
||||
{
|
||||
func(instance,pCreateInfo,pAllocator,pCallback);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool DestroyDebugReportCallbackEXT(VkInstance instance,VkDebugReportCallbackEXT callback,const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
auto func=(PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance,"vkDestroyDebugReportCallbackEXT");
|
||||
if(func)
|
||||
{
|
||||
func(instance,callback,pAllocator);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkDebugReportFlagsEXT msgFlags,VkDebugReportObjectTypeEXT objType,uint64_t srcObject,
|
||||
size_t location,int32_t msgCode,const char *pLayerPrefix,const char *pMsg,
|
||||
void *pUserData)
|
||||
{
|
||||
if(msgFlags&VK_DEBUG_REPORT_ERROR_BIT_EXT)
|
||||
{
|
||||
std::cout<<"ERROR: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_WARNING_BIT_EXT)
|
||||
{
|
||||
std::cout<<"WARNING: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
|
||||
{
|
||||
std::cout<<"PERFORMANCE WARNING: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
|
||||
{
|
||||
std::cout<<"INFO: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_DEBUG_BIT_EXT)
|
||||
{
|
||||
std::cout<<"DEBUG: ";
|
||||
}
|
||||
|
||||
std::cout<<"["<<pLayerPrefix<<"] Code "<<msgCode<<" : "<<pMsg<<std::endl;
|
||||
|
||||
/*
|
||||
* false indicates that layer should not bail-out of an
|
||||
* API call that had validation failures. This may mean that the
|
||||
* app dies inside the driver due to invalid parameter(s).
|
||||
* That's what would happen without validation layers, so we'll
|
||||
* keep that behavior here.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}//namespace
|
||||
|
||||
|
||||
virtual bool Init(VkInstance);
|
||||
debug_report_callback=VK_NULL_HANDLE;
|
||||
{
|
||||
VkDebugReportCallbackCreateInfoEXT create_info;
|
||||
|
||||
create_info.sType =VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
|
||||
create_info.pNext =nullptr;
|
||||
|
||||
create_info.flags =VK_DEBUG_REPORT_ERROR_BIT_EXT
|
||||
|VK_DEBUG_REPORT_WARNING_BIT_EXT
|
||||
|VK_DEBUG_REPORT_DEBUG_BIT_EXT
|
||||
|VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||
|
||||
create_info.pfnCallback =dbgFunc;
|
||||
create_info.pUserData =nullptr;
|
||||
|
||||
CreateDebugReportCallbackEXT(inst,&create_info,nullptr,&debug_report_callback);
|
||||
}
|
||||
|
||||
debug_messenger=VK_NULL_HANDLE;
|
||||
{
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo;
|
||||
|
||||
createInfo.sType =VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
createInfo.pNext =nullptr;
|
||||
createInfo.flags =0;
|
||||
|
||||
createInfo.messageSeverity =VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
|
||||
createInfo.messageType =VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
|
||||
createInfo.pfnUserCallback =debugCallback;
|
||||
createInfo.pUserData =nullptr;
|
||||
|
||||
CreateDebugUtilsMessengerEXT(inst,&createInfo,nullptr,&debug_messenger);
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if(debug_messenger)
|
||||
DestroyDebugUtilsMessengerEXT(inst,debug_messenger,nullptr);
|
||||
|
||||
if(debug_report_callback)
|
||||
DestroyDebugReportCallbackEXT(inst,debug_report_callback,nullptr);
|
||||
}
|
@ -6,128 +6,12 @@
|
||||
VK_NAMESPACE_BEGIN
|
||||
Device *CreateRenderDevice(VkInstance,const PhysicalDevice *,Window *);
|
||||
|
||||
namespace
|
||||
{
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,const VkAllocationCallbacks *pAllocator,VkDebugUtilsMessengerEXT *pDebugMessenger)
|
||||
{
|
||||
auto func=(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance,"vkCreateDebugUtilsMessengerEXT");
|
||||
if(func)
|
||||
{
|
||||
return func(instance,pCreateInfo,pAllocator,pDebugMessenger);
|
||||
}
|
||||
else
|
||||
{
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyDebugUtilsMessengerEXT(VkInstance instance,VkDebugUtilsMessengerEXT debugMessenger,const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
auto func=(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance,"vkDestroyDebugUtilsMessengerEXT");
|
||||
if(func)
|
||||
{
|
||||
func(instance,debugMessenger,pAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageType,const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,void *pUserData)
|
||||
{
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||
{
|
||||
std::cout<<"ERROR: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
|
||||
{
|
||||
std::cout<<"WARNING: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
|
||||
{
|
||||
std::cout<<"INFO: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
|
||||
{
|
||||
std::cout<<"VERBOSE: "<<pCallbackData->pMessage<<std::endl;
|
||||
}
|
||||
else
|
||||
std::cerr<<"validation layer: "<<pCallbackData->pMessage<<std::endl;
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
bool CreateDebugReportCallbackEXT(VkInstance instance,const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,const VkAllocationCallbacks *pAllocator,VkDebugReportCallbackEXT *pCallback)
|
||||
{
|
||||
auto func=(PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance,"vkCreateDebugReportCallbackEXT");
|
||||
if(func)
|
||||
{
|
||||
func(instance,pCreateInfo,pAllocator,pCallback);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool DestroyDebugReportCallbackEXT(VkInstance instance,VkDebugReportCallbackEXT callback,const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
auto func=(PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance,"vkDestroyDebugReportCallbackEXT");
|
||||
if(func)
|
||||
{
|
||||
func(instance,callback,pAllocator);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkDebugReportFlagsEXT msgFlags,VkDebugReportObjectTypeEXT objType,uint64_t srcObject,
|
||||
size_t location,int32_t msgCode,const char *pLayerPrefix,const char *pMsg,
|
||||
void *pUserData)
|
||||
{
|
||||
if(msgFlags&VK_DEBUG_REPORT_ERROR_BIT_EXT)
|
||||
{
|
||||
std::cout<<"ERROR: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_WARNING_BIT_EXT)
|
||||
{
|
||||
std::cout<<"WARNING: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
|
||||
{
|
||||
std::cout<<"PERFORMANCE WARNING: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
|
||||
{
|
||||
std::cout<<"INFO: ";
|
||||
}
|
||||
else if(msgFlags&VK_DEBUG_REPORT_DEBUG_BIT_EXT)
|
||||
{
|
||||
std::cout<<"DEBUG: ";
|
||||
}
|
||||
|
||||
std::cout<<"["<<pLayerPrefix<<"] Code "<<msgCode<<" : "<<pMsg<<std::endl;
|
||||
|
||||
/*
|
||||
* false indicates that layer should not bail-out of an
|
||||
* API call that had validation failures. This may mean that the
|
||||
* app dies inside the driver due to invalid parameter(s).
|
||||
* That's what would happen without validation layers, so we'll
|
||||
* keep that behavior here.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}//namespace
|
||||
|
||||
Instance *CreateInstance(const UTF8String &app_name)
|
||||
Instance *CreateInstance(const UTF8String &app_name,VKDebugOut *do)
|
||||
{
|
||||
VkApplicationInfo app_info;
|
||||
VkInstanceCreateInfo inst_info;
|
||||
CharPointerList ext_list;
|
||||
CharPointerList validation_list;
|
||||
|
||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
app_info.pNext = nullptr;
|
||||
@ -142,108 +26,36 @@ Instance *CreateInstance(const UTF8String &app_name)
|
||||
ext_list.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||
ext_list.Add(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
|
||||
const char *validation_layers[]=
|
||||
{
|
||||
// "VK_LAYER_LUNARG_api_dump",
|
||||
// "VK_LAYER_LUNARG_assistant_layer",
|
||||
"VK_LAYER_LUNARG_core_validation",
|
||||
// "VK_LAYER_LUNARG_device_simulation",
|
||||
// "VK_LAYER_LUNARG_monitor",
|
||||
"VK_LAYER_LUNARG_object_tracker",
|
||||
"VK_LAYER_LUNARG_standard_validation",
|
||||
"VK_LAYER_LUNARG_parameter_validation",
|
||||
// "VK_LAYER_LUNARG_vktrace",
|
||||
"VK_LAYER_RENDERDOC_Capture",
|
||||
validation_list.Add("VK_LAYER_KHRONOS_validation");
|
||||
validation_list.Add("VK_LAYER_LUNARG_standard_validation");
|
||||
validation_list.Add("VK_LAYER_RENDERDOC_Capture");
|
||||
|
||||
// "VK_LAYER_KHRONOS_validation",
|
||||
|
||||
// "VK_LAYER_NV_nsight-sys",
|
||||
|
||||
// "VK_LAYER_GOOGLE_unique_objects",
|
||||
// "VK_LAYER_GOOGLE_threading"
|
||||
};
|
||||
|
||||
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
inst_info.pNext = nullptr;
|
||||
inst_info.flags = 0;
|
||||
inst_info.pApplicationInfo = &app_info;
|
||||
inst_info.enabledExtensionCount = ext_list.GetCount();
|
||||
inst_info.ppEnabledExtensionNames = ext_list.GetData();
|
||||
inst_info.enabledLayerCount = sizeof(validation_layers)/sizeof(const char *);
|
||||
inst_info.ppEnabledLayerNames = validation_layers;
|
||||
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
inst_info.pNext = nullptr;
|
||||
inst_info.flags = 0;
|
||||
inst_info.pApplicationInfo = &app_info;
|
||||
inst_info.enabledExtensionCount = ext_list.GetCount();
|
||||
inst_info.ppEnabledExtensionNames = ext_list.GetData();
|
||||
inst_info.enabledLayerCount = validation_list.GetCount();
|
||||
inst_info.ppEnabledLayerNames = validation_list.GetData();
|
||||
|
||||
VkInstance inst;
|
||||
|
||||
if(vkCreateInstance(&inst_info,nullptr,&inst)==VK_SUCCESS)
|
||||
return(new Instance(inst,ext_list));
|
||||
{
|
||||
do->Init(inst);
|
||||
return(new Instance(inst,ext_list,do));
|
||||
}
|
||||
|
||||
return(nullptr);
|
||||
}
|
||||
|
||||
Instance::Instance(VkInstance i,CharPointerList &el)
|
||||
Instance::Instance(VkInstance i,CharPointerList &el,VKDebugOut *do)
|
||||
{
|
||||
inst=i;
|
||||
ext_list=el;
|
||||
|
||||
{
|
||||
uint32_t layerCount;
|
||||
vkEnumerateInstanceLayerProperties(&layerCount,nullptr);
|
||||
|
||||
layer_properties.SetCount(layerCount);
|
||||
vkEnumerateInstanceLayerProperties(&layerCount,layer_properties.GetData());
|
||||
|
||||
debug_out(layer_properties);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t prop_count;
|
||||
vkEnumerateInstanceExtensionProperties(nullptr,&prop_count,nullptr);
|
||||
|
||||
extension_properties.SetCount(prop_count);
|
||||
vkEnumerateInstanceExtensionProperties(nullptr,&prop_count,extension_properties.GetData());
|
||||
|
||||
debug_out(extension_properties);
|
||||
}
|
||||
|
||||
debug_report_callback=VK_NULL_HANDLE;
|
||||
{
|
||||
VkDebugReportCallbackCreateInfoEXT create_info;
|
||||
|
||||
create_info.sType =VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
|
||||
create_info.pNext =nullptr;
|
||||
|
||||
create_info.flags =VK_DEBUG_REPORT_ERROR_BIT_EXT
|
||||
|VK_DEBUG_REPORT_WARNING_BIT_EXT
|
||||
|VK_DEBUG_REPORT_DEBUG_BIT_EXT
|
||||
|VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||
|
||||
create_info.pfnCallback =dbgFunc;
|
||||
create_info.pUserData =nullptr;
|
||||
|
||||
CreateDebugReportCallbackEXT(inst,&create_info,nullptr,&debug_report_callback);
|
||||
}
|
||||
|
||||
debug_messenger=VK_NULL_HANDLE;
|
||||
{
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo;
|
||||
|
||||
createInfo.sType =VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
createInfo.pNext =nullptr;
|
||||
createInfo.flags =0;
|
||||
|
||||
createInfo.messageSeverity =VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
|
||||
createInfo.messageType =VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
|
||||
|VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
|
||||
createInfo.pfnUserCallback =debugCallback;
|
||||
createInfo.pUserData =nullptr;
|
||||
|
||||
CreateDebugUtilsMessengerEXT(inst,&createInfo,nullptr,&debug_messenger);
|
||||
}
|
||||
debug_out=do;
|
||||
|
||||
uint32_t gpu_count = 1;
|
||||
|
||||
@ -260,34 +72,13 @@ Instance::Instance(VkInstance i,CharPointerList &el)
|
||||
}
|
||||
|
||||
Instance::~Instance()
|
||||
{
|
||||
|
||||
SAFE_CLEAR(debug_out);
|
||||
|
||||
physical_devices.Clear();
|
||||
|
||||
if(debug_messenger)
|
||||
DestroyDebugUtilsMessengerEXT(inst,debug_messenger,nullptr);
|
||||
|
||||
if(debug_report_callback)
|
||||
DestroyDebugReportCallbackEXT(inst,debug_report_callback,nullptr);
|
||||
|
||||
vkDestroyInstance(inst,nullptr);
|
||||
}
|
||||
|
||||
const bool Instance::CheckLayerSupport(const UTF8String &layer_name)const
|
||||
{
|
||||
const uint32_t count=layer_properties.GetCount();
|
||||
VkLayerProperties *lp=layer_properties.GetData();
|
||||
|
||||
for(uint32_t i=0;i<count;i++)
|
||||
{
|
||||
if(layer_name==lp->layerName)
|
||||
return(true);
|
||||
|
||||
++lp;
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
const PhysicalDevice *Instance::GetDevice(VkPhysicalDeviceType type)const
|
||||
{
|
||||
const uint32_t count=physical_devices.GetCount();
|
||||
|
58
src/RenderDevice/Vulkan/VKProperties.cpp
Normal file
58
src/RenderDevice/Vulkan/VKProperties.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include<hgl/graph/vulkan/VK.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
|
||||
namespace
|
||||
{
|
||||
static List<VkLayerProperties> layer_properties;
|
||||
static List<VkExtensionProperties> extension_properties;
|
||||
}//namespace
|
||||
|
||||
const List<VkLayerProperties> &GetLayerProperties(){return layer_properties;}
|
||||
const List<VkExtensionProperties> &GetExtensionProperties(){return extension_properties;}
|
||||
|
||||
void InitVulkanProperties()
|
||||
{
|
||||
layer_properties.Clear();
|
||||
extension_properties.Clear();
|
||||
|
||||
{
|
||||
uint32_t layer_count;
|
||||
vkEnumerateInstanceLayerProperties(&layer_count,nullptr);
|
||||
|
||||
layer_properties.SetCount(layer_count);
|
||||
vkEnumerateInstanceLayerProperties(&layer_count,layer_properties.GetData());
|
||||
|
||||
debug_out(layer_properties);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t prop_count;
|
||||
vkEnumerateInstanceExtensionProperties(nullptr,&prop_count,nullptr);
|
||||
|
||||
extension_properties.SetCount(prop_count);
|
||||
vkEnumerateInstanceExtensionProperties(nullptr,&prop_count,extension_properties.GetData());
|
||||
|
||||
debug_out(extension_properties);
|
||||
}
|
||||
}
|
||||
|
||||
const bool CheckLayerSupport(const char *layer_name)
|
||||
{
|
||||
if(!layer_name||!*layer_name)
|
||||
return(false);
|
||||
|
||||
const uint32_t count=layer_properties.GetCount();
|
||||
VkLayerProperties *lp=layer_properties.GetData();
|
||||
|
||||
for(uint32_t i=0;i<count;i++)
|
||||
{
|
||||
if(strcmp(layer_name,lp->layerName)==0)
|
||||
return(true);
|
||||
|
||||
++lp;
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
VK_NAMESPACE_END
|
2
src/Tools/ShaderCompiler/CMakeLists.txt
Normal file
2
src/Tools/ShaderCompiler/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
add_executable(ShaderCompiler main.cpp)
|
||||
target_link_libraries((ShaderCompiler PRIVATE ${ULRE}
|
0
src/Tools/ShaderCompiler/main.cpp
Normal file
0
src/Tools/ShaderCompiler/main.cpp
Normal file
7
src/Tools/TexConv/CMakeLists.txt
Normal file
7
src/Tools/TexConv/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
add_executable(TexConv MainUnit.cpp ${HGL_GRAPHICS_MAIN_SOURCE})
|
||||
|
||||
target_compile_definitions(TexConv PRIVATE "-DIL_STATIC_LIB")
|
||||
target_include_directories(TexConv PRIVATE ${CMGDK_PATH}/src/PlugIn/Image.Monolayer/DevIL/include)
|
||||
target_link_libraries(TexConv ${HGL_GRAPHICS_LIB} DevIL)
|
||||
|
||||
SET_TARGET_PROPERTIES(TexConv PROPERTIES WIN32_EXECUTABLE "true")
|
708
src/Tools/TexConv/MainUnit.cpp
Normal file
708
src/Tools/TexConv/MainUnit.cpp
Normal file
@ -0,0 +1,708 @@
|
||||
#include<hgl/Graphics.h>
|
||||
|
||||
#include<hgl/graph/Render.h> //SetClearColor
|
||||
#include<hgl/graph/Shader.h> //GLSL
|
||||
#include<hgl/graph/Texture.h> //Texture
|
||||
#include<hgl/graph/Material.h> //Material
|
||||
#include<hgl/graph/VertexBuffer.h> //VB3f/VB4f
|
||||
#include<hgl/graph/Renderable.h> //Renderable
|
||||
#include<hgl/Time.h> //GetMicroTime
|
||||
|
||||
#include<hgl/io/FileOutputStream.h>
|
||||
#include<hgl/ut/CmdParse.h>
|
||||
#include<hgl/graph/Bitmap.h>
|
||||
#include<hgl/Str.h>
|
||||
#include<hgl/Info.h> //GetString
|
||||
|
||||
#include<IL/il.h>
|
||||
#include<IL/ilu.h>
|
||||
|
||||
#include<string.h>
|
||||
|
||||
using namespace hgl;
|
||||
using namespace hgl::io;
|
||||
using namespace hgl::util;
|
||||
using namespace hgl::graph;
|
||||
using namespace hgl::filesystem;
|
||||
|
||||
const TextureFormat *default_r8 =&TextureFormatInfoList[HGL_SF_R8];
|
||||
const TextureFormat *default_rg8 =&TextureFormatInfoList[HGL_SF_RG8];
|
||||
const TextureFormat *default_rgb8 =&TextureFormatInfoList[HGL_SF_RGB8];
|
||||
const TextureFormat *default_rgba8 =&TextureFormatInfoList[HGL_SF_RGBA8];
|
||||
|
||||
const TextureFormat *default_r16 =&TextureFormatInfoList[HGL_SF_R16];
|
||||
const TextureFormat *default_r32f =&TextureFormatInfoList[HGL_SF_R32F];
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const TextureFormat * glfmt[4] ={NULL,NULL,NULL,NULL}; //选中格式
|
||||
bool gen_mipmaps =false; //是否产生mipmaps
|
||||
|
||||
bool only_view =false; //仅显示
|
||||
|
||||
bool use_color_key=false; //是否使用ColorKey
|
||||
uint8 color_key[3]; //ColorKey颜色
|
||||
|
||||
const float texcoord[] ={0.0f,0.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f, 0.0f,1.0f};
|
||||
|
||||
VertexArray * va =NULL;
|
||||
Renderable * render_obj =NULL;
|
||||
Material * mtl =NULL;
|
||||
Texture2D * tex =NULL;
|
||||
VB2f * vertex =NULL;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//OpenIL数据
|
||||
|
||||
uint il_index=0; //图片索引
|
||||
int il_width,il_height,il_bit;
|
||||
uint il_format=0;
|
||||
uint il_type=0;
|
||||
uint il_pal_type=0;
|
||||
uint il_pal_color_num=0;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//统计数据
|
||||
|
||||
int max_pixels=0; //最大像素数
|
||||
uint8 *image_data=NULL; //图像数据
|
||||
|
||||
int max_bytes=0; //最大字节数
|
||||
uint8 *texture_data=NULL; //贴图数据
|
||||
|
||||
int convert_count=0; //转换总数
|
||||
int bytes_count=0; //总字节数
|
||||
int cbytes_count=0; //转换后总字节数
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const TextureFormat *CheckOpenGLCoreFormat(const CmdParse &cmd,const os_char *flag,const TextureFormat *default_tf)
|
||||
{
|
||||
OSString fmtstr;
|
||||
|
||||
if(!cmd.GetString(flag,fmtstr))return(nullptr);
|
||||
|
||||
#if HGL_OS==HGL_OS_Windows
|
||||
UTF8String str=to_u8(fmtstr);
|
||||
|
||||
const TextureFormat *result=GetTextureFormat(str.c_str());
|
||||
#else
|
||||
const TextureFormat *result=GetTextureFormat(fmtstr.c_str());
|
||||
#endif//HGL_OS==HGL_OS_Windows
|
||||
|
||||
if(result)return(result);
|
||||
|
||||
return default_tf;
|
||||
}
|
||||
|
||||
void CheckOpenGLCoreFormat(const CmdParse &cmd)
|
||||
{
|
||||
//指定格式
|
||||
glfmt[0]=CheckOpenGLCoreFormat(cmd,OS_TEXT("/R:"), &TextureFormatInfoList[HGL_SF_R8]);
|
||||
glfmt[1]=CheckOpenGLCoreFormat(cmd,OS_TEXT("/RG:"), &TextureFormatInfoList[HGL_SF_RG8]);
|
||||
glfmt[2]=CheckOpenGLCoreFormat(cmd,OS_TEXT("/RGB:"), &TextureFormatInfoList[HGL_SF_RGB8]);
|
||||
glfmt[3]=CheckOpenGLCoreFormat(cmd,OS_TEXT("/RGBA:"), &TextureFormatInfoList[HGL_SF_RGBA8]);
|
||||
}
|
||||
|
||||
void CheckColorKey(const CmdParse &cmd)
|
||||
{
|
||||
OSString ckstr;
|
||||
|
||||
if(!cmd.GetString(OS_TEXT("/ColorKey:"),ckstr))return;
|
||||
|
||||
os_char rgbstr[6];
|
||||
|
||||
hgl_cpy(rgbstr,ckstr.c_str(),6); //注意:hgl_cpy是跨类型复制的,不要替换成strcpy或memcpy
|
||||
|
||||
ParseHexStr(color_key[0],rgbstr+0);
|
||||
ParseHexStr(color_key[1],rgbstr+2);
|
||||
ParseHexStr(color_key[2],rgbstr+4);
|
||||
|
||||
use_color_key=true;
|
||||
}
|
||||
|
||||
bool CheckSameAlpha(uint8 *data,uint count)
|
||||
{
|
||||
uint8 *p=data;
|
||||
|
||||
while(count--)
|
||||
{
|
||||
if(*p!=*data)return(false);
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测RGB数据是否一致
|
||||
*/
|
||||
bool CheckSameRGB(uint8 *data,int color,uint count)
|
||||
{
|
||||
uint8 *p=data;
|
||||
|
||||
while(count--)
|
||||
{
|
||||
if(memcmp(data,p,color-1))
|
||||
return(false);
|
||||
|
||||
p+=color;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void MixLA(uint8 *lum,uint8 *alpha,int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
{
|
||||
lum++;
|
||||
*lum++=*alpha++;
|
||||
}
|
||||
}
|
||||
|
||||
void MixRGBA(uint8 *rgba,uint8 *alpha,int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
{
|
||||
rgba+=3;
|
||||
*rgba++=*alpha++;
|
||||
}
|
||||
}
|
||||
|
||||
void FlipData(uint8 *data,int line_bytes,int row_number)
|
||||
{
|
||||
int i;
|
||||
uint8 *temp=new uint8[line_bytes];
|
||||
uint8 *end=data+line_bytes*(row_number-1);
|
||||
|
||||
for(i=0;i<row_number/2;i++)
|
||||
{
|
||||
memcpy(temp,data,line_bytes);
|
||||
memcpy(data,end,line_bytes);
|
||||
memcpy(end,temp,line_bytes);
|
||||
|
||||
data+=line_bytes;
|
||||
end-=line_bytes;
|
||||
}
|
||||
|
||||
delete[] temp;
|
||||
}
|
||||
|
||||
void ConvertPixelFormat()
|
||||
{
|
||||
uint fmt=il_format;
|
||||
|
||||
if(il_format==IL_BGR)
|
||||
fmt=IL_RGB;
|
||||
else
|
||||
if(il_format==IL_BGRA)
|
||||
fmt=IL_RGBA;
|
||||
|
||||
if(il_format==IL_RGBA||il_format==IL_BGRA||il_format==IL_LUMINANCE_ALPHA)
|
||||
{
|
||||
uint8 *alpha=ilGetAlpha(IL_UNSIGNED_BYTE);
|
||||
uint count=il_width*il_height;
|
||||
uint color=(il_format==IL_LUMINANCE_ALPHA?2:3);
|
||||
|
||||
if(CheckSameAlpha(alpha,count)) //检测ALPHA全部一样的,将RGBA转为RGB,将LA转为L
|
||||
{
|
||||
if(il_format==IL_RGBA||il_format==IL_BGRA)
|
||||
{
|
||||
fmt=IL_RGB;
|
||||
}
|
||||
else
|
||||
if(il_format==IL_LUMINANCE_ALPHA)
|
||||
{
|
||||
fmt=IL_LUMINANCE;
|
||||
}
|
||||
}
|
||||
else //如果ALPHA不同,检测颜色是否相同,如果相同只留ALPHA
|
||||
{
|
||||
uint8 *data=ilGetData();
|
||||
uint count=il_width*il_height;
|
||||
|
||||
if(CheckSameRGB(data,color,count))
|
||||
fmt=IL_ALPHA;
|
||||
}
|
||||
|
||||
if(alpha)free(alpha);
|
||||
}
|
||||
|
||||
if(il_format==IL_RGB||il_format==IL_BGR)
|
||||
{
|
||||
if(CheckMono(ilGetData(),3,il_width,il_height))
|
||||
fmt=IL_LUMINANCE;
|
||||
}
|
||||
|
||||
if(fmt!=IL_ALPHA //只有ALPHA就不检测
|
||||
&&(il_format==IL_RGBA||il_format==IL_BGRA))
|
||||
{
|
||||
if(CheckMono(ilGetData(),4,il_width,il_height))
|
||||
{
|
||||
if(fmt==IL_RGB) //前面一段代码已经将alpha砍掉了
|
||||
fmt=IL_LUMINANCE;
|
||||
else
|
||||
fmt=IL_LUMINANCE_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
if(fmt!=il_format)
|
||||
{
|
||||
ilConvertImage(fmt,il_type);
|
||||
|
||||
il_format=fmt;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckPalette()
|
||||
{
|
||||
uint pal=il_pal_type;
|
||||
|
||||
if(il_pal_type==IL_PAL_BGR24||il_pal_type==IL_PAL_BGR32||il_pal_type==IL_PAL_RGB32)
|
||||
pal=IL_PAL_RGB24;
|
||||
else
|
||||
if(il_pal_type==IL_PAL_BGRA32)
|
||||
pal=IL_PAL_RGBA32;
|
||||
|
||||
if(pal!=il_pal_type)
|
||||
{
|
||||
ilConvertPal(pal);
|
||||
|
||||
il_pal_type=pal;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTexture2DToFile(const os_char *filename,void *texture_data,uint width,uint height,const char *format,uint bytes,bool include_color_key)
|
||||
{
|
||||
os_char tex_fn[HGL_MAX_PATH];
|
||||
char fmt_str[17];
|
||||
|
||||
replace_extname(tex_fn,filename,HGL_MAX_PATH,OS_TEXT("Tex2D"));
|
||||
|
||||
FileOutputStream fs;
|
||||
DataOutputStream *dos;
|
||||
|
||||
if(!fs.CreateTrunc(tex_fn))
|
||||
{
|
||||
LOG_INFO(OS_TEXT("\tCreateFile(")+OSString(tex_fn)+OS_TEXT(") error!"));
|
||||
return;
|
||||
}
|
||||
|
||||
dos=new LEDataOutputStream(&fs);
|
||||
|
||||
memset(fmt_str,0,17);
|
||||
hgl::strcpy(fmt_str,16,format);
|
||||
|
||||
dos->Write("Tex\x1A",4);
|
||||
dos->WriteUint8(1); //版本号
|
||||
dos->WriteBool(false); //是否有mipmaps
|
||||
dos->Write(fmt_str,16); //格式
|
||||
dos->WriteUint32(bytes); //字节数
|
||||
|
||||
if(include_color_key)
|
||||
{
|
||||
dos->WriteBool(true);
|
||||
dos->WriteUint8(color_key,3);
|
||||
|
||||
LOG_INFO(OS_TEXT("\tColor Key: true"));
|
||||
}
|
||||
else
|
||||
{
|
||||
dos->Write("\0\0\0\0",4);
|
||||
}
|
||||
|
||||
dos->WriteUint32(width); //宽
|
||||
dos->WriteUint32(height); //高
|
||||
|
||||
dos->Write(texture_data,bytes);
|
||||
delete dos;
|
||||
|
||||
LOG_INFO(OS_TEXT("\tSave to ")+OSString(tex_fn));
|
||||
}
|
||||
|
||||
int ConvertImage(const os_char *filename)
|
||||
{
|
||||
bool confirm_color_key=false;
|
||||
|
||||
uint pixels=0;
|
||||
const TextureFormat *curfmt=nullptr;
|
||||
const TextureFormat *tarfmt=nullptr;
|
||||
|
||||
LOG_INFO(OS_TEXT("File: ")+OSString(filename));
|
||||
|
||||
ilGenImages(1,&il_index);
|
||||
ilBindImage(il_index);
|
||||
|
||||
if(ilLoadImage(filename))
|
||||
{
|
||||
il_width =ilGetInteger(IL_IMAGE_WIDTH);
|
||||
il_height =ilGetInteger(IL_IMAGE_HEIGHT);
|
||||
il_bit =ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
|
||||
il_format =ilGetInteger(IL_IMAGE_FORMAT);
|
||||
il_type =ilGetInteger(IL_IMAGE_TYPE);
|
||||
|
||||
if(ilGetInteger(IL_IMAGE_ORIGIN)==IL_ORIGIN_LOWER_LEFT)
|
||||
iluFlipImage();
|
||||
|
||||
LOG_INFO(OS_TEXT("\twidth: ")+OSString(il_width));
|
||||
LOG_INFO(OS_TEXT("\theight: ")+OSString(il_height));
|
||||
|
||||
pixels=il_width*il_height;
|
||||
|
||||
if(pixels>max_pixels)
|
||||
SAFE_CLEAR_ARRAY(image_data);
|
||||
|
||||
if(!image_data)
|
||||
{
|
||||
image_data=new uint8[pixels*4*4];
|
||||
max_pixels=pixels;
|
||||
}
|
||||
|
||||
if(il_format!=IL_COLOR_INDEX)
|
||||
{
|
||||
if(il_format==IL_LUMINANCE )
|
||||
{
|
||||
if(il_type==IL_UNSIGNED_BYTE)
|
||||
curfmt=default_r8;
|
||||
else
|
||||
if(il_type==IL_UNSIGNED_SHORT)
|
||||
curfmt=default_r16;
|
||||
else
|
||||
if(il_type==IL_FLOAT)
|
||||
curfmt=default_r32f;
|
||||
else
|
||||
{
|
||||
ilConvertImage(IL_LUMINANCE,IL_UNSIGNED_BYTE);
|
||||
il_type=IL_UNSIGNED_BYTE;
|
||||
|
||||
curfmt=default_r8;
|
||||
}
|
||||
|
||||
tarfmt=(glfmt[0]?glfmt[0]:curfmt);
|
||||
|
||||
memcpy(image_data,ilGetData(),pixels*curfmt->source_bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(il_type!=IL_UNSIGNED_BYTE)
|
||||
{
|
||||
ilConvertImage(il_format,IL_UNSIGNED_BYTE);
|
||||
il_type=IL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
ConvertPixelFormat();
|
||||
|
||||
if(il_format==IL_LUMINANCE )
|
||||
{
|
||||
curfmt=default_r8;
|
||||
tarfmt=(glfmt[0]?glfmt[0]:curfmt);
|
||||
|
||||
memcpy(image_data,ilGetData(),pixels);
|
||||
}
|
||||
else
|
||||
if(il_format==IL_ALPHA )
|
||||
{
|
||||
curfmt=default_r8;
|
||||
tarfmt=(glfmt[0]?glfmt[0]:curfmt);
|
||||
|
||||
memcpy(image_data,ilGetAlpha(GL_UNSIGNED_BYTE),pixels);
|
||||
}
|
||||
else
|
||||
if(il_format==IL_LUMINANCE_ALPHA)
|
||||
{
|
||||
curfmt=default_rg8;
|
||||
tarfmt=(glfmt[1]?glfmt[1]:curfmt);
|
||||
|
||||
uint8 *alpha=ilGetAlpha(GL_UNSIGNED_BYTE);
|
||||
|
||||
memcpy(image_data,ilGetData(),pixels*2);
|
||||
|
||||
MixLA(image_data,alpha,pixels);
|
||||
|
||||
free(alpha);
|
||||
}
|
||||
else
|
||||
if(il_format==IL_RGB )
|
||||
{
|
||||
curfmt=default_rgb8;
|
||||
tarfmt=(glfmt[2]?glfmt[2]:curfmt);
|
||||
|
||||
memcpy(image_data,ilGetData(),pixels*3);
|
||||
|
||||
if(use_color_key) //检测ColorKey是否存在
|
||||
{
|
||||
unsigned char *p=image_data;
|
||||
|
||||
for(int i=0;i<pixels;i++)
|
||||
{
|
||||
if((image_data[0]==color_key[0])
|
||||
&&(image_data[1]==color_key[1])
|
||||
&&(image_data[2]==color_key[2]))
|
||||
{
|
||||
confirm_color_key=true;
|
||||
break;
|
||||
}
|
||||
|
||||
p+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(il_format==IL_RGBA )
|
||||
{
|
||||
curfmt=default_rgba8;
|
||||
tarfmt=(glfmt[3]?glfmt[3]:curfmt);
|
||||
|
||||
uint8 *alpha=ilGetAlpha(GL_UNSIGNED_BYTE);
|
||||
|
||||
memcpy(image_data,ilGetData(),pixels*4);
|
||||
|
||||
MixRGBA(image_data,alpha,pixels);
|
||||
|
||||
free(alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
curfmt=NULL;
|
||||
tarfmt=NULL;
|
||||
|
||||
LOG_INFO("\tsource format error");
|
||||
|
||||
ilDeleteImages(1,&il_index);
|
||||
return(0);
|
||||
}
|
||||
}//LUMINANCE
|
||||
|
||||
tex->SetImage(il_width,il_height,image_data,pixels*curfmt->source_bytes,curfmt->tsf,tarfmt->video_format);
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
LOG_INFO(OS_TEXT("\tcolor format = ")+to_u16(curfmt->name)+OS_TEXT(" bytes = ")+OSString(curfmt->source_bytes*il_width*il_height));
|
||||
LOG_INFO(OS_TEXT("\ttarget format = ")+to_u16(tarfmt->name));
|
||||
#else
|
||||
LOG_INFO(OS_TEXT("\tcolor format = ")+OSString(curfmt->name)+OS_TEXT(" bytes = ")+OSString(curfmt->source_bytes*il_width*il_height));
|
||||
LOG_INFO(OS_TEXT("\ttarget format = ")+OSString(tarfmt->name));
|
||||
#endif//HGL_OS == HGL_OS_Windows
|
||||
|
||||
int bytes=tex->GetImage(NULL,tarfmt->tsf);
|
||||
|
||||
if(bytes>0)
|
||||
{
|
||||
LOG_INFO(OS_TEXT("\toutput bytes = ")+OSString(bytes));
|
||||
|
||||
if(bytes>max_bytes)
|
||||
SAFE_CLEAR_ARRAY(texture_data);
|
||||
|
||||
if(!texture_data)
|
||||
{
|
||||
texture_data=new uint8[bytes];
|
||||
max_bytes=bytes;
|
||||
}
|
||||
|
||||
tex->GetImage(texture_data,tarfmt->tsf);
|
||||
|
||||
SaveTexture2DToFile(filename,texture_data,il_width,il_height,tarfmt->name,bytes,confirm_color_key);
|
||||
|
||||
convert_count++;
|
||||
bytes_count+=il_width*il_height*curfmt->source_bytes;
|
||||
cbytes_count+=bytes;
|
||||
}
|
||||
}
|
||||
// else //索引色贴图
|
||||
// {
|
||||
// il_pal_type =ilGetInteger(IL_PALETTE_TYPE); //调色板类型
|
||||
// il_pal_color_num=ilGetInteger(IL_PALETTE_NUM_COLS); //颜色数量
|
||||
//
|
||||
// LOG_INFO(OS_TEXT("\tpal color number = ")+OSString(il_pal_color_num));
|
||||
//
|
||||
// if(il_pal_color_num==16||il_pal_color_num==256)
|
||||
// {
|
||||
// CheckPalette();
|
||||
//
|
||||
// if(il_pal_type==IL_PAL_RGB24 &&il_pal_color_num== 16)curfmt=GetFormat("16RGB");else
|
||||
//
|
||||
// if(il_pal_type==IL_PAL_RGBA32&&il_pal_color_num== 16)curfmt=GetFormat("16RGBA");else
|
||||
// if(il_pal_type==IL_PAL_RGB24 &&il_pal_color_num==256)curfmt=GetFormat("256RGB");else
|
||||
// if(il_pal_type==IL_PAL_RGBA32&&il_pal_color_num==256)curfmt=GetFormat("256RGBA");else
|
||||
// curfmt=NULL;
|
||||
//
|
||||
// if(curfmt)
|
||||
// LOG_INFO(OS_TEXT("\tcolor format = ")+OSString(curfmt->name));
|
||||
// }
|
||||
// else
|
||||
// curfmt=NULL;
|
||||
// }
|
||||
|
||||
if(!curfmt)
|
||||
LOG_INFO("\tformat error!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("\tLoad File error!");
|
||||
}
|
||||
|
||||
ilDeleteImages(1,&il_index);
|
||||
return(0);
|
||||
}
|
||||
|
||||
class EnumFileConfigApp:public EnumFileConfig
|
||||
{
|
||||
public:
|
||||
|
||||
GraphicsApplication *app;
|
||||
|
||||
using EnumFileConfig::EnumFileConfig;
|
||||
};
|
||||
|
||||
void EnumConvertImage(EnumFileConfig *efc,FileInfo &fi)
|
||||
{
|
||||
EnumFileConfigApp *efca=(EnumFileConfigApp *)efc;
|
||||
|
||||
GraphicsApplication *gapp=efca->app;
|
||||
|
||||
ConvertImage(fi.fullname);
|
||||
|
||||
render_obj->AutoCreateShader();
|
||||
|
||||
ClearColorDepthBuffer();
|
||||
|
||||
const int l=(GetScreenWidth()-il_width)/2;
|
||||
const int t=(GetScreenHeight()-il_height)/2;
|
||||
|
||||
vertex->Begin();
|
||||
vertex->WriteRect(l,t,il_width,il_height);
|
||||
vertex->End();
|
||||
|
||||
DirectRender2D(render_obj);
|
||||
|
||||
gapp->SwapBuffer();
|
||||
gapp->WaitActive();
|
||||
}
|
||||
|
||||
HGL_GRAPHICS_MAIN(sii,app,args)
|
||||
{
|
||||
CmdParse cmd(args);
|
||||
|
||||
bool sub=false;
|
||||
|
||||
sii.info.ProjectName=U8_TEXT("贴图转换");
|
||||
sii.info.ProjectCode=OS_TEXT("Texture Converter");
|
||||
sii.info.ProjectVersion=U8_TEXT("1.01");
|
||||
|
||||
if(!app.Init(&sii))return(-1);
|
||||
|
||||
LOG_INFO("argc="+UTF8String(args.GetCount()));
|
||||
for(int i=0;i<args.GetCount();i++)
|
||||
LOG_INFO(OS_TEXT("argv[")+OSString(i)+OS_TEXT("] ")+args[i]);
|
||||
|
||||
if(args.GetCount()<1)
|
||||
{
|
||||
char space[33];
|
||||
constexpr uint STR_HINT_MAX=128+(32*HGL_SF_END);
|
||||
char *hint=new char[STR_HINT_MAX];
|
||||
|
||||
hgl::strcpy(hint,STR_HINT_MAX,
|
||||
"Command format:\n"
|
||||
"\tTexConv <filename or pathname> [/s] [/view] [/R:?] [/RG:?] [/RGB:?] [/RGBA:?]\n"
|
||||
"\n"
|
||||
"Params:\n"
|
||||
"\t/s : proc sub-directory\n"
|
||||
"\n"
|
||||
"support format:\n\n");
|
||||
|
||||
int count=0;
|
||||
int len;
|
||||
memset(space,' ',32);
|
||||
space[32]=0;
|
||||
|
||||
for(int i=HGL_SF_NONE+1;i<HGL_SF_END;i++)
|
||||
{
|
||||
if(TextureFormatInfoList[i].name[0]==0)
|
||||
{
|
||||
if(count==0)
|
||||
hgl::strcat(hint,STR_HINT_MAX,'\n');
|
||||
else
|
||||
hgl::strcat(hint,STR_HINT_MAX,"\n\n",2);
|
||||
count=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
len=hgl::strlen(TextureFormatInfoList[i].name);
|
||||
hgl::strcat(hint,STR_HINT_MAX,TextureFormatInfoList[i].name,len);
|
||||
hgl::strcat(hint,STR_HINT_MAX,space,16-len);
|
||||
|
||||
++count;
|
||||
if(count==4)
|
||||
{
|
||||
hgl::strcat(hint,STR_HINT_MAX,'\n');
|
||||
count=0;
|
||||
}
|
||||
else
|
||||
hgl::strcat(hint,STR_HINT_MAX,'\t');
|
||||
}
|
||||
|
||||
//MessageBoxA(nullptr,hint,"TexConv",MB_OK|MB_ICONINFORMATION);
|
||||
LOG_ERROR(hint);
|
||||
|
||||
delete[] hint;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(cmd.Find(OS_TEXT("/s"))!=-1)sub=true; //检测是否处理子目录
|
||||
|
||||
if(cmd.Find(OS_TEXT("/view"))!=-1)only_view=true; //检测是否仅显示
|
||||
if(cmd.Find(OS_TEXT("/mip"))!=-1)gen_mipmaps=true; //检测是否生成mipmaps
|
||||
|
||||
CheckColorKey(cmd);
|
||||
CheckOpenGLCoreFormat(cmd); //检测推荐格式
|
||||
|
||||
ilInit();
|
||||
|
||||
OSString cur_path=info::GetString(info::hfsStartPath);
|
||||
|
||||
va=new VertexArray(HGL_PRIM_TRIANGLES);
|
||||
va->SetVertexBuffer(vbtVertex,vertex=new VB2f(6,0,HGL_DYNAMIC_DRAW));
|
||||
va->SetVertexBuffer(vbtDiffuseTexCoord,new VB2f(6,texcoord));
|
||||
|
||||
tex=CreateTexture2D();
|
||||
|
||||
mtl=new Material;
|
||||
|
||||
mtl->SetColorMaterial(false);
|
||||
mtl->SetTexture(mtcDiffuse,tex);
|
||||
|
||||
render_obj=new Renderable(va,mtl);
|
||||
|
||||
render_obj->SetMaterial(mtl);
|
||||
render_obj->SetTexCoord(mtcDiffuse,vbtDiffuseTexCoord);
|
||||
|
||||
double start_time=GetMicroTime();
|
||||
double end_time;
|
||||
|
||||
EnumFileConfigApp efc;
|
||||
|
||||
efc.app =&app;
|
||||
|
||||
efc.folder_name =cur_path;
|
||||
efc.find_name =args[0];
|
||||
efc.proc_file =true;
|
||||
efc.sub_folder =sub;
|
||||
efc.cb_file =EnumConvertImage;
|
||||
|
||||
EnumFile(&efc);
|
||||
|
||||
end_time=GetTime();
|
||||
|
||||
LOG_INFO(OS_TEXT("总计转换图片")+OSString(convert_count)
|
||||
+OS_TEXT("张,总计处理原始数据")+OSString(bytes_count)
|
||||
+OS_TEXT("字节,转换后")+OSString(cbytes_count)
|
||||
+OS_TEXT("字节,总计耗时")+OSString(end_time-start_time)+OS_TEXT("秒"));
|
||||
|
||||
delete[] image_data;
|
||||
delete[] texture_data;
|
||||
delete tex;
|
||||
delete render_obj;
|
||||
|
||||
ilShutDown();
|
||||
|
||||
return(0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user