【问题标题】:Displaying pixmap with glDrawPixels使用 glDrawPixels 显示像素图
【发布时间】:2011-04-05 07:55:51
【问题描述】:

我使用 OpenGL 和 GLUT 编写了一个小示例程序,以使用 glDrawPixels 函数显示由四个彩色方块组成的 2×2 网格。不幸的是,我发现:

  1. 网格中的颜色显示不正确;和
  2. 当向 glPixelZoom 函数传递负参数以旋转像素图时,窗口中不会显示任何内容。

以下 C++ 代码 sn-p 显示示例图像。我在这里做错了什么,我应该改变什么才能查看预期的颜色和旋转像素图?


struct RGB 
{
 unsigned char r, g, b;
};

class Pixmap
{
public:

 RGB color[4];

 Pixmap()
 {
  color[0].r = 255;
  color[0].g = 0;
  color[0].b = 0;

  color[1].r = 0;
  color[1].g = 255;
  color[1].b = 0;

  color[2].r = 0;
  color[2].g = 0;
  color[2].b = 255;

  color[3].r = 255;
  color[3].g = 255;
  color[3].b = 255;
 }

 void render()
 {
  glClear(GL_COLOR_BUFFER_BIT);
  glDrawPixels( 2, 2, GL_RGB, GL_UNSIGNED_BYTE, color );
  glFlush();
 }
};

// Create an instance of class Pixmap
Pixmap myPixmap;

void myRender()
{
 myPixmap.render();
}

int main( int argc, char *argv[] )
{
 int screenWidth, screenHeight;

 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

 screenWidth = glutGet(GLUT_SCREEN_WIDTH);
 screenHeight = glutGet(GLUT_SCREEN_HEIGHT);

 int windowWidth = screenHeight / 2;
 int windowHeight = screenHeight / 2;
 glutInitWindowSize(windowWidth, windowHeight);

 int posX = (screenWidth - windowWidth) / 2;
 int posY = (screenHeight - windowHeight) / 4;

 glutInitWindowPosition(posX, posY);
 glutCreateWindow("Picture");

 GLfloat scaleX = 1.0f * windowWidth / 2;
 GLfloat scaleY = 1.0f * windowHeight / 2;
 glMatrixMode( GL_PROJECTION );

        // If glPixelZoom(-scaleX, scaleY)
        // then no image is displayed

 glPixelZoom(scaleX, scaleY);

 glClearColor(1.0, 1.0, 1.0, 0.0);
 glColor3f(0.0f, 0.0f, 0.0f);

 glutDisplayFunc( myRender );
 glutMainLoop();
}




【问题讨论】:

    标签: c++ opengl graphics


    【解决方案1】:

    经过一些实验,我认为我找到了一个似乎适合我自己目的的解决方案。首先,鉴于我上面问题中的示例代码,像素图似乎需要作为具有 alpha 通道的数组 GLubyte color[2][2][4] 传递给 glDrawPixels 函数。正如 Vaayu 所提到的,glMatrixMode 函数也有可能需要正确设置。其次,根据 pg。 OpenGL 编程指南(第 7 版)的第 356 节,如果使用负参数调用 glPixelZoom 函数,则需要设置当前光栅位置。本质上,为什么我看不到图像是因为光栅被绘制在一个不在窗口可视区域内的位置。以下代码演示了如何为四种不同情况设置旋转和当前光栅位置:

    
    // case 0
    glWindowPos2i(0, 0);
    glPixelZoom(scaleX, scaleY);
    
    

    // case 1 glWindowPos2i(windowHeight, 0); glPixelZoom(-scaleX, scaleY);

    // case 2 glWindowPos2i(0, windowHeight); glPixelZoom(scaleX, -scaleY);

    // case 3 glWindowPos2i(windowWidth, windowHeight); glPixelZoom(-scaleX, -scaleY);

    所以我原来的问题中给出的例子可以更新:

    类像素图 { 民众: GLubyte 颜色[2][2][4]; 像素图() { // 红色的 颜色[0][0][0] = 255; 颜色[0][0][1] = 0; 颜色[0][0][2] = 0; 颜色[0][0][3] = 0; // 绿色 颜色[0][1][0] = 0; 颜色[0][1][1] = 255; 颜色[0][1][2] = 0; 颜色[0][1][3] = 0; // 蓝色 颜色[1][0][0] = 0; 颜色[1][0][1] = 0; 颜色[1][0][2] = 255; 颜色[1][0][3] = 0; // 白色的 颜色[1][1][0] = 255; 颜色[1][1][1] = 255; 颜色[1][1][2] = 255; 颜色[1][1][3] = 0; } 无效渲染() { glClear(GL_COLOR_BUFFER_BIT); glDrawPixels(2, 2, GL_RGBA, GL_UNSIGNED_BYTE, 颜色); glFlush(); } }; // 创建类 Pixmap 的实例 像素图 myPixmap; 无效我的渲染() { myPixmap.render(); } int main(int argc, char *argv[]) { 整数屏幕宽度,屏幕高度; 整数旋转; // 选择旋转情况 {0, 1, 2, 3} 旋转 = 3; glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); screenWidth = glutGet(GLUT_SCREEN_WIDTH); screenHeight = glutGet(GLUT_SCREEN_HEIGHT); int windowWidth = screenHeight / 2; int windowHeight = screenHeight / 2; glutInitWindowSize(windowWidth, windowHeight); int posX = (screenWidth - windowWidth) / 2; int posY = (screenHeight - windowHeight) / 4; glutInitWindowPosition(posX, posY); glutCreateWindow("图片"); GLfloat scaleX = 1.0f * windowWidth / 2; GLfloat scaleY = 1.0f * windowHeight / 2; glMatrixMode(GL_MODELVIEW); // 选择旋转 开关(旋转) { 案例0: glWindowPos2i(0, 0); glPixelZoom(scaleX, scaleY); 休息; 情况1: glWindowPos2i(windowHeight, 0); glPixelZoom(-scaleX, scaleY); 休息; 案例2: glWindowPos2i(0, windowHeight); glPixelZoom(scaleX, -scaleY); 休息; 案例3: glWindowPos2i(windowWidth, windowHeight); glPixelZoom(-scaleX, -scaleY); 休息; 默认: 休息; } glClearColor(1.0, 1.0, 1.0, 0.0); glColor3f(0.0f, 0.0f, 0.0f); glutDisplayFunc(myRender); 过剩主循环(); }

    【讨论】:

      【解决方案2】:
      glMatrixMode( GL_PROJECTION );
      

      上面那一行是引起问题的那一行。将其更改为“glMatrixMode(GL_MODELVIEW);”因为您并没有真正将投影矩阵用于任何事情。

      投影矩阵用于设置投影参数,如透视/正交模式、FOV 等。这通常需要在创建窗口时以及窗口/视口大小发生变化时进行。模型视图矩阵用于平移、旋转和缩放。

      由于 OpenGL 的工作方式,跟踪“状态”非常重要。一般的工作流程是设置投影模式,根据需要更改参数并立即更改回模型视图模式,例如:

      glMatrixMode(GL_PROJECTION);
      //...
      //do various projection stuff
      //...
      glMatrixMode(GL_MODELVIEW);
      

      这适用于 OpenGL 中的许多事物,不仅是矩阵状态,还有其他事物,如灯光、混合等。在执行另一组操作之前返回“默认”状态并再次切换回默认状态是很常见的。

      【讨论】:

      • 感谢您的建议,瓦尤。我尝试更改您建议的线路,但对我来说问题仍然存在。颜色没有正确显示,当我尝试将负参数传递给 glPixelZoom 函数时,只显示白色背景。也许这是一个特定于平台的问题?我正在使用 gcc 4.2.1 处理 Mac OS X 10.6.4。
      • 也许还有另一种方法可以做我想做的事(如上面代码所示显示一个像素图),而且这种方法不涉及glDrawPixels函数?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-13
      相关资源
      最近更新 更多