Нежелательная прозрачность в OpenGL

#cocoa #opengl

#cocoa #opengl

Вопрос:

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

 float rot = 0.01;

@implementation ECGameView

- (void)prepareOpenGL {
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0, 0.0, 0.0, 0.0);

    glEnable(GL_NORMALIZE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_CULL_FACE);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);

    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_shininess[] = { 50.0 };
    GLfloat lightPosition[] = { 1.0, 1.0, 1.0, 0.0 };
    GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat lmodel_ambient[] = { 0.1, 0.1, 0.1, 1.0 };

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
    glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

    NSImage * texImg = [NSImage imageNamed:@"texture.png"];
    glGenTextures(1, amp;texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    NSBitmapImageRep * bitmap = [NSBitmapImageRep imageRepWithData:[texImg TIFFRepresentation]];
    glTexImage2D(GL_TEXTURE_2D, 0, 3, [texImg size].width, [texImg size].height, 0, GL_RGB, GL_UNSIGNED_BYTE, [bitmap bitmapData]) ;
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    updateTimer = [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(update:) userInfo:nil repeats:TRUE];
}

- (void) update:(NSTimer*)timer; {
    [self setNeedsDisplay:TRUE];
}

- (void)reshape {
    NSSize size = self.bounds.size;
    glViewport(0,0, size.width, size.height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, size.width/size.height, 0.1, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -10.0);
}

- (void)drawRect:(NSRect)rect {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindTexture(GL_TEXTURE_2D, texture);

    glRotatef(rot, 1, 0, 1);
    rot = (rot   .01);

    static GLfloat vertices[] = {1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
    1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0,
    1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
    -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0,
    -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
    -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0};

    static GLfloat normals[] = {1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
    1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0,
    1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
    -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0,
    -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
    -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0};

    static const GLfloat texCoords[] = {
    0.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
    1.0, 0.0,
    0.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
    1.0, 0.0,
    0.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
    1.0, 0.0,
    0.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
    1.0, 0.0,
    0.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
    1.0, 0.0
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glNormalPointer(GL_FLOAT, 0, normals);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glDrawArrays(GL_QUADS, 0, 24);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glFlush();
}
  

Весь рисунок выполняется в ECGameView , который является подклассом NSOpenGLView, с Gluint переменной в заголовке. У кого-нибудь есть какие-нибудь идеи?

Кстати, я знаю, что это большой объем кода, но я, честно говоря, не знаю, что не так, и все эти вещи, похоже, применимы.

РЕДАКТИРОВАТЬ: Я только что удалил раскраску в своем коде, и она показывает оранжевый куб. Я думаю, это означает, что текстура вроде как работает (текстура ниже, из http://www.nullterminator.net/gltexture.html).

Текстуру, которую я использую для этого теста

ПРАВКА 2: ПОЖАЛУЙСТА, помогите мне разобраться в этом. Проблема с текстурированием решена, но проблема, о которой я спрашивал, не решена. Я получаю странное отверстие на одной стороне куба. Код был обновлен

Странная дыра

РЕДАКТИРОВАТЬ 3: Я понял, почему это происходит, но я не знаю, как это исправить. Это отрисовка текстуры на неправильной стороне плоскости (обратной стороне куба). Как я могу заставить его рисовать с правильной стороны?

Комментарии:

1. Вы уверены, что они становятся прозрачными? Вы пробовали менять фон, чтобы посмотреть, действительно ли они становятся прозрачными или, может быть, темнее? Если они станут темнее, это будет из-за вашего освещения.

2. И что вы имеете в виду, текстура невидима? Вы имеете в виду, что видите куб только в цвете, а не с текстурой? Или весь объект при текстурировании каким-то образом невидим?

3. Вы установили режим текстурного окружения?

4. Я думаю , что текстура просто не отображается, но я выполнил проверку на ошибки, и она загружена правильно. Это очень сбивает с толку.

5. Я только что проверил цвет, и я действительно могу видеть насквозь первую половину куба. Я вижу, как соединяются две стороны и низ.

Ответ №1:

Я нигде не вижу, чтобы текстурирование было включено. glEnable(GL_TEXTURE_2D);

редактировать: я также думаю, что вам понадобится 24 пары текстурных координат (s, t).

наконец: похоже, вы не включили отбраковку задней поверхности: glEnable(GL_CULL_FACE); Вам также следует обратить внимание на glPolygonMode , не является ли порядок вершин (намотка) граней по умолчанию против часовой стрелки.

Комментарии:

1. Как мне их вставить? Я понятия не имею, что вы подразумеваете под «24 (s, t) парами текстурных координат»

2. @Justin: Вы указали координаты текстуры только для первого GL_QUAD. Вы хотите сделать это еще 5 раз. вероятно, GL считывает мусор после конца массива texCoords.

3. Это сработало. К сожалению, это все еще оставляет меня с этой странной проблемой прозрачности. Я собираюсь опубликовать его фотографию через несколько минут.

4. У меня все еще есть квадратное отверстие на одной из 6 сторон. Это делает прозрачной почти половину стороны