OpenGL镂空贴图的方法

【转】OpenGL镂空贴图的方法

OpenGL镂空贴图可以使用AlphaTest来完成,也可以使用Blend。

在载入bmp材质时,如果该bmp具有alpha通道,那么可以直接使用它创建纹理。如果只有rgb数据,想使用某种颜色作为镂空色,那么则需要手工创建一个unsigned char [width][height][4] 的空间,先将RGB按 [x][y][0], [x][y][1], [x][y][2] 对应拷贝到这个RGBA缓冲中,然后遍历它,对需要镂空的颜色,将其位置的 [x][y][3] 设置为 0 (对应alpha通道float表示方式的0.0f),否则为255 (对应alpha通道float表示方式的1.0f)。

 

之后,按RGBA, 4字节的方式创建纹理贴图

 

 

参考代码片段:

//---------------------------------------------------------------------------
bool Material::Open(const String& bmpFile)
{
        if (this->IsOpen())
                return false;

        if (!File::IsExist(bmpFile))
                return false;
        AUX_RGBImageRec* textureImage = auxDIBImageLoad(bmpFile.ToLocal().Data());
        if (!textureImage)
                return false;

        int handleId = -1;
        glGenTextures(1, (GLuint*)&handleId);     // 限制不超过signed int, 并且要成功
        if (handleId < 0)
        {
                glDeleteTextures(1, (GLuint*)&handleId);
                if (textureImage->data)
                        free(textureImage->data);//注意要用free
                free(textureImage); //这里也要free
                return false;
        }

        const int img_size = textureImage->sizeX * textureImage->sizeY;
        unsigned char* buffer = new unsigned char[img_size * 4];
        gt_assert(buffer);
        for (int i = 0; i < img_size; ++i)
        {
                buffer[i * 4 + 0] =  textureImage->data[i * 3];
                buffer[i * 4 + 1] =  textureImage->data[i * 3 + 1];
                buffer[i * 4 + 2] =  textureImage->data[i * 3 + 2];

                if (buffer[i * 4 + 0] == MASK_RED && buffer[i * 4 + 1] == MASK_GREEN && buffer[i * 4 + 2] == MASK_BLUE)
                        buffer[i * 4 + 3] = 0;
                else
                        buffer[i * 4 + 3] = 255;
        }

        glBindTexture(GL_TEXTURE_2D, handleId);
        glTexImage2D(GL_TEXTURE_2D, 0, 4, textureImage->sizeX, textureImage->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glBindTexture(GL_TEXTURE_2D, 0);

        delete buffer; buffer = NULL;
        if (textureImage->data)
                free(textureImage->data);//注意要用free
        free(textureImage);  //这里也要free

        m_handle = handleId;
        return true;
}
//---------------------------------------------------------------------------

 

现在有2种显示镂空的方法:

(1) AlphaTest方式:

绘制前设置:

glEnable(GL_ALPHA_TEST);   
glAlphaFunc(GL_GREATER, 0.0f); // GL_GREATER表示大于的意思,这里指:当源的Alpha通道>0.0f时,画出这个象素,否则不画。

 

 (2) Blend方式:

绘制前设置:
glEnable(GL_BLEND);        // 启用混合

glDisable(GL_DEPTH_TEST); // 禁用深度测试
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // 表示按源元素Alpha处理,不改变Alpha亮度进行混合。

 

两种方式中,第一种方法专用与镂空,第二种方法可以实现半透明+镂空,具体效果可以调整alpha值自己体会。

注意,第一种方式会明显快与第二种,因为openGL中,alpha test是先于alpha blend的,首先要通过检测的pix才进入管线再进行颜色混合的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值