【问题标题】:What's the correct way to draw a distorted plane in OpenGL?在OpenGL中绘制扭曲平面的正确方法是什么?
【发布时间】:2013-06-07 16:47:51
【问题描述】:

我尝试使用 GL_QUADS、GL_TRIANGLES 和 GL_POLYGON 扭曲平面:

glBegin(GL_QUADS);
for (int i = 0; i < squareIn.size(); i++) {
    glNormal3f(0,0,1);
    glTexCoord2f(squareIn[i]->v1->x,squareIn[i]->v1->y);
    glVertex2f(squareOut[i]->v1->x,squareOut[i]->v1->y);
    glTexCoord2f(squareIn[i]->v2->x,squareIn[i]->v2->y);
    glVertex2f(squareOut[i]->v2->x,squareOut[i]->v2->y);
    glTexCoord2f(squareIn[i]->v3->x,squareIn[i]->v3->y);
    glVertex2f(squareOut[i]->v3->x,squareOut[i]->v3->y);
    glTexCoord2f(squareIn[i]->v4->x,squareIn[i]->v4->y);
    glVertex2f(squareOut[i]->v4->x,squareOut[i]->v4->y);
    glTexCoord2f(squareIn[i]->v1->x,squareIn[i]->v1->y);
    glVertex2f(squareOut[i]->v1->x,squareOut[i]->v1->y);
}
glEnd();

但是当我进行极端扭曲时,它们都会给出这个结果:

预期结果:

我现在看到了两种可能的解决方案,使用 glNormal 或 glMultMatrixf。

glNormal 显然看起来是一个优雅的解决方案,而 glMultMatrixf 看起来很复杂。 但我找不到任何代码解释如何计算 glNormals 以纹理平面。

这里是a good example,使用 glMultMatrif。

【问题讨论】:

  • 从视觉上看,您到底期望发生什么?更重要的是,您使用的是哪一个:桌面 OpenGL 还是 OpenGL ES?因为它们不是一回事。
  • 嗨,Nicol,我正在使用 OpenGL ES,我期待类似 this image 的结果。
  • 为了进行透视插值,您需要为您的顶点提供适当的 w 坐标。您可以通过透视变换或直接设置它们来实现这一点。
  • 我该怎么做?你有一个简单的代码示例吗?谢谢!
  • 使用矩阵进行转换是最通用的,也可能是最强大的方法。我建议你采用这种方式,即使它需要更“复杂”的数学运算(并不是说可以分解矩阵,这样更容易处理)。

标签: c++ opengl-es


【解决方案1】:

我编写了一个将图像细分为多个部分的 OpenFramworks 代码,adapted from here

//----------------------------------------- setup   
#define GRID_X 8
#define GRID_Y 8

float * compL = new float[GRID_Y];
float * compR = new float[GRID_Y];

memset(compL, 0, GRID_Y * sizeof(float));
memset(compR, 0, GRID_Y * sizeof(float));

ofPoint * grid = new ofPoint[GRID_X * GRID_Y];
ofPoint * coor = new ofPoint[GRID_X * GRID_Y];


int width = imageGrid.width;
int height = imageGrid.height;

ofPoint quad[4];
ofPoint utQuad[4];  

//----------------------------------------- update
quad[0].set(0,0,0);
quad[1].set(width,0,0);
quad[2].set(mouseX,mouseY,0);
quad[3].set(0,height,0);

utQuad[0].set(0,0,0);
utQuad[1].set(1,0,0);
utQuad[2].set(1,1,0);
utQuad[3].set(0,1,0);

int gridSizeX = GRID_X;
int gridSizeY = GRID_Y;

float xRes = 1.0/(gridSizeX-1);
float yRes = 1.0/(gridSizeY-1);

for(int y = 0; y < gridSizeY; y++){
    for(int x = 0; x < gridSizeX; x++){

        int index = y*gridSizeX + x;


        float pctx  = (float)x * xRes;
        float pcty  = (float)y * yRes;

        float pctyL = pcty + yRes*compL[y];
        float pctyR = pcty + yRes*compR[y];

        float linePt0x  = (1-pctyL)*quad[0].x + pctyL * quad[3].x;
        float linePt0y  = (1-pctyL)*quad[0].y + pctyL * quad[3].y;
        float linePt1x  = (1-pctyR)*quad[1].x + pctyR * quad[2].x;
        float linePt1y  = (1-pctyR)*quad[1].y + pctyR * quad[2].y;

        float ptx       = (1-pctx) * linePt0x + pctx * linePt1x;
        float pty       = (1-pctx) * linePt0y + pctx * linePt1y;

        float utPt0x    = (1-pcty)*utQuad[0].x + pcty * utQuad[3].x;
        float utPt0y    = (1-pcty)*utQuad[0].y + pcty * utQuad[3].y;
        float utPt1x    = (1-pcty)*utQuad[1].x + pcty * utQuad[2].x;
        float utPt1y    = (1-pcty)*utQuad[1].y + pcty * utQuad[2].y;
        float tt        = (1-pctx) * utPt0x + pctx * utPt1x;
        float uu        = (1-pctx) * utPt0y + pctx * utPt1y;



        grid[index].set(ptx, pty, 0);
        coor[index].set( (tt * imageGrid.getTextureReference().texData.tex_t), imageGrid.getTextureReference().texData.bFlipTexture ? imageGrid.getTextureReference().texData.tex_u - (uu * imageGrid.getTextureReference().texData.tex_u) : (uu * imageGrid.getTextureReference().texData.tex_u), 0);
    }
}

//----------------------------------------- draw

ofSetColor(255, 255, 255);
ofFill();

glEnable(imageGrid.getTextureReference().texData.textureTarget);
glBindTexture( imageGrid.getTextureReference().texData.textureTarget, (GLuint)imageGrid.getTextureReference().texData.textureID);

for(int y = 0; y < gridSizeY-1; y++){
    for(int x = 0; x < gridSizeX-1; x++){

        glBegin(GL_QUADS);

        int pt0 = x + y*gridSizeX;
        int pt1 = (x+1) + y*gridSizeX;
        int pt2 = (x+1) + (y+1)*gridSizeX;
        int pt3 = x + (y+1)*gridSizeX;

        glTexCoord2f(coor[pt0].x, coor[pt0].y);
        glVertex2f(  grid[pt0].x, grid[pt0].y);

        glTexCoord2f(coor[pt1].x, coor[pt1].y);
        glVertex2f(  grid[pt1].x, grid[pt1].y);

        glTexCoord2f(coor[pt2].x, coor[pt2].y);
        glVertex2f(  grid[pt2].x, grid[pt2].y);

        glTexCoord2f(coor[pt3].x, coor[pt3].y);
        glVertex2f(  grid[pt3].x, grid[pt3].y);

        glEnd();

    }
}
glDisable(imageGrid.getTextureReference().texData.textureTarget);


//Draw grid
ofSetColor(255, 0, 0);
ofNoFill();
for(int y = 0; y < gridSizeY-1; y++){
    for(int x = 0; x < gridSizeX-1; x++){

        glBegin(GL_LINE_LOOP);

        int pt0 = x + y*gridSizeX;
        int pt1 = (x+1) + y*gridSizeX;
        int pt2 = (x+1) + (y+1)*gridSizeX;
        int pt3 = x + (y+1)*gridSizeX;

        glVertex2f(  grid[pt0].x, grid[pt0].y);
        glVertex2f(  grid[pt1].x, grid[pt1].y);
        glVertex2f(  grid[pt2].x, grid[pt2].y);
        glVertex2f(  grid[pt3].x, grid[pt3].y);

        glEnd();

    }
}

结果太棒了:

【讨论】:

    猜你喜欢
    • 2020-06-11
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多