2012-03-06 19 views
10

Idę szalony, ponieważ nie mogę utworzyć prostego zestawu trójkątów na moim ekranie.Renderowanie prostego prostokąta z OpenGL 3 w języku D

Używam OpenGL3 (bez przestarzałego ustalonego potoku) przy użyciu porzuconych wiązań dla języka programowania D.

Czy możesz wykryć błąd w następującym programie? Kompiluje się dobrze i nie rzuca żadnego błędu OpenGL/GLSL. Po prostu pokazuje pusty ekran z ustawionym jasnym kolorem.

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

Nie mogę powiedzieć od razu, jaki jest problem, ale prawie na pewno pomoże, jeśli rzeczywiście sprawdzić błędy OpenGL za pomocą glGetError(). Sprawdź funkcję wymuszania w wyjątku std.exception i jak używa on leniwego parametru - możesz go dostosować do funkcji 'enforceGL()', aby ułatwić wychwytywanie błędów OpenGL. –

+0

Zrobiłem wersję tego kodu, gdzie sprawdzałem każde wywołanie gl z linią assert (glGetError() == 0); 'Nic nie spowodowało błędu. –

+0

Dlaczego przeładowujesz Derelict? : o –

Odpowiedz

13

Na tej linii:

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

jesteś pewien, że chcesz vertices.sizeof, który ma wartość 16? W D dynamiczna tablica to struktura z dwoma elementami (ptr i length). Prawdopodobnie chcesz albo float.sizeof lub float.sizeof * 2.

Podobnie jest w przypadku połączeń BufferData.

+0

Dzięki za odpowiedź! Zmieniłem deklarację, aby uczynić je statycznymi tablicami (myślałem, że zostały zdefiniowane z literałem, że będą statyczne), a teraz. Rozmiar wynosi 32 (długość * float.sizeof) dla 'wierzchołków' i 8 dla' indeksów'. Ale wciąż nie dostaję nic. :( –

+0

Och, czekaj, jesteś niesamowity.Zmieniłem 'vertices.sizeof' na' vertices.length * float.sizeof' w wywołaniu glBufferData, tak samo z 'indeksami' .Ale w' glVertexAttribPointer' potrzebowałem '2 * float.sizeof' jako parametr kroku.Odziękuje! Dziękujemy! –

+0

@Santiago V. Hej, udało mi się użyć twojego przykładu, aby pomóc mi zacząć (nie używając sdl) .Wiem, że to jest stare, ale kiedy to zrobiłem , Po prostu okno, które było kolorowe ... jakby trójkąt był znacznie większy od okna. Masz jakieś pomysły na ten temat? – AbstractDissonance

Powiązane problemy