OpenGL超级宝典笔记——操作像素

原文: http://my.oschina.net/sweetdark/blog/174663


OpenGL支持放大,缩小,旋转图像。下面将举例介绍这些像素的操作。下面的例子是从tga文件中读取图片并显示,而且可以通过右键菜单来选择图像的显示模式和保存图片的快照到磁盘命名为screenshot.tga。完整的代码示例如下:

#include "gltools.h" #include <math.h> static GLbyte *pImage = NULL; static GLint iRenderMode = 0; static GLint iWidth, iHeight, iComponents; static GLenum eFormat; void ProcessMenu(int value)
{ if (value == 1)
    { //保存图像的快照 gltWriteTGA("screenshot.tga");
    } else {
        iRenderMode = value;
    }

    glutPostRedisplay();

} void RenderScene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (!pImage)
    { return;
    } //设置光栅位置 glRasterPos2i(0, 0); //修改的图像,和用于反转的映射数组 GLbyte *pModifyImage = NULL;
  GLfloat invertMap[256]; switch (iRenderMode)
    { case 2: //图像倒转 glPixelZoom(-1.0f, -1.0f); //倒转后的图像的,渲染方向也倒转过来了,变成了从右上角开始往左下角渲染,所以设置倒转后的光栅位置为图像的宽高。 glRasterPos2i(iWidth, iHeight); break; case 3: //让图像填充满屏幕 GLint viewport[4]; //取得视口的大小 glGetIntegerv(GL_VIEWPORT, viewport); //按比例缩放 glPixelZoom((GLfloat)viewport[2]/iWidth, (GLfloat)viewport[3]/iHeight); break; case 4: //只保留红色 glPixelTransferf(GL_RED_SCALE, 1.0f);
    glPixelTransferf(GL_GREEN_SCALE, 0.0f);
    glPixelTransferf(GL_BLUE_SCALE, 0.0f); break; case 5: //只保留绿色 glPixelTransferf(GL_RED_SCALE, 0.0f);
    glPixelTransferf(GL_GREEN_SCALE, 1.0f);
    glPixelTransferf(GL_BLUE_SCALE, 0.0f); break; case 6: //只保留蓝色 glPixelTransferf(GL_RED_SCALE, 0.0f);
    glPixelTransferf(GL_GREEN_SCALE, 0.0f);
    glPixelTransferf(GL_BLUE_SCALE, 1.0f); break; case 7: //先渲染图像到颜色缓冲区中 glDrawPixels(iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pImage); //NTSC标准,转成黑白图像  glPixelTransferf(GL_RED_SCALE, 0.3f);
    glPixelTransferf(GL_GREEN_SCALE, 0.59f);
    glPixelTransferf(GL_BLUE_SCALE, 0.11f); //申请临时空间来保存修改后的图像 pModifyImage = (GLbyte *)malloc(iWidth * iHeight * 3); if (!pModifyImage)
    { return;
    } //从颜色缓冲区中读取图像的亮度数据 glReadPixels(0, 0, iWidth, iHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, pModifyImage); //还原 glPixelTransferf(GL_RED_SCALE, 1.0f);
    glPixelTransferf(GL_GREEN_SCALE, 1.0f);
    glPixelTransferf(GL_BLUE_SCALE, 1.0f); break; case 8: //设置反转的颜色映射 invertMap[0] = 1.0f; for(int i = 0; i < 256; ++i)
    {
      invertMap[i] = 1.0f - (1.0f / 255.0f * (GLfloat)i);
    } //映射 glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 255, invertMap);
    glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 255, invertMap);
    glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 255, invertMap); //开启颜色映射 glPixelTransferi(GL_MAP_COLOR, GL_TRUE); default: break;
    } if (pModifyImage)
  { //画黑白图像 glDrawPixels(iWidth, iHeight, GL_RGB, GL_UNSIGNED_BYTE, pModifyImage);
    free(pModifyImage);
  } else {
      glDrawPixels(iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pImage);
  } //还原 glPixelTransferf(GL_RED_SCALE, 1.0f);
  glPixelTransferf(GL_GREEN_SCALE, 1.0f);
  glPixelTransferf(GL_BLUE_SCALE, 1.0f);
  glPixelZoom(1.0f, 1.0f);
  glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
    glutSwapBuffers();
} void SetupRC()
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //设置像素的存储格式 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //加载图像数据 pImage = gltLoadTGA("horse.tga", &iWidth, &iHeight, &iComponents, &eFormat);

} //释放图像数据占用的内存空间 void ShutdownRC()
{ if (pImage)
    {
        free(pImage);
        pImage = NULL;
    }
} void ChangeSize(GLsizei w, GLsizei h)
{ if (h == 0)
        h = 1;

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glutPostRedisplay();
} int main(int args, char **argv)
{
    glutInit(&args, argv);
    glutInitDisplayMode(GL_RGB | GL_DOUBLE);
    glutInitWindowSize(800, 600);
    glutCreateWindow("pixel operation");
    
    glutDisplayFunc(RenderScene);
    glutReshapeFunc(ChangeSize); //设置菜单 int menuID = glutCreateMenu(ProcessMenu);
    glutAddMenuEntry("Save Image", 1);
    glutAddMenuEntry("Flip", 2);
    glutAddMenuEntry("zoom pixel fill window", 3);
  glutAddMenuEntry("Just Red", 4);
  glutAddMenuEntry("Just Green", 5);
  glutAddMenuEntry("Just Blue", 6);
  glutAddMenuEntry("black & white", 7);
  glutAddMenuEntry("invert map", 8);
    glutAttachMenu(GLUT_RIGHT_BUTTON);

    SetupRC();
    glutMainLoop();
    ShutdownRC(); return 0;
}


SetupRC函数用于加载图像数据,保存图像数据,图像的宽高和格式等信息。

glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //设置像素的存储格式 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //加载图像数据 pImage = gltLoadTGA("horse.tga", &iWidth, &iHeight, &iComponents, &eFormat);

在程序退出时,记得释放为图像数据分配的内存,在ShutdownRC中释放图像数据

if (pImage)
{
    free(pImage);
    pImage = NULL;
}

在main函数中,创建菜单,为每个菜单项分配键值,然后绑定到右键上。

//设置菜单 int menuID = glutCreateMenu(ProcessMenu);
    glutAddMenuEntry("Save Image", 1);
    glutAddMenuEntry("Flip", 2);
    glutAddMenuEntry("zoom pixel fill window", 3);
  glutAddMenuEntry("Just Red", 4);
  glutAddMenuEntry("Just Green", 5);
  glutAddMenuEntry("Just Blue", 6);
  glutAddMenuEntry("black & white", 7);
  glutAddMenuEntry("invert map", 8);
    glutAttachMenu(GLUT_RIGHT_BUTTON);

根据所选择的菜单进行相应的操作,默认情况下是通过glDrawPixels函数把图像放置在窗口的左下角显示。第一个菜单项Save Image是保存图像的快照。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值