2012-03-06 35 views
10

Tôi sẽ phát điên vì tôi không thể tạo một bộ tam giác đơn giản xuất hiện trên màn hình của mình.Hiển thị hình chữ nhật đơn giản với ngôn ngữ OpenGL 3 trong ngôn ngữ D

Tôi đang sử dụng OpenGL3 (không có đường ống cố định không được dùng nữa) bằng cách sử dụng các ràng buộc vô chủ cho ngôn ngữ lập trình D.

Bạn có thể phát hiện lỗi trong chương trình sau không? Nó biên dịch tốt và không ném bất kỳ lỗi OpenGL/GLSL nào. Nó chỉ cho thấy một màn hình trống với màu sắc rõ ràng tôi đặt.

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

Tôi không thể cho bạn biết chính xác vấn đề là gì, nhưng nó gần như chắc chắn sẽ giúp ích nếu bạn thực sự kiểm tra lỗi OpenGL bằng cách sử dụng glGetError(). Kiểm tra hàm thi hành trong std.exception và cách nó sử dụng tham số lười - bạn có thể điều chỉnh nó thành hàm 'enforceGL()' để làm cho dễ dàng hơn khi gặp lỗi OpenGL. –

+0

Tôi đã thực hiện một phiên bản của mã này, nơi tôi đã kiểm tra tất cả các cuộc gọi gl với một 'khẳng định (glGetError() == 0);' dòng ... Không có gì nêu ra một lỗi. –

+0

Tại sao bạn tải lại Derelict? : o –

Trả lời

13

On line này:

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

bạn có chắc rằng bạn muốn vertices.sizeof, trong đó có một giá trị của 16? Trong D, mảng động là cấu trúc có hai thành viên (ptrlength). Bạn có thể muốn hoặc là float.sizeof hoặc float.sizeof * 2.

Và cũng vậy với các cuộc gọi BufferData của bạn.

+0

Cảm ơn bạn đã trả lời! Tôi đã thay đổi khai báo để biến chúng thành các mảng tĩnh (tôi nghĩ khi chúng được định nghĩa với một chữ, chúng sẽ là tĩnh) và bây giờ .sizeof là 32 (length * float.sizeof) cho 'vertices' và 8 cho' index'. Nhưng tôi vẫn không nhận được gì. :( –

+0

Oh chờ đợi, bạn tuyệt vời.Tôi đã thay thế 'vertices.sizeof' bằng' vertices.length * float.sizeof' trong hàm glBufferData, giống với 'index'. Nhưng trong' glVertexAttribPointer' tôi cần '2 * float.sizeof' như tham số stride.Nó hoạt động !! Cảm ơn bạn –

+0

@SantiagoV Hey, tôi đã có thể sử dụng ví dụ của bạn để giúp tôi bắt đầu (không sử dụng sdl) Tôi biết điều này là cũ nhưng khi tôi đã làm nó , Tôi chỉ là một cửa sổ có màu ... giống như hình tam giác lớn hơn cửa sổ. Có ý tưởng nào về điều đó không? – AbstractDissonance

Các vấn đề liên quan