3

バージョン 2.1 の RedBook に取り組んだ後、私の以前の質問を見た人は誰でも、バージョン 4.3 に移行しています。(あなた方の多くが私にこれを行うように何年もの間言ってきたので、あなたは言います。)

ですから、私は第 3 章に深く入っていますが、第 1 章のサンプル プログラムはまだ機能していません。

2 つの問題があります。(実際には 3.) まず、コンパイルされません。それは問題ですが、次の 2 つを考えると、ちょっと関係ありません。第二に、それがどのように機能するか、または何をしようとしているのか正確にはわかりませんが、それについて説明します.

第三に、このコードの作成者は完全な魔術師であるように私には思えます。ここでは、あらゆる種類のいじくりハッキングが行われていることを示唆しています。これは、問題番号 2 が原因である可能性が最も高く、それが何をしようとしているのかわからないという事実です。もちろん、この本を書いた人たちはばかではありませんが、私に我慢して、例を挙げます。

ファイルの先頭から抜粋したコードのセクションを次に示しmain.cppます。ファイルの残りの部分は後で含めますが、今のところは次のとおりです。

enum VAO_IDs {
    Triangles,
    NumVAOs
};

私が正しく理解していれば、列挙型はゼロベースであるため、これによりVAO_IDs::Trianglesの値が得られます。1(ここで私が正しいことを願っています。そうしないと、恥ずかしい思いをすることになります。)

しばらくすると、次の行が表示されます。

GLuint VAOs[NumVAOs];

GLuintNumVAOs が 1 に等しいという事実により、1 つの Gluint を含む の配列を宣言しVAO_IDs::NumVAOsます。

そして第二に、一体なぜ列挙型がこのように使用されたのでしょうか? 明らかな理由で、そのような列挙型を使用することはありません-同じ値を持つ複数のデータを持つことはできません、値は明示的に指定されていません...

ここで正しい木を吠えていますか?これを行うのは意味がありません.VAOは、このようにグローバルであるべきでしたね。GLuint NumVAOs = 1;これは、列挙型を乱用するだけです!

実際、ステートメントの下に表示されconst GLuint NumVertices = 6;ます。必要に応じて値 6 を変更することはできますが、NumVAOs を 0 に変更することはできません。たとえば、Triangles は既に 0 に設定されているためです。

とにかく、列挙型のことは忘れてください...今のところ...わかりましたので、それで大したことをしました。それで問題は終わりです...これ以上のコメントは今コードにあります。glfw のほとんどは無視できます。本質的には glut と同じです。

// ----------------------------------------------------------------------------
//
// Triangles - First OpenGL 4.3 Program
//
// ----------------------------------------------------------------------------

#include <cstdlib>
#include <cstdint>
#include <cmath>

#include <stdio.h>
#include <iostream>

//#include <GL/gl.h>
//#include <GL/glu.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>


/// OpenGL specific
#include "vgl.h"
#include "LoadShaders.h" // These are essentially empty files with some background work going on, nothing declared or defined which is relevant here

enum VAO_IDs {
    Triangles,
    NumVAOs
};
// So Triangles = 0, NumVAOs = 1
// WHY DO THIS?!

enum Buffer_IDs {
    ArrayBuffer,
    NumBuffers
};

enum Attrib_IDs {
    vPosition = 0
}
// Please, please, please someone explain the enum thing to me, why are they using them instead of global -just- variables.
// (Yeah an enum is a variable, okay, but you know what I mean.)

GLuint VAOs[NumVAOs]; // Compile error: expected initializer before 'VAOs'
GLuint Buffers[NumBuffers]; // NumBuffers is hidden in an enum again, so it NumVAOs

const GLuint NumVertices = 6; // Why do something different here?

// ----------------------------------------------------------------------------
//
// Init
//
// ----------------------------------------------------------------------------

void init()
{
    glGenVertexArrays(NumVAOs, VAOs); // Error: VAOs was not declared in this scope
    glBindVertexArray(VAOs[Triangles]);

    GLfloat vertices[NumVertices][2] = {
        { -0.90, -0.90 },
        { +0.85, -0.90 },
        { -0.90, +0.85 },
        { +0.90, -0.85 },
        { +0.90, +0.90 },
        { -0.85, +0.90 }
    };

    glGenBuffers(NumBuffers, Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    ShaderInfo shaders[] = {
        { GL_VERTEX_SHADER, "triangles.vert" },
        { GL_FRAGMENT_SHADER, "triangles.frag" },
        { GL_NONE, nullptr }
    };

    GLuint program = LoadShaders(shaders);
    glUseProgram(program);

    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(vPosition);
}

// ----------------------------------------------------------------------------
//
// Display
//
// ----------------------------------------------------------------------------

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArray(VAOs[Triangles]);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices); // Error VAOs not declared

    glFlush();
}

// ----------------------------------------------------------------------------
//
// Main
//
// ----------------------------------------------------------------------------

void error_handle(int error, const char* description)
{
    fputs(description, stderr);
}

void key_handle(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);

}


void handle_exit()
{

}


int main(int argc, char **argv)
{

    // Setup exit function
    atexit(handle_exit);


    // GLFW Window Pointer
    GLFWwindow* window;


    // Setup error callback
    glfwSetErrorCallback(error_handle);


    // Init
    if(!glfwInit())
    {
        exit(EXIT_FAILURE);
    }


    // Setup OpenGL
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);


    // Set GLFW window hints
    glfwWindowHint(GLFW_DEPTH_BITS, 32);
    glfwWindowHint(GLFW_RED_BITS, 8);
    glfwWindowHint(GLFW_GREEN_BITS, 8);
    glfwWindowHint(GLFW_BLUE_BITS, 8);
    glfwWindowHint(GLFW_ALPHA_BITS, 8);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);


    // Init GLEW
    if(glewInit())
    {
        printf("GLEW init failure!\n", stderr);
        exit(EXIT_FAILURE);
    }


    // Init OpenGL
    init();


    // Create Window
    window = glfwCreateWindow(800, 600, "Window Title", nullptr, nullptr);
    if(!window)
    {
        glfwTerminate();
        return EXIT_FAILURE;
    }

    // Make current
    glfwMakeContextCurrent(window);


    // Set key callback
    glfwSetKeyCallback(window, key_handle);


    // Check OpenGL Version
    char* version;
    version = (char*)glGetString(GL_VERSION);
    printf("OpenGL Application Running, Version: %s\n", version);


    // Enter main loop
    while(!glfwWindowShouldClose(window))
    {
        // Event polling
        glfwPollEvents();

        // OpenGL Rendering

        // Setup OpenGL viewport and clear screen
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / height;

        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Setup projection
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(45.0, ratio, 0.1, 10.0);

        // Render
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        // Swap Buffers
        glfwSwapBuffers(window);
    }


    // Free glfw memory allocated for window
    glfwDestroyWindow(window);


    // Exit
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

非常に冗長な質問だと思いますが、簡単に「わからない」と言うのではなく、クレイジーなコードだと思う理由を説明することが重要だと思いました。これらの非常に賢い人々がなぜこのようにすることに決めたのか、なぜエラーがあるのか​​ を誰か説明してもらえますか. (私はこれについてオンラインで何も見つけることができません。)

4

1 に答える 1

2

作成者は の自動番号付けプロパティを使用して、との値enumsの定義を自動的に更新しています。たとえば、新しい VAO ID が に追加された場合でも、 の最後にリストされている限り、値は正しいままです。NumVAOsNumBuffersenumNumVAOsenum

enum VAO_IDs {
    Triangles,
    Polygons,
    Circles,
    NumVAOs
};

ほとんどの場合、コンパイラはこのトリックをサポートしていません。

于 2013-07-23T00:57:08.357 に答える