Функция glClear: вопрос о параметрах - PullRequest
1 голос
/ 13 сентября 2011

Я бы хотел понять функцию glClear до ее глубокого уровня.Я понимаю его общее объяснение -> очистить буферы для цвета, глубины, трафарета и накопления, но у меня есть дополнительные вопросы.Мой друг предположил, что вы очищаете биты, которые представляют цвет, глубину, трафарет и накопление в памяти (стек?).Задавая и применяя параметры: (например, только цвет и глубина) «маски», вы очищаете только те биты в памяти (следовательно, «битовая операция»).

Возьмем пример:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

Объяснение параметров www.khronos.org для «маски».маска: побитовое ИЛИ масок, которые указывают на очищаемые буферы.

Вот мои вопросы:

  • Параметры GL_COLOR_BUFFER_BIT и GL_DEPTH_BUFFER_BIT представляют 1 бит памяти каждый?Или сколько битов они представляют (я хотел бы понять, как на самом деле применяется битовая маска)?
  • Я не вижу, как маска "ИЛИ" может отменять биты?Если вы используете «ИЛИ» для бита, который помечен как «установленный» (вместо «неустановленный»), он все равно вернет ноль (1 ИЛИ 0 по-прежнему возвращает 1)?Я вижу это совершенно неправильно / я что-то здесь упускаю?
  • Что происходит со знаком "или" (труба);почему эти параметры не разделены обычной запятой и не объявлена ​​ли побитовая операция «ИЛИ» в реальной функции?

Возможно, я путаю вещи, так как я новичок в этой области.Не могли бы вы дать мне исчерпывающее объяснение?Я предпочитаю не пропускать эти вопросы по мере продвижения в OpenGL;Я хочу знать, что я делаю, и понимание этого может помочь мне в этом.Спасибо!

Ответы [ 3 ]

7 голосов
/ 13 сентября 2011

Способ написания вещей обеспечивает большую гибкость, когда вы указываете, что вы хотите очистить.Вот как можно определить флаги:

#define GL_COLOR_BUFFER_BIT 1 // 0000 0001
#define GL_DEPTH_BUFFER_BIT 2 // 0000 0010

Как видите, это степень 2. Таким образом, в памяти только один бит установлен в 1 для каждого флага (очевидно, в разных позициях),Когда вы вычисляете побитовое ИЛИ для этих флагов, вы получаете 0000 0011. Чтобы узнать, установлен ли флаг в результирующем значении, вам просто нужно вычислить побитовое И с установленным флагом.

int foo = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; // foo = 0000 0011

if (foo & GL_COLOR_BUFFER_BIT) { // 0000 0011 & 0000 0001 => 0000 0001 (!= 0)
    // clear color buffer(which is located at a position OpenGL knows)
}
if (foo & GL_DEPTH_BUFFER_BIT) { // 0000 0011 & 0000 0010 => 0000 0010 (!= 0)
    // clear depth buffer
}
3 голосов
/ 13 сентября 2011

Битовая комбинация, которую вы даете glClear, не является битами, с которыми очищаются буферы.Буфер очищается индивидуально с помощью своего определенного чистого цвета (glClearColor) или значения чистой глубины (glClearDepth, я думаю?).Побитовые флаги для glClear только говорят ему, какие буферы очистить.Они разбиты на биты, чтобы просто указать более одного буфера для очистки.

РЕДАКТИРОВАТЬ: Вы можете представить , чтобы он работал следующим образом:

void glClear(unsigned int bits)
{
    if(bits & GL_COLOR_BUFFER_BIT)    //color bit is set
    {
        //clear color buffer using current clear color
    }
    if(bits & GL_DEPTH_BUFFER_BIT)    //depth bit is set
    {
        //clear depth buffer using current clear depth value (usually 1)
    }
    if(bits & GL_STENCIL_BUFFER_BIT)  //stencil bit is set
    {
        //clear stencil buffer using current clear stencil value (usually 0)
    }
}
1 голос
/ 13 сентября 2011

Как уже говорили другие, эти GL_COLOR_BUFFER_BIT и связанные битовые маски не имеют ничего общего с возможными значениями очистки, записанными в различные буферы. Каждый из них - это просто флаг, который glClear() проверяет внутри (используя побитовое И, как указывали другие), чтобы решить, на какие буферы действовать.

После проверки флагов буфера, концептуально, glClear() просто зацикливается на каждом пикселе в буфере кадра и устанавливает для него значение "clear", чтобы у вас был чистый лист для рисования. Эти значения устанавливаются с помощью glClearColor() и т.п. Вы можете представить это так:

void glClear(GLuint buffers)
{
  if (buffers & GL_COLOR_BUFFER_BIT) {
    for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; ++j) {
        colorBuffer[i][j].r = clearColor.r;
        colorBuffer[i][j].g = clearColor.g;
        colorBuffer[i][j].b = clearColor.b;
        colorBuffer[i][j].a = clearColor.a;
      }
    }
  }

  if (buffers & GL_DEPTH_BUFFER_BIT) {
    // Etc, using depthBuffer and glClearDepth value instead here
  }

  // etc. for accum & aux buffers.
}
...