Отображение растрового изображения с glDrawPixels - PullRequest
2 голосов
/ 29 августа 2010

Я написал небольшую примерную программу, использующую OpenGL и GLUT, для отображения сетки 2 на 2 из четырех цветных квадратов с помощью функции glDrawPixels.К сожалению, я обнаружил, что:

  1. Цвета в сетке не отображаются должным образом;и
  2. Когда функции glPixelZoom передаются отрицательные аргументы для поворота растрового изображения, в окне ничего не отображается.

В следующем фрагменте кода C ++ показано изображение примера.Что я здесь делаю не так, и что я должен изменить, чтобы иметь возможность просматривать предполагаемые цвета и поворачивать растровое изображение?


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();
}




Ответы [ 2 ]

2 голосов
/ 30 августа 2010

После некоторых экспериментов я думаю, что нашел решение, которое кажется подходящим для моих собственных целей.Во-первых, учитывая пример кода в моем вопросе выше, кажется, что растровое изображение необходимо передать в функцию glDrawPixels в виде массива GLubyte color[2][2][4] с альфа-каналом.Как уже упоминал Ваайю, существует также вероятность того, что функция glMatrixMode должна быть настроена правильно.Во-вторых, согласно с.356 Руководства по программированию OpenGL (7-е издание), текущая позиция растра должна быть установлена, если функция glPixelZoom вызывается с отрицательными аргументами.По сути, я не мог видеть изображение из-за того, что растр был нарисован в позиции, не входящей в видимую область окна.Следующий код демонстрирует, как установить вращение и текущую позицию растра для четырех отдельных случаев:

<code>
// case 0
glWindowPos2i(0, 0);
glPixelZoom(scaleX, scaleY);</p>

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

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

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

Так что пример, приведенный в моем исходном вопросе, можно обновить:

class Pixmap
{
public:

    GLubyte color[2][2][4];

    Pixmap()
    {
        // red
        color[0][0][0] = 255;
        color[0][0][1] = 0;
        color[0][0][2] = 0;
        color[0][0][3] = 0;

        // green
        color[0][1][0] = 0;
        color[0][1][1] = 255;
        color[0][1][2] = 0;
        color[0][1][3] = 0;

        // blue
        color[1][0][0] = 0;
        color[1][0][1] = 0;
        color[1][0][2] = 255;
        color[1][0][3] = 0;

        // white
        color[1][1][0] = 255;
        color[1][1][1] = 255;
        color[1][1][2] = 255;
        color[1][1][3] = 0;
    }

    void render()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawPixels( 2, 2, GL_RGBA, 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;
    int rotation;

    // Choose rotation case {0, 1, 2, 3}
    rotation = 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("Picture");

    GLfloat scaleX = 1.0f * windowWidth / 2;
    GLfloat scaleY = 1.0f * windowHeight / 2;

    glMatrixMode(GL_MODELVIEW);

    // Select rotation
    switch(rotation)
    {
    case 0:
        glWindowPos2i(0, 0);
        glPixelZoom(scaleX, scaleY);
        break;
    case 1:
        glWindowPos2i(windowHeight, 0);
        glPixelZoom(-scaleX, scaleY);
        break;
    case 2:
        glWindowPos2i(0, windowHeight);
        glPixelZoom(scaleX, -scaleY);
        break;
    case 3:
        glWindowPos2i(windowWidth, windowHeight);
        glPixelZoom(-scaleX, -scaleY);
        break;
    default:
    break;
    }

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

    glutDisplayFunc( myRender );
    glutMainLoop();
}

2 голосов
/ 29 августа 2010
glMatrixMode( GL_PROJECTION );

Приведенная выше строка вызывает проблемы.Измените его на «glMatrixMode (GL_MODELVIEW);»так как вы на самом деле не используете матрицу проекции для чего-либо.

Матрица проекции используется для установки параметров проекции, таких как перспективный / орфографический режим, FOV и т. д. Это необходимо сделать обычно во время создания окна ивсякий раз, когда размер окна / области просмотра изменяется.Матрица просмотра модели используется для переводов, поворотов и масштабирования.

В связи с тем, как работает OpenGL, очень важно отслеживать «состояние».Общий рабочий процесс состоит в том, чтобы установить режим проецирования, изменить необходимые параметры и немедленно вернуться в режим просмотра модели, например:

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

Это относится ко многим вещам в OpenGL, не только к состоянию матрицы, но и к другим вещам, таким каксвет, смешивание и т. д. тоже.Очень часто в состоянии «по умолчанию» возвращаться после выполнения набора операций перед выполнением другого набора операций и повторного переключения в состояние по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...