2013-07-23 61 views
3

對於那些看過我之前的問題的人,在完成RedBook for Version 2.1之後,我現在轉到4.3版。 (你說過,因爲你們很多人都告訴我這麼做很長時間了。)OpenGL編程協會第八版,示例程序和'NumVAO'

所以,我深入到第3章,但還沒有得到第1章的示例程序的工作。

我有兩個問題。 (其實3)首先,它不編譯。好吧,這是一個問題,但考慮到接下來的兩個問題,這是一個無關緊要的問題。其次,我不完全理解它是如何工作的或者它想要做什麼,但是我們會接受這一點。

第三,在我看來,這個代碼的作者是一個完整的魔術師。我會建議在這裏發生各種各樣的嘲弄。這很可能是因爲問題2,我不明白它想做什麼。寫這本書的人當然不是白癡,但是對我而言,我會舉一個例子。

這是從main.cpp文件頂部取得的代碼段落。我將包括文件的其餘部分以後,但現在:

enum VAO_IDs { 
    Triangles, 
    NumVAOs 
}; 

如果我沒有理解錯,這給VAO_IDs::Triangles1價值,因爲枚舉的是從零開始的。 (我希望我是正確的位置,或者這將是令人尷尬的我。)

過一會兒,你可以看到這行:

GLuint VAOs[NumVAOs]; 

它聲明的GLuint的數組,其中包含1 GLuint的歸因於NumVAO等於1.現在,首先,不應該是VAO_IDs::NumVAOs

其次,爲什麼在地球上這樣使用枚舉?我永遠不會使用這樣的枚舉出於顯而易見的原因 - 不能有多個具有相同值的數據,值沒有明確指定等...

我在這裏吠叫正確的樹嗎?這樣做是沒有意義的...... VAO應該是一個全球性的,像這樣,當然? GLuint NumVAOs = 1;這只是濫用枚舉!

事實上,下面的語句const GLuint NumVertices = 6;出現。這是有道理的,不是嗎,因爲如果我們想要,我們可以更改值6,但是我們不能將NumVOs更改爲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); 
} 

一個非常詳細的問題,我知道,但我想解釋爲什麼我認爲它瘋狂的代碼,而不是隻是說:「我不明白這一點」之類很容易是很重要的。有人能解釋爲什麼這些非常聰明的人決定這樣做,爲什麼會有錯誤。 (我在這裏沒有發現任何關於這個在線。)

+1

那些'enums'尖叫被重寫爲簡單的'#define'預處理語句。我同意你的看法,作者決定使用'enums'是令人迷惑的。 –

+1

枚舉的好處是,當你需要增加更多的值時,你不需要修改代碼的其他部分。 – yngccc

+0

@JesseCraig好吧我真的很高興聽到有人同意!任何想法在其他編譯錯誤?我至少檢查了兩次,我確信這本書是一個錯誤。 – user3728501

回答

2

作者正在使用自動編號屬性enums來自動更新NumVAOsNumBuffers值的定義。例如,當新的VAO ID添加到enum時,NumVAOs值將仍然正確,只要它在enum中最後列出。

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

很可能你的編譯器不支持這個技巧。

+0

嗯,這是既聰明又愚蠢的同時。我正在使用gcc/g ++版本4.6,或者如果需要,我可以使用版本4.8。當然gcc 4.6支持這個? – user3728501

+0

它是否適用於'VAO_IDs :: NumVAOs'語法?查看代碼,如果將'enum'值重新實現爲'const'或'#define'值,那麼什麼都不會改變。作者的選擇肯定會影響本書教授OpenGL的意圖。 –

+0

好吧,現在它正在工作,謝謝......至少它_compiles_。不鏈接,尚未...很多「未定義的參考」 – user3728501