游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4474|回复: 4

用GDI+绘制到内存DC中生成OpenGL文字纹理

[复制链接]

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
发表于 2011-6-29 00:37:00 | 显示全部楼层 |阅读模式
关键代码如下:
//开始及结束GDI+,期间的代码可以把GDI+的绘图函数运用到图像对象上
Graphics* CGrap::CImage::BeginGDIPlus()
{       
        if(NULL==m_pData)return NULL;
        if(NULL==CImage::hDC)CImage::hDC=::CreateCompatibleDC(NULL);
        if(NULL==CImage::hDC)return NULL;       
        if(m_bBitmapInvalid)
        {
                if(NULL!=m_hBitmap):eleteObject(m_hBitmap);
                m_hBitmap=NULL;
                if(NULL==(m_hBitmap=::CreateBitmap(m_W, m_H, 1, m_Type*8, m_pData)))return NULL;
                m_bBitmapInvalid=false;
        }       
        ::SelectObject(CImage::hDC, m_hBitmap);
        if(NULL!=CImage::pGDIPlusGrap)delete CImage::pGDIPlusGrap;
        CImage::pGDIPlusGrap=NULL;
        CImage::pGDIPlusGrap=new Graphics(CImage::hDC);
        return CImage::pGDIPlusGrap;
}
void CGrap::CImage::EndGDIPlus()
{
        if(NULL!=CImage::pGDIPlusGrap)delete CImage::pGDIPlusGrap;
        CImage::pGDIPlusGrap=NULL;
}
        用法:
       CGrap::CImage img;
       img.Create(8,8); //,CGrap::CImage::TYPE::RGBA,const_colors[CONST_COLOR::Blue].ColorValue
        ///*
        Graphics *pGPG=img.BeginGDIPlus();
        if(NULL!=pGPG)
        {
                //pGPG->DrawString(L"我是中国人", -1,&Font(L"宋体", 10),PointF(0, 0),&SolidBrush(Color::Red));
                pGPG->DrawRectangle(&ampen(&SolidBrush(Color::Red)),0,0,4,4);
        }
        img.EndGDIPlus();
        tex[0].Create(img);

    结果GDI+什么也没绘制,跟踪进GDI+的代码,每一步都是成功的,可是监控m_pData所指向的内存区域,一个字节都没改变,后来改用GDI的函数也同样,不得其解?

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2011-6-29 01:02:00 | 显示全部楼层

Re:用GDI+绘制到内存DC中生成OpenGL文字纹理

呵呵,不好意思,看了以前sandy_zc_1大哥关于我的“在内存DC中,同时用API绘图和内存拷贝绘图时的遮挡问题如何解决?”贴的回复,似乎找到原因了,引用sandy_zc_1大哥的原话“如果我没有理解错的话,MSDN上说CreateBitmap最后一个参数传入的指针是用于“指明填充位图的数据所在地”,而不是“直接把指向的地方当作位图数据的存放地”。

根据我的测试,当CreateBitmap之后,你再对那个指针指向的区域做任何修改都不会影响到位图的数据了。也就是说其实CreateBitmap是把你的m_pRenderBuffer里面的数据拷贝到它的位图数据区去了,你之后再怎么修改m_pRenderBuffer都和Create出来的Bitmap无关了。”
只是还没找到解决之道@#¥%%¥¥%¥#%#@¥@%#¥@……

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2011-6-29 12:52:00 | 显示全部楼层

Re: 用GDI+绘制到内存DC中生成OpenGL文字纹理

用CreateDIBSection已解决问题,遗憾的是CreateDIBSection创建的位图不带Alpha通道,浪费了GDI+的Alpha功能。
//开始及结束GDI+,期间的代码可以把GDI+的绘图函数运用到图像对象上
Graphics* CGrap::CImage::BeginGDIPlus()
{       
        if(NULL==m_pData)return NULL;
        if(NULL==CImage::hDC)CImage::hDC=::CreateCompatibleDC(NULL);
        if(NULL==CImage::hDC)return NULL;       
        if(m_bBitmapInvalid)
        {
                if(NULL!=m_hBitmap):eleteObject(m_hBitmap);
                m_hBitmap=NULL;
                BITMAPINFO bmpinfo;
                bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                bmpinfo.bmiHeader.biWidth = m_W;
                bmpinfo.bmiHeader.biHeight = m_H;
                bmpinfo.bmiHeader.biPlanes = 1;
                bmpinfo.bmiHeader.biBitCount = 24;
                bmpinfo.bmiHeader.biCompression = BI_RGB;
                bmpinfo.bmiHeader.biSizeImage = 0;
                bmpinfo.bmiHeader.biXPelsPerMeter = 0;
                bmpinfo.bmiHeader.biYPelsPerMeter = 0;
                bmpinfo.bmiHeader.biClrUsed = 0;
                bmpinfo.bmiHeader.biClrImportant = 0;
                if(NULL==(m_hBitmap =::CreateDIBSection(hDC,&bmpinfo,DIB_RGB_COLORS,(void **)&m_pBitmapData,NULL,0)))return NULL;
                m_bBitmapInvalid=false;
        }       
        ::SelectObject(CImage::hDC, m_hBitmap);
        if(NULL!=CImage::pGDIPlusGrap)delete CImage::pGDIPlusGrap;
        CImage::pGDIPlusGrap=NULL;
        CImage::pGDIPlusGrap=new Graphics(CImage::hDC);
        return CImage::pGDIPlusGrap;
}
void CGrap::CImage::EndGDIPlus(COLORREF bkColor,CHANNEL keyChannel)
{
        if(NULL!=CImage::pGDIPlusGrap)delete CImage::pGDIPlusGrap;
        CImage::pGDIPlusGrap=NULL;
        long DIBPadBytes=IJL_DIB_PAD_BYTES(m_W,3);
        long j=0,i=0;
        keyChannel=keyChannel&3;
        switch(m_Type)
        {
                case TYPE::RGBA:
                        for(j=0;j<m_H;++j)
                        {
                                for(i=0;i<m_W;++i)
                                {
                                        if(GetR(bkColor)!=m_pBitmapData[(m_W*3+DIBPadBytes)*j+i*3]||
                                           GetG(bkColor)!=m_pBitmapData[(m_W*3+DIBPadBytes)*j+i*3+1]||
                                           GetB(bkColor)!=m_pBitmapData[(m_W*3+DIBPadBytes)*j+i*3+2])
                                        {       
                                                m_pData[(m_W*j+i)*4]  =m_pBitmapData[(m_W*3+DIBPadBytes)*j+i*3];
                                                m_pData[(m_W*j+i)*4+1]=m_pBitmapData[(m_W*3+DIBPadBytes)*j+i*3+1];
                                                m_pData[(m_W*j+i)*4+2]=m_pBitmapData[(m_W*3+DIBPadBytes)*j+i*3+2];
                                                m_pData[(m_W*j+i)*4+3]=255;
                                        }
                                }
                        }
                        break;
                case TYPE::ALPHA:
                        for(j=0;j<m_H;++j)
                        {
                                for(i=0;i<m_W;++i)
                                {
                                        m_pData[(m_W*j+i)]=m_pBitmapData[(m_W*3+DIBPadBytes)*j+i*3+keyChannel];                                       
                                }
                        }
        }
}

下面是DEMO文件:

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2011-6-29 12:59:00 | 显示全部楼层

Re: 用GDI+绘制到内存DC中生成OpenGL文字纹理

Demo

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2011-6-29 13:00:00 | 显示全部楼层

Re: 用GDI+绘制到内存DC中生成OpenGL文字纹理

Demo
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-8-7 04:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表