2012-03-06 7 views
10

Я сойду с ума, потому что не могу сделать простой набор треугольников, появляющихся на моем экране.Оказание простого прямоугольника с OpenGL 3 в языке D

Я использую OpenGL3 (без устаревшего фиксированного конвейера), используя заброшенные привязки для языка программирования D.

Вы можете обнаружить ошибку в следующей программе? Он компилируется просто отлично и не вызывает никакой ошибки OpenGL/GLSL. Он просто показывает пустой экран с четким цветом, который я установил.

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

Я не могу сразу сказать вам, в чем проблема, но это почти наверняка поможет, если вы действительно проверяете ошибки OpenGL с помощью glGetError(). Проверьте функцию принудительного выполнения в std.exception и как он использует ленивый параметр - вы можете адаптировать его к функции 'enforceGL()', чтобы облегчить обнаружение ошибок OpenGL. –

+0

Я сделал версию этого кода, где я проверил каждый вызов gl с помощью строки 'assert (glGetError() == 0);' ... Ничего не вызвало ошибку. –

+0

Почему вы перезагружаете Derelict? : o –

ответ

13

На этой линии:

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

вы уверены, что вы хотите vertices.sizeof, который имеет значение 16? В D динамический массив представляет собой структуру с двумя членами (ptr и length). Вероятно, вы хотите либо float.sizeof, либо float.sizeof * 2.

И то же самое касается ваших звонков BufferData.

+0

Спасибо за ответ! Я изменил объявление, чтобы сделать их статичными массивами (я думал, как они были определены с литералом, они будут статическими), а теперь .sizeof равно 32 (length * float.sizeof) для 'vertices' и 8 для' индексов'. Но все же я ничего не получаю. :( –

+0

Ой, подождите, вы классный. Я заменил 'vertices.sizeof' на' vertices.length * float.sizeof' в вызове glBufferData, то же самое с 'indices'. Но в' glVertexAttribPointer' мне понадобилось '2 * float.sizeof' как параметр шага.Он работает !! Спасибо! –

+0

@SantiagoV Эй, я смог использовать ваш пример, чтобы помочь мне начать (не используя sdl). Я знаю, что это старый, но когда я это сделал , Я просто окно, которое было окрашено ... как будто треугольник был больше, чем окно. Есть идеи по этому поводу? – AbstractDissonance