2012-03-06 17 views
10

Me estoy volviendo loco porque no puedo hacer que un simple conjunto de triángulos aparezca en mi pantalla.Renderizar un rectángulo simple con OpenGL 3 en el lenguaje D

Estoy usando OpenGL3 (sin la tubería fija desaprobada) usando los enlaces abandonados para el lenguaje de programación D.

¿Puede detectar el error en el siguiente programa? Se compila muy bien y no arroja ningún error OpenGL/GLSL. Simplemente muestra una pantalla en blanco con el color claro que configuré.

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

No puedo decirte cuál es el problema, pero seguramente será de gran ayuda si realmente compruebas si hay errores OpenGL al usar glGetError(). Consulte la función de imposición en std.exception y cómo utiliza un parámetro diferido: puede adaptarlo a una función 'enforceGL()' para que sea más fácil detectar los errores de OpenGL. –

+0

Hice una versión de este código donde comprobé cada llamada gl con una línea 'assert (glGetError() == 0);' ... Nada provocó un error. –

+0

¿Por qué estás recargando Abandonado? : o –

Respuesta

13

En esta línea:

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

¿Estas seguro que quieres vertices.sizeof, que tiene un valor de 16? En D, una matriz dinámica es una estructura con dos miembros (ptr y length). Probablemente desee float.sizeof o float.sizeof * 2.

Y lo mismo vale para sus llamadas BufferData.

+0

¡Gracias por la respuesta! Cambié la declaración para convertirlas en matrices estáticas (pensé que como estaban definidas con un literal, serían estáticas) y ahora .sizeof es 32 (longitud * float.sizeof) para 'vertices' y 8 para' indices'. Pero aún no me dibuja nada. :( –

+0

Oh espera, eres increíble. Reemplacé 'vertices.sizeof' con' vertices.length * float.sizeof' en la llamada glBufferData, lo mismo con 'indices'. Pero en' glVertexAttribPointer' necesitaba '2 * float.sizeof' como el parámetro de zancada. ¡Funciona! ¡Gracias! –

+0

@SantiagoV. Oye, pude utilizar tu ejemplo para ayudarme a comenzar (sin usar sdl). Sé que esto es antiguo, pero cuando lo hice , Solo una ventana que estaba coloreada ... como si el triángulo fuera mucho más grande que la ventana. ¿Tienes alguna idea al respecto? – AbstractDissonance

Cuestiones relacionadas