Рендеринг сглаженных линий с текстурами = ›поиск очень простого примера

Существует этот сайт ...

... где объясняют, как нарисовать линию сглаживания.

Именно то, что я хочу!
но ...

Я не понимаю, как этого добиться для простой строчки. Я нашел онлайн-версию книги (статья в некотором роде взята из книги), я загрузил образец кода (показывающий фигурку, делающую причудливые движения), но происходит так много мамбожамбо ... какие-то странные скрипт python ... круги в виде png-изображений и файлов заголовков, почти все написано в cpp, файлы, которые я копирую в свой проект, вызывают множество ошибок, которые я не могу правильно исправить и так далее, и так далее. И я думаю, мне не нужны все эти причудливые штуки, так как я хочу рисовать линии только в простом приложении на основе cocos2d [Кстати .... Я не хотел использовать AA, но мои линии толще 5 пикселей, что делает их некрасивыми дырками при соединении (например, в круге, состоящем из нескольких линий), так что я должен использовать AA, как кажется].

Так есть ли у кого-то или нашелся крошечный кусочек исполняемого образца кода, используя принцип, описанный в связанной статье?


Примечания:

  1. На картинке вы видите дыры:
    http://pimml.de/circles.png

  2. Здесь вы найдете код упомянутого крупье (линии AA): http://examples.oreilly.com/9780596804831/readme.html#AaLines

  3. Вот как я рисую свои круги:

    int segments = 80;
    CGFloat width = 100;
    CGFloat height = 100;
    CGPoint center = ccp(800,200);  
    
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    //glEnable(GL_LINE_SMOOTH); // doesn't work on device
    glTranslatef(center.x, center.y, 0.0);
    glLineWidth(3.0f);
    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);
    }
    glVertexPointer (2, GL_FLOAT , 0, vertices); 
    glDrawArrays (GL_LINE_LOOP, 0, segments);
    
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);    
    

person Allisone    schedule 08.09.2010    source источник


Ответы (3)


Я тоже столкнулся с этой проблемой. Я потратил некоторое время на то, чтобы понять это ... Некоторое время я использовал решение, подобное этому (через walterBenjamin на Apple.com):

https://devforums.apple.com/message/264670

Это работает, это легко и красиво, но все же не самое лучшее (для того, что я делаю). В конце концов, я написал свое собственное решение, которое объединило рисование частиц GL Paint с его решением рисования линий точка-точка.

Я сделал массив и в touchesBegin, touchesMoved добавил к нему точку:

[currentStroke addObject:[NSValue valueWithCGPoint:point]]

Затем я перебираю штрихи, как вы видите в GL Paint, используя GL_Points.

person Beaker    schedule 16.09.2010
comment
Не беспокойся. Надеюсь, это помогло, извините, я не увидел его раньше! - person Beaker; 17.09.2010
comment
Что ж, вы здесь новенький, поэтому для меня даже большая честь, что мой был первым вопросом, на который вы ответили, хотя я полагал, что никто больше на него не ответит. Но я должен признать, что два дня назад я уже успешно реализовал AALine с техникой текстур (после многих мучительных проблем, связанных с таким количеством элементов и библиотек C ++, которые я не понимал, и смешивания с фреймворком obj-c cocos2d). Ваш сработал немедленно, и теперь я очищу свой код, оптимизирую его, а затем по производительности решу, какой метод использовать. - person Allisone; 17.09.2010
comment
Возможно, я найду время, чтобы опубликовать здесь какой-нибудь ясный и простой пример другой техники. - person Allisone; 17.09.2010
comment
Ха, спасибо. Я хотел бы опубликовать код, но я нахожусь под соглашением о неразглашении ... что раздражает. В любом случае, я не могу опубликовать код, но если у вас есть конкретные вопросы, я уверен, что смогу на них ответить, не создавая особых проблем. Примечание по производительности. Метод GL_Paint отлично подходит для линий, нарисованных пользователем, лучше, чем метод касательной из форумов Apple, просто потому, что он намного более гладкий. Однако он может замедлиться, и мне пришлось потратить немало времени на оптимизацию ... - person Beaker; 17.09.2010

Спасибо Полу Хэберли, вот код, которым он поделился со мной для рисования сглаженных прямоугольников, точек и линий:

/*
 *   Antialised 2D points, lines and rectangles for iOS devices
 *
 *   The feathered edge of these primitives is width/2.0.
 *
 *   If you are working in screen space, the width should be 1.0.
 *
 *       Paul Haeberli 2010
 *
 */
void fillSmoothRectangle(CGRect *r, float width)
{
    GLfloat rectVertices[10][2];
    GLfloat curc[4]; 
    GLint   ir, ig, ib, ia;

    // fill the inside of the rectangle
    rectVertices[0][0] = r->origin.x;
    rectVertices[0][1] = r->origin.y;
    rectVertices[1][0] = r->origin.x+r->size.width;
    rectVertices[1][1] = r->origin.y;
    rectVertices[2][0] = r->origin.x;
    rectVertices[2][1] = r->origin.y+r->size.height;
    rectVertices[3][0] = r->origin.x+r->size.width;
    rectVertices[3][1] = r->origin.y+r->size.height;

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, rectVertices);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    rectVertices[0][0] = r->origin.x;
    rectVertices[0][1] = r->origin.y;
    rectVertices[1][0] = r->origin.x-width;
    rectVertices[1][1] = r->origin.y-width;
    rectVertices[2][0] = r->origin.x+r->size.width;
    rectVertices[2][1] = r->origin.y;
    rectVertices[3][0] = r->origin.x+r->size.width+width;
    rectVertices[3][1] = r->origin.y-width;
    rectVertices[4][0] = r->origin.x+r->size.width;
    rectVertices[4][1] = r->origin.y+r->size.height;
    rectVertices[5][0] = r->origin.x+r->size.width+width;
    rectVertices[5][1] = r->origin.y+r->size.height+width;
    rectVertices[6][0] = r->origin.x;
    rectVertices[6][1] = r->origin.y+r->size.height;
    rectVertices[7][0] = r->origin.x-width;
    rectVertices[7][1] = r->origin.y+r->size.height+width;
    rectVertices[8][0] = r->origin.x;
    rectVertices[8][1] = r->origin.y;
    rectVertices[9][0] = r->origin.x-width;
    rectVertices[9][1] = r->origin.y-width;

    glGetFloatv(GL_CURRENT_COLOR, curc);
    ir = 255.0*curc[0];
    ig = 255.0*curc[1];
    ib = 255.0*curc[2];
    ia = 255.0*curc[3];

    const GLubyte rectColors[] = {
        ir, ig, ib, ia,
        ir, ig, ib, 0,
        ir, ig, ib, ia,
        ir, ig, ib, 0,
        ir, ig, ib, ia,
        ir, ig, ib, 0,
        ir, ig, ib, ia,
        ir, ig, ib, 0,
        ir, ig, ib, ia,
        ir, ig, ib, 0,
        ir, ig, ib, ia,
        ir, ig, ib, 0,
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, rectVertices);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, rectColors);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 10);
    glDisableClientState(GL_COLOR_ARRAY);
}

void drawSmoothLine(CGPoint *pos1, CGPoint *pos2, float width)
{
    GLfloat lineVertices[12], curc[4]; 
    GLint   ir, ig, ib, ia;
    CGPoint dir, tan;

    width = width*8;
    dir.x = pos2->x - pos1->x;
    dir.y = pos2->y - pos1->y;
    float len = sqrtf(dir.x*dir.x+dir.y*dir.y);
    if(len<0.00001)
        return;
    dir.x = dir.x/len;
    dir.y = dir.y/len;
    tan.x = -width*dir.y;
    tan.y = width*dir.x;

    lineVertices[0] = pos1->x + tan.x;
    lineVertices[1] = pos1->y + tan.y;
    lineVertices[2] = pos2->x + tan.x;
    lineVertices[3] = pos2->y + tan.y;
    lineVertices[4] = pos1->x;
    lineVertices[5] = pos1->y;
    lineVertices[6] = pos2->x;
    lineVertices[7] = pos2->y;
    lineVertices[8] = pos1->x - tan.x;
    lineVertices[9] = pos1->y - tan.y;
    lineVertices[10] = pos2->x - tan.x;
    lineVertices[11] = pos2->y - tan.y;

    glGetFloatv(GL_CURRENT_COLOR,curc);
    ir = 255.0*curc[0];
    ig = 255.0*curc[1];
    ib = 255.0*curc[2];
    ia = 255.0*curc[3];

    const GLubyte lineColors[] = {
        ir, ig, ib, 0,
        ir, ig, ib, 0,
        ir, ig, ib, ia,
        ir, ig, ib, ia,
        ir, ig, ib, 0,
        ir, ig, ib, 0,
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, lineVertices);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, lineColors);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
    glDisableClientState(GL_COLOR_ARRAY);
}


void drawSmoothPoint(CGPoint *pos, float width)
{
    GLfloat pntVertices[12], curc[4]; 
    GLint   ir, ig, ib, ia;

    pntVertices[0] = pos->x;
    pntVertices[1] = pos->y;
    pntVertices[2] = pos->x - width;
    pntVertices[3] = pos->y - width;
    pntVertices[4] = pos->x - width;
    pntVertices[5] = pos->y + width;
    pntVertices[6] = pos->x + width;
    pntVertices[7] = pos->y + width;
    pntVertices[8] = pos->x + width;
    pntVertices[9] = pos->y - width;
    pntVertices[10] = pos->x - width;
    pntVertices[11] = pos->y - width;

    glGetFloatv(GL_CURRENT_COLOR,curc);
    ir = 255.0*curc[0];
    ig = 255.0*curc[1];
    ib = 255.0*curc[2];
    ia = 255.0*curc[3];

    const GLubyte pntColors[] = {
        ir, ig, ib, ia,
        ir, ig, ib, 0,
        ir, ig, ib, 0,
        ir, ig, ib, 0,
        ir, ig, ib, 0,
        ir, ig, ib, 0,
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, pntVertices);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, pntColors);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
    glDisableClientState(GL_COLOR_ARRAY);
}
person snibbe    schedule 23.01.2011

Возможно, вы увидите это. Я решаю проблему по этой ссылке для opengl-es.

person AechoLiu    schedule 08.09.2010
comment
Сработало ли это с кругом 10 пикселей? У вас есть рабочий образец кода? - person Allisone; 09.09.2010
comment
Моя проблема в том, что моя текстура нарисована прямоугольником, а края нуждаются в сглаживании. Изучая этот сайт и получая ссылку, я решаю свою проблему, снова перерисовывая линии края. Сейчас он работает хорошо. Но мои коды - opengl-es, а не cocos2d. - person AechoLiu; 09.09.2010
comment
Cocos2d использует OpenGL-es. Это просто приятный фреймворк с множеством простых в использовании вещей, таких как спрайты, меню, анимация, переходы между сценами и т. Д. - person Allisone; 09.09.2010
comment
Возможно, однажды я изучу Cocos2d. Но в моем проекте сейчас используется iPhone-SDK и opengl-es. Я не начальник, так что ... - person AechoLiu; 09.09.2010