updates
This commit is contained in:
Submodule CMSceneGraph updated: 89b649ddcd...88862bd7b2
@@ -37,6 +37,9 @@ CreateProject(10.InlineGeometryScene InlineGeometryScene.cpp)
|
|||||||
CreateProject(11.Atomsphere Atomsphere.cpp)
|
CreateProject(11.Atomsphere Atomsphere.cpp)
|
||||||
|
|
||||||
CreateProject(12.RectanglePrimitive RectanglePrimitive.cpp)
|
CreateProject(12.RectanglePrimitive RectanglePrimitive.cpp)
|
||||||
|
|
||||||
|
CreateProject(13.DrawTile DrawTile.cpp)
|
||||||
|
|
||||||
CreateProject(13.DrawText DrawText.cpp)
|
CreateProject(13.DrawText DrawText.cpp)
|
||||||
|
|
||||||
IF(SUPPORT_QT_VULKAN)
|
IF(SUPPORT_QT_VULKAN)
|
||||||
|
177
example/Vulkan/DrawTile.cpp
Normal file
177
example/Vulkan/DrawTile.cpp
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
// DrawTile
|
||||||
|
// 该示例使用TileData,演示多个tile图片在一张纹理上
|
||||||
|
|
||||||
|
#include<hgl/type/StringList.h>
|
||||||
|
#include<hgl/graph/TextureLoader.h>
|
||||||
|
|
||||||
|
//#include"VulkanAppFramework.h"
|
||||||
|
//#include<hgl/graph/vulkan/VKTexture.h>
|
||||||
|
//#include<hgl/graph/vulkan/VKSampler.h>
|
||||||
|
//#include<hgl/math/Math.h>
|
||||||
|
|
||||||
|
using namespace hgl;
|
||||||
|
using namespace hgl::graph;
|
||||||
|
/*
|
||||||
|
VK_NAMESPACE_BEGIN
|
||||||
|
Texture2D *CreateTextureFromFile(Device *device,const OSString &filename);
|
||||||
|
VK_NAMESPACE_END
|
||||||
|
|
||||||
|
constexpr uint32_t SCREEN_SIZE=512;
|
||||||
|
|
||||||
|
constexpr uint32_t VERTEX_COUNT=1;
|
||||||
|
|
||||||
|
constexpr float BORDER=0.1f;
|
||||||
|
|
||||||
|
constexpr float vertex_data[4]=
|
||||||
|
{
|
||||||
|
SCREEN_SIZE*BORDER, SCREEN_SIZE*BORDER,
|
||||||
|
SCREEN_SIZE*(1.0-BORDER), SCREEN_SIZE*(1.0-BORDER)
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr float tex_coord_data[4]=
|
||||||
|
{
|
||||||
|
0,0,1,1
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestApp:public VulkanApplicationFramework
|
||||||
|
{
|
||||||
|
Camera cam;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
vulkan::Material * material =nullptr;
|
||||||
|
vulkan::Texture2D * texture =nullptr;
|
||||||
|
vulkan::Sampler * sampler =nullptr;
|
||||||
|
vulkan::MaterialInstance * material_instance =nullptr;
|
||||||
|
vulkan::Renderable * render_obj =nullptr;
|
||||||
|
vulkan::Buffer * ubo_world_matrix =nullptr;
|
||||||
|
|
||||||
|
vulkan::Pipeline * pipeline =nullptr;
|
||||||
|
|
||||||
|
vulkan::VertexAttribBuffer *vertex_buffer =nullptr;
|
||||||
|
vulkan::VertexAttribBuffer *tex_coord_buffer =nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool InitMaterial()
|
||||||
|
{
|
||||||
|
material=shader_manage->CreateMaterial( OS_TEXT("res/shader/DrawRect2D.vert"),
|
||||||
|
OS_TEXT("res/shader/DrawRect2D.geom"),
|
||||||
|
OS_TEXT("res/shader/FlatTexture.frag"));
|
||||||
|
if(!material)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
render_obj=material->CreateRenderable(VERTEX_COUNT);
|
||||||
|
material_instance=material->CreateInstance();
|
||||||
|
|
||||||
|
texture=vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/lena.Tex2D"));
|
||||||
|
|
||||||
|
sampler=db->CreateSampler();
|
||||||
|
|
||||||
|
material_instance->BindSampler("tex",texture,sampler);
|
||||||
|
material_instance->BindUBO("world",ubo_world_matrix);
|
||||||
|
material_instance->Update();
|
||||||
|
|
||||||
|
db->Add(material);
|
||||||
|
db->Add(material_instance);
|
||||||
|
db->Add(texture);
|
||||||
|
db->Add(render_obj);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InitUBO()
|
||||||
|
{
|
||||||
|
const VkExtent2D extent=sc_render_target->GetExtent();
|
||||||
|
|
||||||
|
cam.width=extent.width;
|
||||||
|
cam.height=extent.height;
|
||||||
|
|
||||||
|
cam.Refresh();
|
||||||
|
|
||||||
|
ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&cam.matrix);
|
||||||
|
|
||||||
|
if(!ubo_world_matrix)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitVBO()
|
||||||
|
{
|
||||||
|
vertex_buffer =db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,vertex_data);
|
||||||
|
tex_coord_buffer=db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,tex_coord_data);
|
||||||
|
|
||||||
|
render_obj->Set("Vertex",vertex_buffer);
|
||||||
|
render_obj->Set("TexCoord",tex_coord_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InitPipeline()
|
||||||
|
{
|
||||||
|
AutoDelete<vulkan::PipelineCreater>
|
||||||
|
pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target);
|
||||||
|
pipeline_creater->CloseCullFace();
|
||||||
|
pipeline_creater->Set(PRIM_RECTANGLES);
|
||||||
|
|
||||||
|
pipeline=pipeline_creater->Create();
|
||||||
|
|
||||||
|
db->Add(pipeline);
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Init()
|
||||||
|
{
|
||||||
|
if(!VulkanApplicationFramework::Init(SCREEN_SIZE,SCREEN_SIZE))
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
if(!InitUBO())
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
if(!InitMaterial())
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
InitVBO();
|
||||||
|
|
||||||
|
if(!InitPipeline())
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
BuildCommandBuffer(pipeline,material_instance,render_obj);
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resize(int w,int h)override
|
||||||
|
{
|
||||||
|
cam.width=w;
|
||||||
|
cam.height=h;
|
||||||
|
|
||||||
|
cam.Refresh();
|
||||||
|
|
||||||
|
ubo_world_matrix->Write(&cam.matrix);
|
||||||
|
|
||||||
|
BuildCommandBuffer(pipeline,material_instance,render_obj);
|
||||||
|
}
|
||||||
|
};//class TestApp:public VulkanApplicationFramework
|
||||||
|
|
||||||
|
int main(int,char **)
|
||||||
|
{
|
||||||
|
TestApp app;
|
||||||
|
|
||||||
|
if(!app.Init())
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
while(app.Run());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
UTF8StringList sl;
|
||||||
|
|
||||||
|
int line=LoadStringListFromTextFile(sl,OS_TEXT("res/image/icon/freepik/list.txt"));
|
||||||
|
|
||||||
|
ObjectList<BitmapData> bmp_list;
|
||||||
|
}
|
59
inc/hgl/graph/TextureLoader.h
Normal file
59
inc/hgl/graph/TextureLoader.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef HGL_GRAPH_TEXTURE_LOADER_INCLUDE
|
||||||
|
#define HGL_GRAPH_TEXTURE_LOADER_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/io/InputStream.h>
|
||||||
|
#include<hgl/type/BaseString.h>
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace graph
|
||||||
|
{
|
||||||
|
#pragma pack(push,1)
|
||||||
|
struct Tex2DFileHeader
|
||||||
|
{
|
||||||
|
uint8 id[6]; ///<Tex2D\x1A
|
||||||
|
uint8 version; ///<必须为2
|
||||||
|
bool mipmaps;
|
||||||
|
uint32 width;
|
||||||
|
uint32 height;
|
||||||
|
uint8 channels;
|
||||||
|
char colors[4];
|
||||||
|
uint8 bits[4];
|
||||||
|
uint8 datatype;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const uint pixel_count()const{return width*height;}
|
||||||
|
const uint pixel_bytes()const{return (bits[0]+bits[1]+bits[2]+bits[3])>>3;}
|
||||||
|
const uint total_bytes()const{return pixel_count()*pixel_bytes();}
|
||||||
|
};//
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2D纹理加载器
|
||||||
|
*/
|
||||||
|
class Texture2DLoader
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Tex2DFileHeader file_header;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void *OnBegin(uint32)=0;
|
||||||
|
virtual void OnEnd()=0;
|
||||||
|
virtual void OnError(){}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const Tex2DFileHeader *GetFileHeader()const{return &file_header;}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~Texture2DLoader()=default;
|
||||||
|
|
||||||
|
bool Load(io::InputStream *is);
|
||||||
|
bool Load(const OSString &filename);
|
||||||
|
};//class Texture2DLoader
|
||||||
|
}//namespace graph
|
||||||
|
}//namespace hgl
|
||||||
|
#endif//HGL_GRAPH_TEXTURE_LOADER_INCLUDE
|
@@ -183,7 +183,7 @@ namespace hgl
|
|||||||
// virtual int Layout (const int max_chars,const BaseString<T> &)=0; ///<排版
|
// virtual int Layout (const int max_chars,const BaseString<T> &)=0; ///<排版
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int PlaneLayout (TileFont *,const int max_chars,const BaseString<T> &)=0; ///<简易排版
|
int PlaneLayout (TileFont *,const int max_chars,const BaseString<T> &); ///<简易排版
|
||||||
};//class TextLayout
|
};//class TextLayout
|
||||||
}//namespace graph
|
}//namespace graph
|
||||||
}//namespace hgl
|
}//namespace hgl
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include<hgl/graph/vulkan/VKMemory.h>
|
#include<hgl/graph/vulkan/VKMemory.h>
|
||||||
#include<hgl/graph/vulkan/VKImageView.h>
|
#include<hgl/graph/vulkan/VKImageView.h>
|
||||||
#include<hgl/graph/Bitmap.h>
|
#include<hgl/graph/Bitmap.h>
|
||||||
|
#include<hgl/type/BaseString.h>
|
||||||
VK_NAMESPACE_BEGIN
|
VK_NAMESPACE_BEGIN
|
||||||
|
|
||||||
BitmapData *LoadBitmapFromFile(const OSString &filename);
|
BitmapData *LoadBitmapFromFile(const OSString &filename);
|
||||||
|
@@ -97,12 +97,15 @@ IF(WIN32)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
|
|
||||||
add_cm_library(ULRE.RenderDevice.Vulkan "ULRE" ${VK_RENDERABLE_SOURCE}
|
add_cm_library(ULRE.RenderDevice.Vulkan "ULRE" ${VK_INST_SOURCE}
|
||||||
|
${VK_DEBUG_SOURCE}
|
||||||
|
${VK_MEMORY_SOURCE}
|
||||||
${VK_DEVICE_SOURCE}
|
${VK_DEVICE_SOURCE}
|
||||||
${VK_PHYSICAL_DEVICE_SOURCE}
|
${VK_PHYSICAL_DEVICE_SOURCE}
|
||||||
${VK_DESCRIPTOR_SETS_SOURCE}
|
${VK_DESCRIPTOR_SETS_SOURCE}
|
||||||
${VK_TEXTURE_SOURCE}
|
|
||||||
${VK_SHADER_SOURCE}
|
${VK_SHADER_SOURCE}
|
||||||
|
${VK_TEXTURE_SOURCE}
|
||||||
${VK_MATERIAL_SOURCE}
|
${VK_MATERIAL_SOURCE}
|
||||||
${VK_RENDER_PASS_SOURCE}
|
${VK_RENDER_PASS_SOURCE}
|
||||||
|
${VK_RENDERABLE_SOURCE}
|
||||||
${VK_RENDER_DEVICE_SOURCE})
|
${VK_RENDER_DEVICE_SOURCE})
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
SET(SHADER_RESOURCE_FILES ${ROOT_INCLUDE_PATH}/hgl/graph/shader/ShaderResource.h
|
SET(SHADER_RESOURCE_FILES ${ROOT_INCLUDE_PATH}/hgl/graph/shader/ShaderResource.h
|
||||||
shader/ShaderResource.cpp)
|
shader/ShaderResource.cpp)
|
||||||
|
|
||||||
|
|
||||||
file(GLOB SG_MATERIAL_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/material/*.*)
|
file(GLOB SG_MATERIAL_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/material/*.*)
|
||||||
|
|
||||||
file(GLOB SG_MATERIAL_SOURCE material/*.*)
|
file(GLOB SG_MATERIAL_SOURCE material/*.*)
|
||||||
@@ -11,6 +10,10 @@ SOURCE_GROUP("Material" FILES ${SG_MATERIAL_HEADER}
|
|||||||
|
|
||||||
SOURCE_GROUP("Material\\Shader" FILES ${SHADER_RESOURCE_FILES})
|
SOURCE_GROUP("Material\\Shader" FILES ${SHADER_RESOURCE_FILES})
|
||||||
|
|
||||||
|
SET(SG_TEXTURE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/TextureLoader.h
|
||||||
|
Texture2DLoader.cpp)
|
||||||
|
|
||||||
|
SOURCE_GROUP("Material\\Texture" FILES ${SG_TEXTURE_SOURCE})
|
||||||
|
|
||||||
SET(SG_VAD_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribData.h
|
SET(SG_VAD_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribData.h
|
||||||
${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribDataAccess.h
|
${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribDataAccess.h
|
||||||
@@ -48,9 +51,9 @@ SET(RENDERABLE_FILES ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableCreater.h
|
|||||||
|
|
||||||
SOURCE_GROUP("Renderable" FILES ${RENDERABLE_FILES})
|
SOURCE_GROUP("Renderable" FILES ${RENDERABLE_FILES})
|
||||||
|
|
||||||
SET(FONT_MANAGE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/Font.h
|
SET(FONT_MANAGE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/Font.h
|
||||||
${ROOT_INCLUDE_PATH}/hgl/graph/font/FontManage.h
|
${ROOT_INCLUDE_PATH}/hgl/graph/font/FontManage.h
|
||||||
font/Font.cpp)
|
font/Font.cpp)
|
||||||
|
|
||||||
SET(FONT_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/FontSource.h
|
SET(FONT_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/FontSource.h
|
||||||
font/FontSource.cpp
|
font/FontSource.cpp
|
||||||
@@ -84,6 +87,7 @@ add_cm_library(ULRE.SceneGraph "ULRE" ${SCENE_GRAPH_HEADER}
|
|||||||
|
|
||||||
${SHADER_RESOURCE_FILES}
|
${SHADER_RESOURCE_FILES}
|
||||||
|
|
||||||
|
${SG_TEXTURE_SOURCE}
|
||||||
${SG_MATERIAL_HEADER}
|
${SG_MATERIAL_HEADER}
|
||||||
${SG_MATERIAL_SOURCE}
|
${SG_MATERIAL_SOURCE}
|
||||||
|
|
||||||
|
102
src/SceneGraph/Texture2DLoader.cpp
Normal file
102
src/SceneGraph/Texture2DLoader.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#include<hgl/graph/TextureLoader.h>
|
||||||
|
#include<hgl/graph/Bitmap.h>
|
||||||
|
#include<hgl/io/FileInputStream.h>
|
||||||
|
#include<hgl/log/LogInfo.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace graph
|
||||||
|
{
|
||||||
|
bool Texture2DLoader::Load(io::InputStream *is)
|
||||||
|
{
|
||||||
|
if(!is)return(false);
|
||||||
|
|
||||||
|
if(is->Read(&file_header,sizeof(Tex2DFileHeader))!=sizeof(Tex2DFileHeader))
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
if(file_header.version!=2)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
if(file_header.total_bytes()==0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
const uint total_bytes=file_header.total_bytes();
|
||||||
|
|
||||||
|
if(is->Available()<total_bytes)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
void *ptr=OnBegin(total_bytes);
|
||||||
|
if(!ptr)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
if(is->Read(ptr,total_bytes)!=total_bytes)
|
||||||
|
OnError();
|
||||||
|
|
||||||
|
OnEnd();
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Texture2DLoader::Load(const OSString &filename)
|
||||||
|
{
|
||||||
|
io::OpenFileInputStream fis(filename);
|
||||||
|
|
||||||
|
if(!fis)
|
||||||
|
{
|
||||||
|
LOG_ERROR(OS_TEXT("[ERROR] open texture file<")+filename+OS_TEXT("> failed."));
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->Load(&fis);
|
||||||
|
}
|
||||||
|
}//namespace graph
|
||||||
|
|
||||||
|
namespace graph
|
||||||
|
{
|
||||||
|
class Bitmap2DLoader:public Texture2DLoader
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
BitmapData *bmp=nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
~Bitmap2DLoader()
|
||||||
|
{
|
||||||
|
SAFE_CLEAR(bmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *OnBegin(uint32 total_bytes) override
|
||||||
|
{
|
||||||
|
bmp=new BitmapData;
|
||||||
|
|
||||||
|
bmp->width =file_header.width;
|
||||||
|
bmp->height =file_header.height;
|
||||||
|
bmp->total_bytes=total_bytes;
|
||||||
|
|
||||||
|
bmp->data=new char[total_bytes];
|
||||||
|
|
||||||
|
return bmp->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnEnd() override {}
|
||||||
|
|
||||||
|
BitmapData *GetBitmap()
|
||||||
|
{
|
||||||
|
BitmapData *result=bmp;
|
||||||
|
bmp=nullptr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};//class Bitmap2DLoader
|
||||||
|
|
||||||
|
BitmapData *LoadBitmapFromFile(const OSString &filename)
|
||||||
|
{
|
||||||
|
Bitmap2DLoader loader;
|
||||||
|
|
||||||
|
if(!loader.Load(filename))
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
return loader.GetBitmap();
|
||||||
|
}
|
||||||
|
}//namespace graph
|
||||||
|
}//namespace hgl
|
@@ -115,14 +115,14 @@ namespace hgl
|
|||||||
return s->GetCharBitmap(ch);
|
return s->GetCharBitmap(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FontSourceMulti::GetCharAdvWidth(const u32char &ch)
|
const bool FontSourceMulti::GetCharMetrics(CharMetricsInfo &cmi,const u32char &ch)
|
||||||
{
|
{
|
||||||
FontSource *s=GetFontSource(ch);
|
FontSource *s=GetFontSource(ch);
|
||||||
|
|
||||||
if(!s)
|
if(!s)
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
return s->GetCharAdvWidth(ch);
|
return s->GetCharMetrics(cmi,ch);
|
||||||
}
|
}
|
||||||
}//namespace graph
|
}//namespace graph
|
||||||
}//namespace hgl
|
}//namespace hgl
|
||||||
|
@@ -240,8 +240,10 @@ namespace hgl
|
|||||||
|
|
||||||
for(int i=0;i<count;i++)
|
for(int i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
vertex->Write(
|
//vertex->Write(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextLayout::pl_h_r2l(){return 0;}
|
int TextLayout::pl_h_r2l(){return 0;}
|
||||||
@@ -255,7 +257,7 @@ namespace hgl
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
int TextLayout::PlaneLayout(TileFont *tf,const int mc,const BaseString<T> &str)
|
int TextLayout::PlaneLayout(TileFont *tf,const int mc,const BaseString<T> &str)
|
||||||
{
|
{
|
||||||
if(mc<=0||str.IsEmpty()
|
if(mc<=0||str.IsEmpty())
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
max_chars=hgl_min(mc,str.Length());
|
max_chars=hgl_min(mc,str.Length());
|
||||||
|
Reference in New Issue
Block a user