Cpper
C/C++高级工程师 Android高级软件工程师 IT集成工程师 音频工程师 熟悉c,c++,java,c#,py,js,asp等多种语言 程序猿

给BGE加上了富文本显示功能
相关代码如下:
void GLTextRenderer::render(const Color& color,const String& string,const FloatRect& area,bool isMultiLine,
        Horizontal hAlignment,Vertical vAlignment,
bool rich)
{
    
if(typeFace_ != 0 && !rich)
    {
        typeFace_
->setColor(color);
        
if(isMultiLine)
        {
            renderMultiline(color,
string,area,hAlignment);
        }
        
else
        {
            Vector2f position(typeFace_
->penX(string,area,hAlignment),baseLineY(area,vAlignment));
            typeFace_
->render(string,position);
        }
    }
    
else if(typeFace_)
    {
        
if(!isMultiLine)
        {
            auto cmdlist 
= parseString(string);
            Vector2f position(typeFace_
->penX(string,area,hAlignment),baseLineY(area,vAlignment));
            typeFace_
->render(String(),position,cmdlist);
        }
        
else
        {
            auto cmdlist 
= parseString(string);
            renderMultiline(color,cmdlist,area,hAlignment);
        }
    }
}
这里的parseString用于解析类似html的问题
函数实现如下:
std::list<textRenderCmdUnit> TextRenderer::parseString(const String& content)
{
    String text(content);
    std::list
<textRenderCmdUnit> cmdList;

    String current;
    auto list 
= text.split('<');
    
for(int i=0;i<list.size();i++)
    {
        current 
= list[i];
        
if(current.startWith(L"/>"))
        {
            textRenderCmdUnit unit;
            unit.undo 
= true;
            cmdList.push_back(unit);

            String remain 
= current.substr(2);
            
if(!remain.empty())
            {
                unit.text 
= remain;
                unit.undo 
= false;
                cmdList.push_back(unit);
            }
        }
        
else if(current.find('>'!= String::InvalidPos)
        {
            textRenderCmdUnit unit;
            unit.tag 
= current.substr(0,current.find('>'));
            unit.undo 
= false;
            cmdList.push_back(unit);

            int32_t find 
= current.find('>');
            
if(find < current.size()-1)
            {
                unit.tag.clear();
                unit.text 
= current.substr(find+1);
                cmdList.push_back(unit);
            }
        }
        
else
        {
            textRenderCmdUnit unit;
            unit.text 
= current;
            unit.undo 
= false;
            cmdList.push_back(unit);
        }
    }

    
return cmdList;
}
以下用于渲染富文本

void TypeFace::render(const FloatRect& area,const std::list<textRenderCmdUnit>& queue,Horizontal hAlignment,float vpos)
{
    
const float availableWidth = area.width_ - 2.0f;

    textRenderCmdUnit unit;

    String line,lineRemain;

    String tag;
    std::queue
<String> cmdStack;

    
float y = vpos;
    
float x = penX(String(),area,hAlignment);

    auto itr 
= queue.begin();
    
while(itr != queue.end())
    {
        unit 
= *itr;
        
if(unit.undo)
        {
            
if(!cmdStack.empty())
            {
                tag 
= cmdStack.front();
                cmdStack.pop();

                
if(tag == "bold")
                    bold_ 
= false;
                
else if(tag == "italic")
                    italic_ 
= false;
                
else if(tag == "underline")
                    underline_ 
= false;
                
else
                    applyColor(tag);
            }
        }
        
else if(!unit.tag.empty())
        {
            tag 
= unit.tag;
            cmdStack.push(tag);

            
if(tag == "bold")
                bold_ 
= true;
            
else if(tag == "italic")
                italic_ 
= true;
            
else if(tag == "underline")
                underline_ 
= true;
            
else
                applyColor(tag);
        }
        
else
        {
            line 
+= unit.text;

            
while(true)
            {
                size_t pos 
= hitCharacterIndex(line,availableWidth-x);
                
if(pos == 0)
                {
                    x 
= penX(String(),area,hAlignment);
                    y 
+= lineHeight();
                    
continue;
                }

                
if(pos == String::InvalidPos)
                    pos 
= line.size();

                String current 
= line.substr(0,pos);
                lineRemain 
= line.substr(pos);
                line 
= current;

                auto linefeed 
= line.get().find_first_of('\n');
                
if(linefeed != std::basic_string<uint32_t>::npos)
                {
                    line 
= line.substr(0,linefeed);
                    lineRemain 
= line.substr(linefeed+1+ lineRemain;
                }

                render(line,Vector2f(x,y),std::list
<textRenderCmdUnit>());
                x 
+= width(line);

                
if(linefeed != String::InvalidPos)
                {
                    x 
= penX(String(),area,hAlignment);
                    y 
+= lineHeight();
                }
                line 
= lineRemain;

                
if(lineRemain.empty())
                    
break;
            }
        }
        itr 
++;
    }
}
以下渲染单色文本
void TypeFace::renderGlyphs(const std::list<textRenderCmdUnit>& cmd)
{
    Vector2f position(
0.0f,0.0f);
    size_t leftChar 
= 0;

    textRenderCmdUnit unit;

    String tag;
    std::queue
<String> cmdStack;

    std::list
<textRenderCmdUnit>::const_iterator itr = cmd.begin();
    
while(itr != cmd.end())
    {
        unit 
= *itr;
        
if(unit.tag.empty() && !unit.undo)
        {
            position 
= renderGlyphs(unit.text,position);
        }
        
else if(!unit.tag.empty())
        {
            tag 
= unit.tag;
            cmdStack.push(tag);

            
if(tag == "bold")
                bold_ 
= true;
            
else if(tag == "italic")
                italic_ 
= true;
            
else if(tag == "underline")
                underline_ 
= true;
            
else
                applyColor(tag);
        }
        
else if(unit.undo)
        {
            
if(!cmdStack.empty())
            {
                tag 
= cmdStack.front();
                cmdStack.pop();

                
if(tag == "bold")
                    bold_ 
= false;
                
else if(tag == "italic")
                    italic_ 
= false;
                
else if(tag == "underline")
                    underline_ 
= false;
                
else
                    applyColor(tag);
            }
        }

        itr 
++;
    }
}
可以看出 支持的文本格式为<Tag>Text</>
一个例子是:
<Blue>这段代码主要测试BGE的富文本显示功能\n</Blue><Red>需要指出的是当前只要能支持多行显示和多颜色显示功能即可(不考虑下划线斜体以及加粗显示)。</Red><White>这句话将被显示为白色</><Blue>这句话应该被蓝色字体</Blue><Green>绿色字体</><Cyan>Cyan色</>";
最终显示如下:
posted @ 2016-02-22 17:46 ccsdu2009 阅读(749) | 评论 (0)编辑 收藏
 
解释:
GraphicsItem 重载 mousePressEvent(QGraphicsSceneMouseEvent* event)后处理完之后需要执行event->accpet().
posted @ 2016-02-05 09:18 ccsdu2009 阅读(1261) | 评论 (0)编辑 收藏
 
推荐一款开源库glc
glc是一款基于Qt和opengl的3D仿真程序,可以是用来渲染3ds,obj,stl等模型以及常见几何体对象
支持对象拾取等功能
学习了一天感觉基本还行.
主页:http://www.glc-lib.net/
posted @ 2016-01-29 17:11 ccsdu2009 阅读(684) | 评论 (0)编辑 收藏
 
算是基本完成了,先上一个截图


可以说GUI所需要的当前基本都是实现了

再上一个使用例子:
#include <BGE/All>

using namespace bge;

int main(int argc, char* argv[])
{
    FileSystem::instance().initial(argv[0]);
    FileSystem::instance().setResourcePackage("data.zip");
    WindowManager::instance().initialize("simkai.ttf",true);

    Device* device = Device::create();
    device->initial();
    device->createWindow(640,480,bge::String("BGE Window"));

    WindowManager::instance().propertyScheme()->load(":skin1.xml");

    Window* window = WindowManager::instance().createWindow(":grid-layout-window.xml");
    WindowManager::instance().addWindow(window);

    while(device->isRunning())
    {
        device->preRender();
        WindowManager::instance().update();
        device->swapBuffers();
        device->pollEvents();
    }

    WindowManager::instance().terminate();
    device->closeWindow();
    device->terminate();
    device->deleteLater();
    return 0;
}

个人感觉写的还是比较清晰,没什么需要特别说明的
使用的开源库有libpng,glfw,freetype,sigslot,physfs
不过代码有点大,有兴趣的可以留个邮箱

posted @ 2016-01-22 15:41 ccsdu2009 阅读(4082) | 评论 (10)编辑 收藏
 
先上一个使用例子
#include <BGE/All>

using namespace bge;

Window
* createButton(const std::string& name,const String& text)
{
    Button
* button = new Button(0,text);
    button
->setName(name);
    button
->setSize(Vector2f(92,42));
    
return button;
}

int main(int argc, char* argv[])
{
    FileSystem::instance().initial(argv[
0]);
    FileSystem::instance().setResourcePackage(
"data.zip");
    WindowManager::instance().initialize(
"simkai.ttf",false);

    Device
* device = Device::create();
    device
->initial();
    device
->createWindow(640,480,bge::String("BGE Window"));

    Panel
* panel = new Panel(FloatRect(30,30,192,180),0);
    GridLayout
* layout = new GridLayout();
    panel
->setLayout(layout);
    std::vector
<float> widths;
    widths.push_back(
0.0f);
    layout
->setColumnWidths(widths);

    std::vector
<float> heights;
    
for(int k = 0; k < 3++k)
        heights.push_back(
48.0f);
    heights.push_back(
0.0f);
    layout
->setRowHeights(heights);

    GridCellInfo info;
    info.columnIndex_ 
= 0; info.rowIndex_ = 0; layout->addWindow(createButton("button1",L"按键"),info);
    info.columnIndex_ 
= 1; info.rowIndex_ = 0; layout->addWindow(createButton("button2",L"按键"),info);
    info.columnIndex_ 
= 0; info.rowIndex_ = 1; layout->addWindow(createButton("button3",L"按键"),info);
    info.columnIndex_ 
= 1; info.rowIndex_ = 1; layout->addWindow(createButton("button4",L"按键"),info);
    info.columnIndex_ 
= 0;
    info.rowIndex_ 
= 2;
    info.horizontalSpan_ 
= 2;
    Window
* edit = new EditField(NULL,L"Edit Text");
    edit
->setSize(Vector2f(196,36));
    layout
->addWindow(edit,info);
    info.columnIndex_ 
= 0;
    info.rowIndex_ 
= 3;
    info.horizontalSpan_ 
= 3;
    layout
->arrangeWithin();

    FrameWindow
* window = new FrameWindow();
    window
->enableMovement();
    window
->setText(L"BGE窗体");
    window
->setClientPanel(panel);

    WindowManager::instance().addWindow(window);

    
while(device->isRunning())
    {
        device
->preRender();
        WindowManager::instance().update();
        device
->swapBuffers();
        device
->pollEvents();
    }

    WindowManager::instance().terminate();
    device
->closeWindow();
    device
->terminate();
    device
->deleteLater();
    
return 0;
}

在开发上参考了Qt等软件,当前支持常见控件 支持控件序列化 整体换肤 控件换肤
上面的代码显示的截图如下:
http://images2015.cnblogs.com/blog/676118/201601/676118-20160120092402484-466039328.png
不过当前还有一点小问题 修改完了再上代码
做这个不为什么 就是几年前一直想做个
posted @ 2016-01-20 09:34 ccsdu2009 阅读(2011) | 评论 (3)编辑 收藏
 
#include <BGE/all>

using namespace bge;

int main(int argc,char* argv[])
{
    
//!初始化文件系统
    FileSystem::instance()->initial(argv[0]);
    
//!加载压缩包
    FileSystem::instance()->setResourcePackage("data.zip");
    
//!初始化UI管理器,设定默认字体,并设定自动删除控件
    WindowManager::instance().initialize("simkai.ttf",true);

    
//!生成和初始化窗口设备
    Device* device = bgeCreateDevice();
    device
->initial();
    device
->createWindow(640,480,bge::String("BGE Window"));
    
    
//!从资源文件加载控件包含子控件和控件属性
    Window* window = WindowManager::instance().create("window.xml");
    bge::WindowManager::instance().addWindow(listbox);

    
while(device->isRunning())
    {
        
//!预渲染设备
        device->perRender();
        
//!窗体更新
        bge::WindowManager::instance().update();
        
        device
->swapBuffers();
        device
->pollEvents();
    }

    
//!销毁窗体管理器
    bge::WindowManager::instance().terminate();
    
//!关闭并销毁设备
    device->closeWindow();
    device
->terminate();
    device
->deleteLater();

    system(
"pause");
    
return 0;
}

还没做完,用法如上,很简练吧:D

什么?对整体视效不满意?
试下这个:
WindowManager::instance().propertyScheme()->load("skin.xml");
想定制某个控件的视效?
Button* button = window->findChild("ok");
button->loadAppearance("button.xml","blue");

posted @ 2016-01-07 16:20 ccsdu2009 阅读(757) | 评论 (0)编辑 收藏
 
libpng比较另类,解码方式比较奇特,这里记录下
以下代码为使用虚拟IOReader的方式,稍做修改就基于FILE使用
代码很详细,不需额外解释
PNGImage::PNGImage(const std::string& filename):
    ReferenceCountedImage(filename),
    data_(
0)
{
    IOReader
* reader = FileSystem::instance()->readFile(filename);
    
if(reader == 0)
        
return;

    png_structp png_ptr 
= png_create_read_struct(PNG_LIBPNG_VER_STRING, 000);
    
if(png_ptr == 0)
    {
        reader
->close();
        reader
->deleteLater();
    }

    png_infop info_ptr 
= png_create_info_struct(png_ptr);
    
if(info_ptr == 0)
    {
        png_destroy_read_struct(
&png_ptr, png_infopp(0), png_infopp(0));
        reader
->close();
        reader
->deleteLater();
    }

    
if(setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(
&png_ptr,png_infopp(0),png_infopp(0));
        reader
->close();
        reader
->deleteLater();
    }

    png_set_read_fn( png_ptr,reader,(png_rw_ptr)user_read_data);

    png_set_sig_bytes(png_ptr,
0);

    png_read_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,
0);
    
const unsigned int width = png_get_image_width(png_ptr,info_ptr);
    
const unsigned int height = png_get_image_height(png_ptr,info_ptr);
    
const unsigned int bit_depth = png_get_bit_depth(png_ptr,info_ptr);
    
if(bit_depth != 8)
    {
        reader
->close();
        reader
->deleteLater();
        png_destroy_info_struct(png_ptr,png_infopp(
&info_ptr));
        png_destroy_read_struct(
&png_ptr,png_infopp(0), png_infopp(0));
    }

    
const png_byte colorType = png_get_color_type(png_ptr, info_ptr);
    
if((colorType != PNG_COLOR_TYPE_RGB) && (colorType != PNG_COLOR_TYPE_RGB_ALPHA))
    {
        reader
->close();
        reader
->deleteLater();
        png_destroy_info_struct(png_ptr, png_infopp(
&info_ptr));
        png_destroy_read_struct(
&png_ptr, png_infopp(0), png_infopp(0));
    }

    
const int bytesPerPixel = (colorType == PNG_COLOR_TYPE_RGB) ? 3 : 4;
    
const int stride = bytesPerPixel * width;

    unsigned 
char* data = new unsigned char[stride * height];
    png_bytep
* row_pointers = png_get_rows(png_ptr, info_ptr);
    
for(unsigned int i = 0; i < height; ++i)
    {
        
const unsigned int row = height - i - 1;
        memcpy(data 
+ (row * stride), row_pointers[i], stride);
    }

    size_.x_ 
= width;
    size_.y_ 
= height;
    numberOfBitsPerPixel_ 
= bytesPerPixel * 8;
    data_ 
= data;

    reader
->close();
    reader
->deleteLater();
    png_destroy_info_struct(png_ptr, png_infopp(
&info_ptr));
    png_destroy_read_struct(
&png_ptr, png_infopp(0), png_infopp(0));
}
posted @ 2015-12-29 11:12 ccsdu2009 阅读(3794) | 评论 (0)编辑 收藏
 
代码如下:
class ArrowItem : public QGraphicsItem
{
public:
    
const static float LINE_WIDTH;
    
const static float ARROW_SIZE;
public:
    ArrowItem(QGraphicsItem
* parent = 0);
    
~ArrowItem();
    
void setData(const QPointF& from,const QRectF& rect);
public:
    QRectF boundingRect()
const;
    
void paint(QPainter* painter,const QStyleOptionGraphicsItem* style,QWidget* widget);
private:
    QPointF computeTo(
const QPointF& from,const QRectF& to);
private:
    
bool mValid;
    QPointF mFrom;
    QPointF mTo;
    QPointF mP1;
    QPointF mP2;
    QRectF  mRect;
};

const float ArrowItem::LINE_WIDTH = 1.5f;
const float ArrowItem::ARROW_SIZE = 8.0f;

ArrowItem::ArrowItem(QGraphicsItem
* parent):
QGraphicsItem(parent),
mValid(
false)
{
}

ArrowItem::
~ArrowItem()
{
}

QPointF ArrowItem::computeTo(
const QPointF& from,const QRectF& to)
{
    QPointF center(to.center());
    QPointF top(center.x(),to.top());
    QPointF right(to.right(),center.y());
    QPointF bottom(center.x(),to.bottom());
    QPointF left(to.left(),center.y());

    
//left
    if(from.x() < to.left())
    {
        
if(from.y() < to.top())
        {
            QLineF line1(from,top);
            QLineF line2(from,left);
            
return line1.length() > line2.length() ? left : top;
        }
        
else if(from.y() > to.bottom())
        {
            QLineF line1(from,left);
            QLineF line2(from,bottom);
            
return line1.length() > line2.length() ? bottom : left;
        }
        
return left;
    }
    
//right
    if(from.x() > to.right())
    {
        
if(from.y() < to.top())
        {
            QLineF line1(from,top);
            QLineF line2(from,right);
            
return line1.length() > line2.length() ? right : top;
        }
        
else if(from.y() > to.bottom())
        {
            QLineF line1(from,bottom);
            QLineF line2(from,right);
            
return line1.length() > line2.length() ? right : bottom;
        }
        
return right;
    }

    
if(from.y() < to.top())
        
return top;
    
else if(from.y() > to.bottom())
        
return bottom;

    Q_ASSERT(
0);
    
return QPointF();
}

void ArrowItem::setData(const QPointF& from,const QRectF& rect)
{
    mValid 
= true;
    mFrom 
= from;
    mRect 
= rect;

    
if(rect.contains(from))
    {
        mValid 
= false;
        
return;
    }

    mTo 
= computeTo(mFrom,mRect);

    QLineF line(mFrom,mTo);
    qreal angle 
= ::acos(line.dx()/line.length());

    
if(line.dy() >= 0)
        angle 
= 3.14159*2 - angle;

    mP1 
= mTo + QPointF(sin(angle-PI/3)*ARROW_SIZE,cos(angle-PI/3)*ARROW_SIZE);
    mP2 
= mTo + QPointF(sin(angle-PI+PI/3)*ARROW_SIZE,cos(angle-PI+PI/3)*ARROW_SIZE);
}

QRectF ArrowItem::boundingRect()
const
{
    qreal extra 
= (LINE_WIDTH + ARROW_SIZE)/2.0;
    QRectF rect
= QRectF(mFrom,QSizeF(mTo.x()-mFrom.x(),mTo.y()-mFrom.y())).normalized().
        adjusted(
-extra,-extra,extra,extra);
    
return rect;
}

void ArrowItem::paint(QPainter* painter,const QStyleOptionGraphicsItem* style,QWidget* widget)
{
    
if(!mValid)
        
return;
    painter
->setRenderHint(QPainter::Antialiasing);
    QPen p(QColor::fromRgb(
79,136,187));
    painter
->setBrush(QBrush(p.color()));
    p.setWidthF(LINE_WIDTH);
    painter
->setPen(p);
    painter
->drawLine(mFrom,mTo);
    painter
->drawPolygon(QPolygonF()<<mTo<<mP1<<mP2);
}

void ArrowItem::setData(const QPointF& from,const QRectF& rect)
该函数第一个参数为箭头起点,rect为箭头指向的矩形框,该函数会自动计算箭头终点和箭头相关参数
该代码经过测试 - 完全可以使用
参考:
http://www.cnblogs.com/liulun/p/3833006.html
posted @ 2015-12-15 13:10 ccsdu2009 阅读(9786) | 评论 (0)编辑 收藏
 
    QFont font;
    font.setPointSize(
15);
    
    
for(int i=0;i<15;i++)
    {
        
for(int j=0;j<18;j++)
        {
            QPointF p(
-2400+20+(RECT_WIDTH+30)*i,-1500+20+(RECT_HEIGHT+30)*j);
            QGraphicsRectItem
* item = new QGraphicsRectItem(p.x(),p.y(),RECT_WIDTH,RECT_HEIGHT);
            item
->setToolTip("click me");
            item
->setBrush(QColor(79,136,187,255));
            scene
->addItem(item);

            QGraphicsTextItem
* text = new QGraphicsTextItem(item);
            text
->setPlainText(QString("%1,%2").arg(i).arg(j));
            QRectF rect 
= text->boundingRect();
            text
->setDefaultTextColor(QColor(255,255,255));
            p.setX(p.x() 
+ RECT_WIDTH/2 - rect.width()/2);
            text
->setPos(p);
            text
->setFont(font);
        }
    }
按照经验以为
QGraphicsRectItem会有setText接口,之后觉得应该定制一个QGraphicsItem
搜了下原来
QGraphicsRectItem是树状结构可以增加子项
因此就好办多了,代码如上
posted @ 2015-12-10 17:12 ccsdu2009 阅读(2920) | 评论 (0)编辑 收藏
 
更新不多,主要是取消了插接结构,把所有的编解码和音效都合入了主库
dll合计不超过1M

支持常见音频格式和音效,使用超级方便
下载在这里:/Files/gaimor/gaudio-sdk-2.2.1.0.zip
posted @ 2015-12-10 16:37 ccsdu2009 阅读(465) | 评论 (0)编辑 收藏
仅列出标题
共38页: First 4 5 6 7 8 9 10 11 12 Last