gpt4 book ai didi

c++ - 我可以纹理这个在 GL_TRIANGLE_STRIP 模式下渲染的立方体吗?

转载 作者:行者123 更新时间:2023-12-01 14:48:37 25 4
gpt4 key购买 nike

我正在尝试使用 GL_TRIANGLE_STRIP 模式渲染和纹理立方体。

多维数据集的基本信息在以下数组中。它被正确加载,形状还可以。

    float vertexData[24] = { //Coordinates for the vertices of a cube.
//vertices
1, 1, -1,
-1, 1, -1,
1, -1, -1,
-1, -1, -1,
1, 1, 1,
-1, 1, 1,
-1, -1, 1,
1, -1, 1
};

int vertexDrawIndices[14] = { //Draw order for vertices in GL_TRIANGLE_STRIP mode.
3,2,6,7,4,2,0,3,1,6,5,4,1,0
};

为了构建这个简单的立方体数据,我引用了这张图片: rendering a cube in one triangle strip

现在对于纹理,我可以向这个立方体添加纹理坐标吗?还是被诅咒被单色遮蔽?

如果我必须用逻辑来回答我自己的问题,我会说像这样纹理化它是不可能的,但也许有人知道一种方法?

最佳答案

多么美妙的谜题…… – 重新开始工作前的正确热身。

我看到两种可能的解决方案:

  • 使用立方体纹理
  • 修改顶点数据。

  • 对于立方体纹理映射,我想引用
    Learn OpenGL – Cubemaps .
    因此,顶点坐标也应该可用作纹理坐标。

    OP 的原始方法不适用于单个纹理,因为存在具有相同坐标但不同纹理坐标的顶点。

    所以,我最终会得到一个包含 14 个坐标和 14 个纹理坐标(或两个相应的数组)的新数组。

    当我尝试将其应用于 OP 的展开时,我得出的结论是,即使这也是不可能的。例如。坐标 3 和 4 出现在展开立方体的顶部和底部 → 再次导致同一顶点的两个不同的纹理坐标。

    幸运的是,我在很多年前就已经解决了带一个三角形 strip 的立方体拼图(当时 OpenGL Performer 仍然是最先进的)。查看我的旧笔记,我发现我的展开更适合预期的纹理。

    a cube unwrapped into a triangle strip以红色三角形开始,以蓝色结束。

    我复制/粘贴了那个旧样本的坐标:
      const GLfloat x0 = -1, x1 = 1, y0 = -1, y1 = 1, z0 = -1, z1 = 1;
    const GLfloat coords[] = {
    x0, y1, z1,
    x0, y0, z0,
    x0, y0, z1,
    x1, y0, z1,
    x0, y1, z1,
    x1, y1, z1,
    x1, y1, z0,
    x1, y0, z1,
    x1, y0, z0,
    x0, y0, z0,
    x1, y1, z0,
    x0, y1, z0,
    x0, y1, z1,
    x0, y0, z0
    };

    所以,我所要做的就是使用草图作为纹理并写下相应的内容。纹理坐标:
      const GLfloat s0 = 0, s1 = 1.f / 5, s2 = 2.f / 5, s3 = 3.f / 5, s4 = 4.f / 5, s5 = 1;
    const GLfloat t0 = 0, t1 = 1.f / 5, t2 = 2.f / 5, t3 = 3.f / 5, t4 = 4.f / 5, t5 = 1;
    const GLfloat texCoords[] = {
    s0, t1,
    s1, t0,
    s1, t1,
    s2, t1,
    s1, t2,
    s2, t2,
    s2, t3,
    s3, t2,
    s3, t3,
    s4, t3,
    s3, t4,
    s4, t4,
    s4, t5,
    s5, t4
    };

    为了检查这一点,我将其应用于最小的 QOpenGLWidget我在我的个人文件夹中找到的样本,使用上面的图像作为纹理。
    testQOpenGLTexCube.cc :
    #include <QtWidgets>
    #include <QOpenGLFunctions_3_3_Compatibility>

    class GLWidget: public QOpenGLWidget,
    protected QOpenGLFunctions_3_3_Compatibility
    {
    private:
    QOpenGLTexture *_pGLTex;
    QOpenGLShaderProgram *_pGLPrg;
    GLuint _coordAttr;
    GLuint _texCoordAttr;
    GLuint _matUniform;
    double _t;
    QMatrix4x4 _matProj;
    QTimer _qTimerAnim;

    public:

    GLWidget(QWidget *pQParent = nullptr):
    QOpenGLWidget(pQParent),
    _pGLTex(nullptr), _pGLPrg(nullptr), _t(0)
    {
    QObject::connect(&_qTimerAnim, &QTimer::timeout,
    [this]() { _t += 0.1; update(); });
    }

    virtual ~GLWidget() = default;

    GLWidget(const GLWidget&) = delete;
    GLWidget& operator=(const GLWidget&) = delete;

    public:

    virtual QSize minimumSizeHint() const
    {
    return QSize(50, 50);
    }
    virtual QSize sizeHint() const
    {
    return QSize(400, 400);
    }

    protected:

    virtual void initializeGL();
    virtual void resizeGL(int width, int height);
    virtual void paintGL();

    };

    static const char *vertexShaderSource =
    "# version 330\n"
    "layout (location = 0) in vec3 coord;\n"
    "layout (location = 1) in vec2 texCoord;\n"
    "uniform mat4 mat;\n"
    "out vec2 texCoordVtx;\n"
    "void main() {\n"
    " texCoordVtx = texCoord;\n"
    " gl_Position = mat * vec4(coord, 1.0);\n"
    "}\n";

    static const char *fragmentShaderSource =
    "#version 330\n"
    "in vec2 texCoordVtx;\n"
    "uniform sampler2D tex;\n"
    "out vec4 colorFrag;\n"
    "void main() {\n"
    " colorFrag = texture2D(tex, texCoordVtx.xy);\n"
    "}\n";

    void GLWidget::initializeGL()
    {
    initializeOpenGLFunctions();
    glClearColor(0.525f, 0.733f, 0.851f, 1.0f);
    _qTimerAnim.start();
    }

    void GLWidget::resizeGL(int w, int h)
    {
    _matProj.setToIdentity();
    _matProj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
    }

    void GLWidget::paintGL()
    {
    const qreal retinaScale = devicePixelRatio();
    glViewport(0, 0, width() * retinaScale, height() * retinaScale);
    // clear screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // create texture if not yet done
    if (!_pGLTex) {
    _pGLTex = new QOpenGLTexture(QImage("cube-tex.png").mirrored());
    _pGLTex->setMagnificationFilter(QOpenGLTexture::Nearest);
    _pGLTex->setMinificationFilter(QOpenGLTexture::Nearest);
    }
    // create shader program if not yet done
    if (!_pGLPrg) {
    _pGLPrg = new QOpenGLShaderProgram(this);
    _pGLPrg->addShaderFromSourceCode(QOpenGLShader::Vertex,
    vertexShaderSource);
    _pGLPrg->addShaderFromSourceCode(QOpenGLShader::Fragment,
    fragmentShaderSource);
    _pGLPrg->link();
    _coordAttr = _pGLPrg->attributeLocation("coord");
    _texCoordAttr = _pGLPrg->attributeLocation("texCoord");
    _matUniform = _pGLPrg->uniformLocation("mat");
    _pGLPrg->setUniformValue("tex", 0);
    }
    // render textured cube
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    _pGLPrg->bind();
    _pGLTex->bind();
    QMatrix4x4 mat = _matProj;
    mat.translate(0, 0, -5);
    mat.rotate(_t, -1.0, -1.0, 1.0);
    _pGLPrg->setUniformValue(_matUniform, mat);
    const GLfloat x0 = -1, x1 = 1, y0 = -1, y1 = 1, z0 = -1, z1 = 1;
    const GLfloat coords[] = {
    x0, y1, z1,
    x0, y0, z0,
    x0, y0, z1,
    x1, y0, z1,
    x0, y1, z1,
    x1, y1, z1,
    x1, y1, z0,
    x1, y0, z1,
    x1, y0, z0,
    x0, y0, z0,
    x1, y1, z0,
    x0, y1, z0,
    x0, y1, z1,
    x0, y0, z0
    };
    const GLfloat s0 = 0, s1 = 1.f / 5, s2 = 2.f / 5, s3 = 3.f / 5, s4 = 4.f / 5, s5 = 1;
    const GLfloat t0 = 0, t1 = 1.f / 5, t2 = 2.f / 5, t3 = 3.f / 5, t4 = 4.f / 5, t5 = 1;
    const GLfloat texCoords[] = {
    s0, t1,
    s1, t0,
    s1, t1,
    s2, t1,
    s1, t2,
    s2, t2,
    s2, t3,
    s3, t2,
    s3, t3,
    s4, t3,
    s3, t4,
    s4, t4,
    s4, t5,
    s5, t4
    };
    glVertexAttribPointer(_coordAttr, 3, GL_FLOAT, GL_FALSE, 0, coords);
    glVertexAttribPointer(_texCoordAttr, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 14);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);
    // done
    _pGLTex->release(); _pGLPrg->release();
    }

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    // setup GUI
    QMainWindow qMainWin;
    GLWidget glWidget;
    qMainWin.setCentralWidget(&glWidget);
    qMainWin.show();
    // runtime loop
    return app.exec();
    }

    输出:

    Snapshot of testQOpenGLTexCube

    关于c++ - 我可以纹理这个在 GL_TRIANGLE_STRIP 模式下渲染的立方体吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60537484/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com