2013-07-23 3 views
3

Redbook에서 버전 2.1로 작업 한 후에 이전 질문을 본 사람이라면, 이제 버전 4.3으로 넘어 가고 있습니다. (많은 사람들이 제게 몇 년 동안 이렇게 해왔다고 말했기 때문에 노골적으로 말했습니다.) 제 3 장에 깊이 들어 있지만 여전히 제 1 장의 예제 프로그램은 작동하지 않습니다.OpenGL 프로그래밍 길드 8 번째 에디션, 샘플 프로그램 및 'NumVAOs'

두 가지 문제점이 있습니다. (실제로 3). 첫째, 컴파일되지 않습니다. 좋습니다. 문제는 있지만 다음 두 가지를 고려할 때 무의미합니다. 둘째로, 나는 그것이 어떻게 작용하는지, 무엇을하려고 하는지를 정확히 이해하지 못한다. 그러나 우리는 그것에 대해 이해할 것이다.

셋째,이 코드의 작성자는 완전 마술사입니다. 나는 모든 종류의 팅커리 - 해커가 여기에서 발생하고 있다고 제안 할 것이다. 이것은 문제 번호 2로 인해 발생할 가능성이 가장 큽니다. 사실 문제가 무엇을 하려는지 이해하지 못하기 때문입니다. 이 책을 쓴 사람들은 물론 바보가 아니고, 나와 베어 낀 사람입니다.

여기는 main.cpp 파일의 맨 위에서 가져온 코드 섹션입니다. 나는,하지만 지금 나중에 파일의 나머지 부분을 포함합니다 : 열거의 기반 제로이기 때문에

enum VAO_IDs { 
    Triangles, 
    NumVAOs 
}; 

만약 내가 제대로 이해하고

이,이, VAO_IDs::Triangles 1의 값을 제공합니다. (나는 여기에 올바른입니다 희망, 또는 나를 위해 당황 할 것이다.) 잠시 후

,이 라인을 볼 수있다 : (1)를 포함

GLuint 년대의 배열을 선언
GLuint VAOs[NumVAOs]; 

, GLuint는 NumVAOs가 1과 같기 때문에 발생합니다. 이제, 먼저, VAO_IDs::NumVAOs일까요?

두 번째로, 지구상에 열거 형이이 방식으로 사용 된 이유는 무엇입니까? 나는 분명히 같은 열거 형을 사용하지 않을 것입니다 - 동일한 값을 갖는 하나 이상의 데이터를 가질 수없고, 값이 명시 적으로 지정되지 않습니다. ...

여기 오른쪽 나무를 짖고 있습니까? VAO가 글로벌 일 것임에 틀림 없어, 분명히? GLuint NumVAOs = 1; 이것은 열거 형에 다만 학대이다!

실제로 아래 진술 문 const GLuint NumVertices = 6;이 나타납니다. 원하는 경우 값 6을 변경할 수 있기 때문에 의미가 있지만 그렇지 않습니다. 예를 들어 NumVAO를 0으로 변경할 수는 없습니다. 삼각형은 이미 0으로 설정되어 있기 때문입니다. (열거 형에있는 이유는 무엇입니까?)

어쨌든 enum의 것을 잊어 버리십시오. 지금은 ... 좋아요. 그래서 나는 큰일을 만들어 냈습니다. 그게 문제의 끝입니다 ... 나는 지금 코드에있는 모든 의견을 갖고 있습니다. 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

을 저자는 자동으로 NumVAOsNumBuffers 값에 대한 정의를 업데이트 할 enums의 번호가 자동으로 속성을 사용하고 있습니다.예를 들어 enum에 새 VAO ID가 추가 된 경우 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