Opengl ES 1.x светящийся эффект в iOS - PullRequest
2 голосов
/ 13 марта 2012

Я сейчас работаю над игрой для iOS. Теперь мне нужна функция для рисования произвольного светящегося и полупрозрачного эллипса с помощью opengl. Это довольно сложно, так как я использую cocos2d 1.1, который не поддерживает OpenGLES 2.0, поэтому нет шейдеров. Вот что я сделал:

Первая - это функция для рисования экструзионных линий, это от http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/

-(void) drawLineFrom:(CGPoint) start to:(CGPoint) end color:(ccColor4B) color width:(CGFloat) width texture:(CCTexture2D *) texture{
    // calculate direction vector
    CGPoint e = [self op:end minus:start];
    CGFloat length = sqrtf(e.x * e.x + e.y * e.y);
    e = ccp(e.x * width / length, e.y * width / length);

    CGPoint n = ccp(-e.y, e.x);
    CGPoint s = [self op:CGPointZero minus:n];
    CGPoint ne = [self op:n plus:e];
    CGPoint nw = [self op:n minus:e];
CGPoint sw = [self op:CGPointZero minus:ne];
    CGPoint se = [self op:CGPointZero minus:nw];

    // init vertices
    CGPoint vertices[8];
    vertices[0] = [self op:start plus:sw];
    vertices[1] = [self op:start plus:nw];
    vertices[2] = [self op:start plus:s];
    vertices[3] = [self op:start plus:n];
    vertices[4] = [self op:end plus:s];
    vertices[5] = [self op:end plus:n];
    vertices[6] = [self op:end plus:se];
    vertices[7] = [self op:end plus:ne];

    // init texture coordinates
    CGPoint texCoords[8] = {ccp(0, 0) ,ccp(0,1), ccp(0.5, 0), ccp(0.5, 1), ccp(0.5, 0), ccp(0.5, 1), ccp(1, 0), ccp(1, 1)};
    // init colors
    ccColor4B colors[8];
    for (int i = 0; i < 8; i++) {
        colors[i] = color;
    }

    glBindTexture(GL_TEXTURE_2D, texture.name);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
}

Тогда моя функция рисования эллипса. По сути, он разделил эллипс на множество маленьких линий и использовал вышеупомянутую функцию рисования линий для их рисования:

-(void) drawEllipse:(float) r focus1:(CGPoint) f1 focus2:(CGPoint) f2 {
    // load texture
    CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage: @"glow.png"];

    int segments = 50;
    CGFloat width = r / 2;
    CGFloat height = sqrtf(powf(r / 2, 2) - powf([Helper distanceFrom:f1 to:f2] / 2, 2));
    CGPoint center = CGPointMake((f1.x + f2.x) / 2, (f1.y + f2.y) / 2);

    glEnable(GL_TEXTURE_2D);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glTranslatef(center.x, center.y, 0.0);
    glRotatef(atanf((f1.y - f2.y) / (f1.x - f2.x)) * 180 / M_PI, 0, 0, 1);

    GLfloat vertices[segments * 2];
    int count = 0;
    for (GLfloat i = 0; i < 360.0f; i += (360.0f / segments)) {
        vertices[count++] = (cos(degreesToRadian(i)) * width);
        vertices[count++] = (sin(degreesToRadian(i)) * height);
    }

    int i = 0;
    CGFloat lineWidth = 20;
    ccColor4B lineColor = ccc4(255, 255, 255, 50);
    while (i < segments * 2 - 2) {
        [self drawLineFrom:ccp(vertices[i++], vertices[i++]) to:ccp(vertices[i++], vertices[i++]) color:lineColor width:lineWidth texture:texture];
    }
    [self drawLineFrom:ccp(vertices[segments * 2 - 2], vertices[segments * 2 - 1]) to:ccp(vertices[0], vertices[1]) color:lineColor width:lineWidth texture:texture];
}

Моя проблема в том, что в вышеописанном режиме наложения мой эллипс выглядит следующим образом:

enter image description here

Вы можете видеть, что режим наложения явно не правильный. Место, где соединяются линии, не похоже на другую часть из-за смешивания. Но я не могу понять, какой режим наложения мне следует использовать.

Я также попробовал glBlendEquation(GL_MAX_EXT), и это определенно делает мой эллипс намного лучше: enter image description here

Но проблема в том, что если я использую GL_MAX_EXT, альфа-значение цвета, похоже, полностью игнорируется, поэтому нет никакого способа сделать эллипс полупрозрачным. Может ли кто-нибудь помочь мне найти правильный способ сделать это? Большое спасибо!

Кстати, вот моя текстура:

enter image description here

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