Графические артефакты с OpenGL? - PullRequest
0 голосов
/ 22 июля 2010

Я не уверен, называется ли это графическим артефактом, но посмотрите на это: http://img835.imageshack.us/img835/9785/anomoly.png

Вы заметите 6 пикселей на черном контуре, которые не на своем месте.

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

РЕНДЕР:

// Set an orthogonal projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(GetCameraX() - ((float)controls.MainGlFrame.Dimensions.x) * scene[current.currentScene].camera.ScaleFactor
        / 2, GetCameraX() + ((float)controls.MainGlFrame.Dimensions.x) * scene[current.currentScene].camera.ScaleFactor / 2,
        GetCameraY() - ((float)controls.MainGlFrame.Dimensions.y) * scene[current.currentScene].camera.ScaleFactor / 2, 
        GetCameraY() + ((float)controls.MainGlFrame.Dimensions.y) * scene[current.currentScene].camera.ScaleFactor / 2,
        -1.0f, 1.0f);

    // Set the model matrix as the current matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


    hdc = BeginPaint(controls.MainGlContext.mhWnd,&ps);


    //start OGL code

Структура камеры выглядит следующим образом:

struct SceneCam {
    double x;
    double y;
    double tempX;
    double tempY;
    double ScaleFactor;

};

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

Спасибо

Render:
void CGlEngine::RenderShapes()
{





    // Set an orthogonal projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(GetCameraX() - ((float)controls.MainGlFrame.Dimensions.x) * scene[current.currentScene].camera.ScaleFactor
        / 2, GetCameraX() + ((float)controls.MainGlFrame.Dimensions.x) * scene[current.currentScene].camera.ScaleFactor / 2,
        GetCameraY() - ((float)controls.MainGlFrame.Dimensions.y) * scene[current.currentScene].camera.ScaleFactor / 2, 
        GetCameraY() + ((float)controls.MainGlFrame.Dimensions.y) * scene[current.currentScene].camera.ScaleFactor / 2,
        -1.0f, 1.0f);

    // Set the model matrix as the current matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


    hdc = BeginPaint(controls.MainGlContext.mhWnd,&ps);


    //start OGL code


    glClear( GL_COLOR_BUFFER_BIT);






for(unsigned int currentlayer = 0; currentlayer < scene[current.currentScene].layer.size(); ++currentlayer)
{

    for(unsigned int i = 0; i < scene[current.currentScene].layer[currentlayer].Shapes.size(); i++)
    {

        //render shape here
        scene[current.currentScene].layer[currentlayer].Shapes[i].Render();



    }

}

for(int i = 0; i < TempBuffers.size(); ++i)
{
    if(scene[current.currentScene].layer[TempBuffers[i].layer].Shapes[TempBuffers[i].shape].Contour[0].DrawingPoints.size() > 1)
    {


    glColor3f(0,0,0);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB,controls.MainGlFrame.BufferVBO);
    glBufferDataARB(GL_ARRAY_BUFFER_ARB,sizeof(GLdouble) * scene[current.currentScene].layer[TempBuffers[i].layer].Shapes[TempBuffers[i].shape].Contour[0].DrawingPoints.size() * 2
        ,(GLdouble*)(&scene[current.currentScene].layer[TempBuffers[i].layer].Shapes[TempBuffers[i].shape].Contour[0].DrawingPoints[0]),GL_STATIC_COPY);


        glEnableClientState(GL_VERTEX_ARRAY);

    glBindBufferARB( GL_ARRAY_BUFFER_ARB, controls.MainGlFrame.BufferVBO);
    glVertexPointer( 2, GL_DOUBLE, 0, (char *) NULL );      // Set The Vertex Pointer To The Vertex Buffer

    if(scene[current.currentScene].layer[TempBuffers[i].layer].Shapes[TempBuffers[i].shape].connected)
    {
            glDrawArrays(GL_LINE_LOOP, 0, scene[current.currentScene].layer[TempBuffers[i].layer].Shapes[TempBuffers[i].shape].Contour[0].DrawingPoints.size());
    }
    else
    {
        glDrawArrays(GL_LINE_STRIP, 0, scene[current.currentScene].layer[TempBuffers[i].layer].Shapes[TempBuffers[i].shape].Contour[0].DrawingPoints.size());

    }

    glColor3f(1,0.5,0.5);
    //glDrawArrays(GL_POINTS, 0, layer[TempBuffers[i].layer].Shapes[TempBuffers[i].shape].Contour[0].DrawingPoints.size());

    glDisableClientState(GL_VERTEX_ARRAY);

    glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0);
    }
}
/*
    glColor3f(0,0,0);
    glLineWidth(2);
    */
/*
    if (ObjectBuffer.Contour[0].UserPoints.size() > 0)
    {

        glBegin(GL_LINES);
        for(unsigned int i = 0; i < ObjectBuffer.Contour[0].DrawingPoints.size() - 1; ++i)
        {
            glVertex2d(ObjectBuffer.Contour[0].UserPoints[i].UserPoint.x,ObjectBuffer.Contour[0].UserPoints[i].UserPoint.y);
            glVertex2d(ObjectBuffer.Contour[0].UserPoints[i + 1].UserPoint.x,ObjectBuffer.Contour[0].UserPoints[i + 1].UserPoint.y);
        }
        glEnd();
    }
*/



    //end OGL code
    glFlush();
    Sleep(1);

    SwapBuffers(hdc);



    EndPaint(controls.MainGlContext.mhWnd,&ps);


}

Изменить размер:

void CGlFrame::resize(HWND mainWindow,CGlContext *context, float rightRemainder)
{
    RECT clientRect;
    GetClientRect(mainWindow,&clientRect);

if(!hasstarted)
{
    context->killOGL();
    context->init(framehWnd,
        context->format);
    hasstarted = true;
    //Generate a VBO
    glGenBuffersARB(1,&BufferVBO);

}



SetWindowPos(framehWnd,NULL,toolWidth,tabHeight,
            (static_cast<int>(((clientRect.right - clientRect.left) - toolWidth) - rightRemainder) ) + toolWidth,
            (static_cast<int>((clientRect.bottom - clientRect.top) - tabHeight - paramHeight) ) ,NULL);



int width;
int height;
RECT newwin;
GetClientRect(framehWnd,&newwin);
width = newwin.right - newwin.left;
height = newwin.bottom - newwin.top;

Dimensions.x = width;
Dimensions.y = height;
glViewport(0, 0, width, height);




glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

glEnable(GL_MULTISAMPLE_ARB);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor( 1.0f, 1.0f, 1.0f, 0.0f );
glLineWidth(2);
glPointSize(5);

}

Визуализация формы:

void CGlShape::Render()
{
    if(!render)
    {
        return;
    }
glColor4f(MainShapeColor.r,MainShapeColor.g,MainShapeColor.b,MainShapeColor.a);
if(Gradient.active)
{
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,Gradient.TextureId);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);


glBindBufferARB( GL_ARRAY_BUFFER_ARB, ObjectVBOInt);
glVertexPointer( 2, GL_FLOAT, 0, (char *) NULL );       // Set The Vertex Pointer To The Vertex Buffer
glBindBufferARB( GL_ARRAY_BUFFER_ARB, TextureCoordsVBOInt);
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );     // Set The Vertex Pointer To The Vertex Buffer


glDrawArrays(GL_TRIANGLES, 0, ObjectVBOCount);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0);
glDisable(GL_TEXTURE_2D);

for(int i = 0; i < Contour.size(); ++i)
{
    glColor4f(Contour[i].Outline.OutlineColor.r,
        Contour[i].Outline.OutlineColor.g,
        Contour[i].Outline.OutlineColor.b,
        Contour[i].Outline.OutlineColor.a);

glBindBufferARB( GL_ARRAY_BUFFER_ARB, Contour[i].Outline.OutlineVBO);
glVertexPointer( 2, GL_FLOAT, 0, (char *) NULL );       // Set The Vertex Pointer To The Vertex Buffer
glDrawArrays(GL_TRIANGLES, 0, Contour[i].Outline.OutlineSize);
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0);
}
glDisableClientState(GL_VERTEX_ARRAY);


}

Редактировать

Мне удалось решить эту проблему, дважды отрисовав контуры с помощью gltranslation 0.00001.Это работает, но вызывает перерасход, хотелось бы лучшего решения.

1 Ответ

2 голосов
/ 22 июля 2010

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

Можно предположить, что черное сечение в виде пары GL_TRIANGLE_STRIP с вместо отдельного GL_TRIANGLES даст хороший шанс исправить проблему (также есть неплохой шанс немного улучшить производительность, поскольку уменьшает число вершин нужно дать).

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