2015-01-12 1 views
0

OpenGL을 처음 접했고 여러 자습서를 읽고 있는데 개체를 렌더링하는 데 사용되는 여러 가지 방법이 있다는 것을 알았지 만 여전히 그 차이점과 각 기능을 사용할 때 차이점이 있습니까?OpenGL : 다중 렌더링 방법 .. 언제 사용합니까?

예를 들어,이 큐브를 렌더링하기 위해 셰이더를 사용하는이 example을 따르고 있으며 "정상적인"방법으로 렌더링하려했을 때 - 이것이 올바른 표현 인 경우. 아무것도 렌더링되지 않습니다. 난 항상 shaderProgram.setAttributeArray(), shaderProgram.enableAttributeArray()shaderProgram.disableAttributeArray()

를 호출해야하지만 그것은 바로 다른 방법을 사용하여 렌더링을 시도하는 경우 - 다시,이 glBegin()glEnd()를 사용하여 올바른 expression- 경우. 아무것도 내가 그것을 사용해야 할 때, 난 정말 이해가 안 나는 또 다른 질문 쉐이더 개념 자체를 가지고, 또한

작동되지 않고해야하지 여기

내 예를 때 :

#include "glwidget.h" 

GlWidget::GlWidget(QWidget *parent) 
    : QGLWidget(QGLFormat(/* Additional format options */), parent) 
{ 
    alpha = 25; 
    beta = -25; 
    distance = 2.5; 
} 

void GlWidget::initializeGL() 
{ 
    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_CULL_FACE); 

    qglClearColor(QColor(Qt::white)); 

    shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh"); 
    shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh"); 
    shaderProgram.link(); 

    vertices << QVector3D(-0.5, -0.5, 0.5) << QVector3D(0.5, -0.5, 0.5) << QVector3D(0.5, 0.5, 0.5) // Front 
      << QVector3D(0.5, 0.5, 0.5) << QVector3D(-0.5, 0.5, 0.5) << QVector3D(-0.5, -0.5, 0.5) 
      << QVector3D(0.5, -0.5, -0.5) << QVector3D(-0.5, -0.5, -0.5) << QVector3D(-0.5, 0.5, -0.5) // Back 
      << QVector3D(-0.5, 0.5, -0.5) << QVector3D(0.5, 0.5, -0.5) << QVector3D(0.5, -0.5, -0.5) 
      << QVector3D(-0.5, -0.5, -0.5) << QVector3D(-0.5, -0.5, 0.5) << QVector3D(-0.5, 0.5, 0.5) // Left 
      << QVector3D(-0.5, 0.5, 0.5) << QVector3D(-0.5, 0.5, -0.5) << QVector3D(-0.5, -0.5, -0.5) 
      << QVector3D(0.5, -0.5, 0.5) << QVector3D(0.5, -0.5, -0.5) << QVector3D(0.5, 0.5, -0.5) // Right 
      << QVector3D(0.5, 0.5, -0.5) << QVector3D(0.5, 0.5, 0.5) << QVector3D(0.5, -0.5, 0.5) 
      << QVector3D(-0.5, 0.5, 0.5) << QVector3D(0.5, 0.5, 0.5) << QVector3D(0.5, 0.5, -0.5) // Top 
      << QVector3D(0.5, 0.5, -0.5) << QVector3D(-0.5, 0.5, -0.5) << QVector3D(-0.5, 0.5, 0.5) 
      << QVector3D(-0.5, -0.5, -0.5) << QVector3D(0.5, -0.5, -0.5) << QVector3D(0.5, -0.5, 0.5) // Bottom 
      << QVector3D(0.5, -0.5, 0.5) << QVector3D(-0.5, -0.5, 0.5) << QVector3D(-0.5, -0.5, -0.5); 
} 

void GlWidget::resizeGL(int width, int height) 
{ 
    if (height == 0) { 
     height = 1; 
    } 

    pMatrix.setToIdentity(); 
    pMatrix.perspective(60.0, (float) width/(float) height, 0.001, 1000); 

    glViewport(0, 0, width, height); 
} 

void GlWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    QMatrix4x4 mMatrix; 
    QMatrix4x4 vMatrix; 

    QMatrix4x4 cameraTransformation; 
    cameraTransformation.rotate(alpha, 0, 1, 0); 
    cameraTransformation.rotate(beta, 1, 0, 0); 

    QVector3D cameraPosition = cameraTransformation * QVector3D(0, 0, distance); 
    QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0); 

    vMatrix.lookAt(cameraPosition, QVector3D(0, 0, 0), cameraUpDirection); 

    shaderProgram.bind(); 
    shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix); 

    // This code is able to draw the cube 
    shaderProgram.setAttributeArray("vertex", vertices.constData()); 
    shaderProgram.enableAttributeArray("vertex"); 
    glDrawArrays(GL_TRIANGLES, 0, vertices.size()); 
    shaderProgram.disableAttributeArray("vertex"); 
    // end 

    // This code is never able to draw the cube or anything 
    glBegin(GL_TRIANGLES); 
    for (int var = 0; var < vertices.size(); ++var) { 
     glVertex3f(vertices[var][0],vertices[var][1],vertices[var][2]); 
    } 
    glEnd(); 
    // end 

    shaderProgram.release(); 
} 

답변

3

OpenGL은 사용 'immediate mode'이 무엇인지 확인하십시오. 이 경우 glBegin()glEnd()을 사용하고 그 사이에 데이터 (점, 법선, 텍스처 좌표)를 점으로 지정하십시오. 모든 프레임에서이 작업을 수행하므로 매우 느립니다. 이 기능은 오랫동안 사용되지 않았지만 대부분의 그래픽 카드 드라이버는 기존 소프트웨어를 손상시키지 않도록 지원합니다. 그러나 현대 OpenGL을 배우고 싶다면 glBegin()이 포함 된 튜토리얼을 무시합니다. 오늘 한 번에 데이터를 GPU로 전송 한 다음 (을 사용하여) 한 명령으로 그립니다.

다른 질문은 쉐이더에 관한 것입니다. 다시 말하지만, 예전에는 OpenGL이 fixed-function pipeline이었습니다. 이는 꼭지점 (정상, ...) 데이터 만 제공한다는 것을 의미하며 그래픽 카드는 계속 진행되며 그 일을합니다. 데이터로 수행하는 작업을 수정할 수 없습니다. 현대 세계에서 파이프 라인의 일부는 프로그래밍이 가능합니다. 즉, 파이프 라인의 일부분을 변경할 수 있습니다 (자체 프로그램을 제공하여 - shaders). 그렇지 않으면 불가능한 많은 효과가 있기 때문에 이것은 매우 유용합니다. 다시 말하지만, 쉐이더를 직접 제공하지 않으면 그래픽 카드가 호환성 문제로 인해 기본 구현으로 대체됩니다. 그러나 당신은 반드시 자신 만의 쉐이더를 작성해야합니다 (기본적인 것은 몇 줄에 불과합니다).

현대식 OpenGL (VBO, VAO, 쉐이더)을 배우기 시작하면 기본 사항을 익히는 데 약간 시간이 걸릴 수 있지만 레거시 소재를 배우기 시작하면 언젠가는 떠나야합니다. 그것을 시작하고 현대 OpenGL을 배우는 처음부터 다시 시작하십시오.

편집 : 일반적으로 현대 코드와 기존 코드를 혼합하는 것은 좋지 않습니다. 당신은 효과가 있을지 모르지만 고통의 가치가있는 것은 아닙니다.

+0

고마워요. 많은 것들을 깨끗하게합니다. – fujy

+0

하지만 마지막 질문에서 정확히 어떤 사람이 VertexBufferObject와 VertexArrayObject를 사용합니까? – fujy

+0

또한이 예제는'glDrawArrays (GL_TRIANGLES, 0, vertices.size());'호출을 사용하여 삼각형을 렌더링하는 방법을 보여줍니다. 그러나'Normals'와 같이 렌더링하고 싶다면 어떻게해야합니까?'shaders '모드? .. 즉,'glNormal3d()'호출의 대안은 무엇입니까? – fujy