2016-03-31 15 views
1

döner, ben GLFW, Glew kullanarak (hem here ve here türetilmiş) temel kod çalıştıran bazı sıkıntılar içine çalıştırmak ve OpenGL ettik .OpenGL + GLFW glGenVertexArrays (temelde 3.2+) "modern" OpenGL kullanarak taşınmak çalışırken GL_INVALID_OPERATION

#define GLEW_STATIC 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 
#include <stdlib.h> 
#include <stdio.h> 

const GLchar* vertexSource = 
    "#version 150 core\n" 
    "in vec2 position;" 
    "void main()" 
    "{" 
    " gl_Position = vec4(position, 0.0, 1.0);" 
    "}"; 
const GLchar* fragmentSource = 
    "#version 150 core\n" 
    "out vec4 outColor;" 
    "void main()" 
    "{" 
    " outColor = vec4(1.0, 1.0, 1.0, 1.0);" 
    "}"; 

void checkErr(const char* msg) { 
    GLenum err = glGetError(); 

    if (err != 0) { 
     printf("@ \"%s\": %d\n", msg, err); 
     exit(EXIT_FAILURE); 
    } else { 
     printf("@ \"%s\": successful\n", msg); 
    } 
} 

int main(int argc, char* argv[]) { 
    GLFWwindow* window; 

    // Initialize GLFW 
    if (!glfwInit()) 
     return -1; 

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

    // Create a windowed mode window and its OpenGL context 
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); 
    if (!window) 
    { 
     glfwTerminate(); 
     return -1; 
    } 

    // Make the window's context current 
    glfwMakeContextCurrent(window); 

    // Initialize GLEW 
    glewExperimental = GL_TRUE; 
    glewInit(); 

    // get version info 
    const GLubyte* renderer = glGetString(GL_RENDERER); 
    const GLubyte* version = glGetString(GL_VERSION); 
    const GLubyte* glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); 
    printf ("Renderer:  %s\n", renderer); 
    printf ("OpenGL version: %s\n", version); 
    printf ("GLSL version: %s\n", glslVersion); 

    // Create Vertex Array Object 
    GLuint vao; 
    glGenVertexArrays(1, &vao); 
    checkErr("Gen VAO"); 
    glBindVertexArray(vao); 
    checkErr("Bind VAO"); 

    // Create a Vertex Buffer Object and copy the vertex data to it 
    GLuint vbo; 
    glGenBuffers(1, &vbo); 
    checkErr("Gen VBO"); 

    GLfloat vertices[] = { 
     0.0f, 0.5f, 
     0.5f, -0.5f, 
     -0.5f, -0.5f 
    }; 

    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    checkErr("Bind VBO"); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    checkErr("VBO data"); 

    // Create and compile the vertex shader 
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexSource, NULL); 
    glCompileShader(vertexShader); 
    checkErr("Compile vert shader"); 

    // Create and compile the fragment shader 
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL); 
    glCompileShader(fragmentShader); 
    checkErr("Compile frag shader"); 

    // Link the vertex and fragment shader into a shader program 
    GLuint shaderProgram = glCreateProgram(); 
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader); 
    glBindFragDataLocation(shaderProgram, 0, "outColor"); 
    glLinkProgram(shaderProgram); 
    checkErr("Link program"); 
    glUseProgram(shaderProgram); 
    checkErr("Use program"); 

    // Specify the layout of the vertex data 
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); 
    glEnableVertexAttribArray(posAttrib); 
    checkErr("Enable vertex attrib"); 
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); 
    checkErr("Describe vert data"); 

    // Loop until the user closes the window 
    while (!glfwWindowShouldClose(window)) 
    { 
     /* Render here */ 
     glClearColor(0.0, 0.0, 0.0, 1.0); 
     glClear(GL_COLOR_BUFFER_BIT); 
     glDrawArrays(GL_TRIANGLES, 0, 3); 

     /* Swap front and back buffers */ 
     glfwSwapBuffers(window); 

     /* Poll for and process events */ 
     glfwPollEvents(); 
    } 

    glfwTerminate(); 
    exit(EXIT_SUCCESS); 
} 

hemen köşe dizisi nesnesi kurma ilk adım GL_INVALID_OPERATION hataları içine çalıştırıyorum:

Benim ilk sorun aşağıdaki kodla olmasıdır.

OS X'in açgözlü OpenGL desteğiyle ilgili epeyce araştırma yaptım, ancak şu ana kadar bu kodda değiştirdiğim şeylerin çoğu daha fazla bir şey yapmadı, ancak tamamen siyah bir ekran oluşturdu (yani checkError yardımcı işlevinin kilitlenme davranışını kaldırdı).

Başvuru için

, ben bir erken 2015 MacBook Pro, w/Retina, OS X v10.11.3 üzerinde çalıştırıyorum ve benim yukarıdaki program listelerinden sürüm bilgi çıktısı aşağıdaki gibi:

Renderer:  Intel(R) Iris(TM) Graphics 6100 
OpenGL version: 4.1 INTEL-10.12.13 
GLSL version: 4.10 

Herhangi yardım büyük beğeni topluyor!

cevap

3

Sadece numaralı ifadenin kabul ettiğinden hatamızın hata oluşturdugu glGenVertexArrays. Ama durum böyle değil. glewInit tarafından üretilmiştir. Ve bunun nedeni GLEW'nin temel profil opengl'de kırılmasıdır: çekirdek prodillerinde mevcut olmayan ve GL_INVALID_ENUM hatası (1280) üreten uzantı dizesini sorgulamak için glGetString(GL_EXTENSIONS) kullanır.

Normalde glewInit sonra dönüş kodu GL_FALSE duracaktır. Ancak, glewExperimental=GL_TRUE'un "geçici çözümü", devam etmesini, hatayı yok saymayı ve tüm uzantı işaretleyicilerini sorgulamayı yine de yapacaktır. Bu artık en az 3 farklı açısından ayrılır:

  1. Tüm GLEW değişkenleri belirli uzantıları avialibility sorgulamak için uzantısı kullanılabilir olduğunda bile return false.
  2. Uygulama tarafından kullanılabilirliği bildirilmeyen uzantı işlevleri için işlev göstergelerini alır. Bu işaretçilerin NULL olması garanti edilmez, ancak bunları çağırmak tanımlanmamış bir davranış olacaktır. 1 ile birlikte, bu, herhangi bir uzantının kullanılabilirliğini kontrol etmenin hiçbir yolunun olmadığı anlamına gelir. Glew'in sizin için yapabilecekleri şeyleri elle yapmak haricinde.
  3. GL içeriğini bir hata durumunda bırakacaktır.

hızlı & kirli hack olarak, sadece uzak hatayı okumak için glGetError() hakkı glewInit sonra ekleyebilir. Bunu yaptıktan sonra, kodunuz benim uygulamamda beklenen beyaz üçgeni oluşturdu (NVIDIA/Linux).

daha iyi bir düzeltme doğru, örneğin glad için, çekirdek profiller ile çalışır bir GL yükleyici üzerinden geçmek için muhtemelen. Geçiş gerçekten çok zor olmayacaktır, sadece init işlevinin değiştirilmesi gerektiğinden. memnun bir yükleyici kütüphane olmadığını unutmayın, ancak başka bir kütüphane bağlamanız gerekir, ama sadece projenize başka kaynak dosyasını eklemek zorunda kalmamak, bir yükleyici source ihtiyaçlarınız için dosyası oluşturur bir Python komut.

+0

Yardım için teşekkürler @derhass, aslında başka bir yerde GLEW kullanmıyorum, bu yüzden sadece GLEW'i kaldırmak sadece üçgeni üretmek için çalıştı! Kesinlikle daha önce memnun oldum, ama GLFW, GLEW, vb. Ile karşılaştırıldığında ne ek bir değer kattığını tam olarak anlayamadım. Ama eminim şimdi bir bakacağım. – jerluc

+1

OSX üzerindeyseniz, OpenGL'nin temel işlevlerine erişmek için bir gl yükleyici kesinlikle gerekli değildir. Bununla birlikte, eğer protable kod yazmayı planlıyorsanız, bunu bu şekilde yapamazsınız. GL yükleyicilerinin neler olduğunu öğrenmek için [this] (https://www.opengl.org/wiki/Load_OpenGL_Functions) ve [this] (https://www.opengl.org/wiki/OpenGL_Loading_Library) OpenGL wiki makalesine bir göz atın. hakkında. – derhass