2012-03-06 4 views
10

Je deviens fou parce que je ne peux pas faire apparaître un simple ensemble de triangles dans mon écran. J'utilise OpenGL3 (sans le pipeline fixe obsolète) en utilisant les liaisons abandonnées pour le langage de programmation D.Rendu d'un simple rectangle avec OpenGL 3 en langage D

Pouvez-vous repérer l'erreur dans le programme suivant? Il compile bien et ne lance aucune erreur OpenGL/GLSL. Il montre juste un écran vide avec la couleur claire que je définis.

import std.string; 
import std.conv; 
import derelict.opengl3.gl3; 
import derelict.sdl2.sdl2; 

immutable string minimalVertexShader = ` 
#version 120 
attribute vec2 position; 
void main(void) 
{ 
    gl_Position = vec4(position, 0, 1); 
} 
`; 

immutable string minimalFragmentShader = ` 
#version 120 
void main(void) 
{ 
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
} 
`; 

void main() { 
    DerelictSDL2.load(); 
    DerelictGL3.load(); 

    if (SDL_Init(SDL_INIT_VIDEO) < 0) { 
     throw new Exception("Failed to initialize SDL: " ~ to!string(SDL_GetError())); 
    } 

    // Set OpenGL version 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); 

    // Set OpenGL attributes 
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 

    auto sdlwindow = SDL_CreateWindow("D App", 
     SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
     640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 

    if (!sdlwindow) 
     throw new Exception("Failed to create a SDL window: " ~ to!string(SDL_GetError())); 

    SDL_GL_CreateContext(sdlwindow); 
    DerelictGL3.reload(); 

    float[] vertices = [ -1, -1, 1, -1, -1, 1, 1, 1]; 
    ushort[] indices = [0, 1, 2, 3]; 
    uint vbo, ibo; 
    // Create VBO 
    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, vertices.sizeof, vertices.ptr, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    // Create IBO 
    glGenBuffers(1, &ibo); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.sizeof, indices.ptr, GL_STATIC_DRAW); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

    // Program 
    auto program = glCreateProgram(); 
    // Vertex Shader 
    auto vsh = glCreateShader(GL_VERTEX_SHADER); 
    auto vshSrc = minimalVertexShader.toStringz; 
    glShaderSource(vsh, 1, &vshSrc, null); 
    glCompileShader(vsh); 
    glAttachShader(program, vsh); 
    // Fragment Shader 
    auto fsh = glCreateShader(GL_FRAGMENT_SHADER); 
    auto fshSrc = minimalFragmentShader.toStringz; 
    glShaderSource(fsh, 1, &fshSrc, null); 
    glCompileShader(fsh); 
    glAttachShader(program, fsh); 

    glLinkProgram(program); 
    glUseProgram(program); 

    auto position = glGetAttribLocation(program, "position"); 
    auto run = true; 

    while (run) { 
     SDL_Event event; 
     while (SDL_PollEvent(&event)) { 
      switch (event.type) { 
       case SDL_QUIT: 
        run = false; 
       default: 
        break; 
      } 
     } 

     glClearColor(1, 0.9, 0.8, 1); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glBindBuffer(GL_ARRAY_BUFFER, vbo); 
     glEnableVertexAttribArray(position); 
     glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, vertices.sizeof, null); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 
     glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, null); 
     glDisableVertexAttribArray(position); 

     SDL_GL_SwapWindow(sdlwindow); 
    } 
} 
+1

Je ne peux pas vous dire tout de suite quel est le problème, mais il sera presque certainement utile si vous vérifiez réellement les erreurs OpenGL en utilisant glGetError(). Vérifiez la fonction enforce dans std.exception et comment elle utilise un paramètre paresseux - vous pouvez l'adapter à une fonction 'enforceGL()' pour faciliter la détection des erreurs OpenGL. –

+0

J'ai fait une version de ce code où j'ai vérifié chaque appel gl avec une ligne 'assert (glGetError() == 0);' ... Rien n'a déclenché une erreur. –

+0

Pourquoi rechargez-vous Derelict? : o –

Répondre

13

Sur cette ligne:

glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, vertices.sizeof, null); 

Etes-vous sûr que vous voulez vertices.sizeof, qui a une valeur de 16? Dans D, un tableau dynamique est une structure à deux membres (ptr et length). Vous voulez probablement soit float.sizeof ou float.sizeof * 2.

Et il en va de même pour vos appels BufferData.

+0

Merci pour la réponse! J'ai changé la déclaration pour en faire des tableaux statiques (je pensais qu'ils étaient définis avec un littéral, ils seront statiques) et maintenant .sizeof est 32 (longueur * float.sizeof) pour 'vertices' et 8 pour' indices'. Mais je n'obtiens toujours rien. :( –

+0

Oh, attends, tu es génial, j'ai remplacé 'vertices.sizeof' par' vertices.length * float.sizeof' dans l'appel de glBufferData, pareil avec 'indices', mais dans' glVertexAttribPointer' j'avais besoin de '2 * float.sizeof' comme le paramètre stride Cela fonctionne !! Merci! –

+0

@SantiagoV Hey, j'ai été capable d'utiliser votre exemple pour m'aider à démarrer (sans utiliser sdl) Je sais que c'est vieux mais quand je l'ai fait , Juste une fenêtre qui était colorée ... comme si le triangle était plus grand que la fenêtre. – AbstractDissonance