2012-03-26 101 views
1

我試圖讓一個簡單的VBO運行。但是,當我打電話VBO + glBufferData當尺寸太高時崩潰

glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*vertexcount, vertices, GL_STATIC_DRAW); 

它只是崩潰,但只有當vertexcount是在1531年是的,在「頂點」數組存儲,或者說沒有分配,更多的則1531元足夠的空間。 這是我的頂點結構:

typedef struct{ 
    float x, y, z; 
    float nx, ny, nz; 
    float u, v; 
}Vertex, vertex; 

所以它應該是32個字節。 32字節* 1531 = 48992字節= 48kb。

但是對於一個正常的VBO,48kb看起來似乎不太高?我不明白髮生了什麼事。

編輯:

的Windows XP 32位Service Pack 3的

的Nvidia GeForce 9800GT 1024MB

EDIT2:我的完整代碼的 短版本: (有趣的部分是在底部)

#include <windows.h> 
#include <glew.h> 
#include <wglew.h> 
#include <gl3.h> 
#include <gl/glu.h> 
#define BUFFER_OFFSET(i) ((char *)NULL + (i)) 

typedef struct{ 
    float x, y, z; 
float nx, ny, nz; 
float u, v; 
}Vertex, vertex; 

typedef struct{ 
    int first, second, third; 
}VertexIndex, vertexindex, vindex, Vindex; 

typedef struct{ 
    unsigned int vao; 
    unsigned int vertexcount, indexcount; 
}Mesh, mesh; 

typedef struct{ 
    HWND hwnd; 
    HDC hdc; 
    HGLRC hrc; 
}GLWindow, Window, window; 

void WindowShenanigans(Window *w, HINSTANCE *hinstance, WNDPROC WindowProc) 
{ 
    HWND tmp_hwnd; 
    WNDCLASS wndclass; 

    ZeroMemory(&wndclass, sizeof(WNDCLASS)); 
    wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_GLOBALCLASS; 
    wndclass.cbClsExtra = 0;  
    wndclass.cbWndExtra = 0; 
    wndclass.lpszMenuName = 0; 
    wndclass.hIcon = 0; 
    wndclass.hInstance = *hinstance; 
    wndclass.lpszClassName = "glclass"; 
    wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); 
    wndclass.hCursor = LoadCursor(0, IDC_ARROW); 
    wndclass.lpfnWndProc = WindowProc; 

    if(RegisterClass(&wndclass) == 0) 
    { 
     return; 
    } 

    ShowCursor(TRUE); 

    tmp_hwnd = CreateWindowA ("glclass", 
          "bla", 
          WS_BORDER | WS_CAPTION | WS_SYSMENU, 
          0, 0, 
          600, 
          800, 
          HWND_DESKTOP, 
          NULL, 
          hinstance, 
          NULL); 

    w->hwnd = tmp_hwnd; 

    unsigned int PixelFormat; 
    PIXELFORMATDESCRIPTOR pfd; 

    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 
    pfd.nVersion = 1; 
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 
    pfd.iPixelType = PFD_TYPE_RGBA; 
    pfd.cColorBits = 32; 
    pfd.cDepthBits = 16; 
    pfd.cStencilBits = 32; 
    pfd.iLayerType = PFD_MAIN_PLANE; 

    w->hdc = GetDC(w->hwnd); 

    PixelFormat = ChoosePixelFormat(w->hdc, &pfd); 
    SetPixelFormat(w->hdc, PixelFormat, &pfd); 

    int attrib[] = 
    { 
      WGL_CONTEXT_MAJOR_VERSION_ARB, 3, 
      WGL_CONTEXT_MINOR_VERSION_ARB, 2, 
      WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 
      0 
    }; //OpenGL Context 

    HGLRC tmphrc = wglCreateContext(w->hdc); 

    wglMakeCurrent (w->hdc, tmphrc); 

    PFNWGLCREATEBUFFERREGIONARBPROC wglCreateContextAttribsARB =  (PFNWGLCREATEBUFFERREGIONARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); 
    w->hrc = (HGLRC)wglCreateContextAttribsARB(w->hdc, 0, (UINT)attrib) ; 

    ShowWindow(w->hwnd, SW_SHOW); 
    UpdateWindow(w->hwnd); 
} 

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 
{ 
    switch(msg) 
    { 
     case WM_DESTROY: 
     { 
      PostQuitMessage(0); 
      return 0; 
     } 
     case WM_CLOSE: 
     { 
      PostQuitMessage(0); 
      return 0; 
     } 
     case WM_CREATE: 
     { 
     } 
     break; 
     case WM_SIZE: 
     { 
     } 
     break; 

     case WM_PAINT: 
     { 
     } 
     break; 
    } 
    return DefWindowProc(hwnd, msg, wparam, lparam); 
} 

BOOL ProcessMessage(MSG *msg) 
{ 
    if(GetMessage(msg, NULL, 0, 0) != 0) 
    { 
     TranslateMessage(msg); 
     DispatchMessage(msg); 
     return TRUE; 
    } 
    else 
    { 
     return FALSE; 
    } 
} 

/////////////////////////////////////////////////////////////////////////////////////////// 
void DataUpload(Mesh *m, Vindex *indices, Vertex *vertices) 
{ 
    unsigned int vbo, index_vbo; 

    glGenVertexArrays(1, &m->vao); 
    glBindVertexArray(m->vao); 

    glGenBuffers(1, &index_vbo); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*3500, indices, GL_STATIC_DRAW); 

    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    // MessageBox(HWND_DESKTOP, "3..2..1..", "", MB_OK); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*3500, vertices, GL_STATIC_DRAW); 
    // MessageBox(HWND_DESKTOP, "YEA", "", MB_OK); 

    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0)); 
    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float)*3)); 
    glEnableVertexAttribArray(2); 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(float)*6)); 
    glBindVertexArray(0); 
} 

void MeshGenerate(Mesh *m, float x, float y, float z) 
{ 
     int i; 
     Vertex *vertices; 
     Vindex *indices; 
     m->vertexcount = 3500; 
     m->indexcount = 3500; 
     vertices = malloc(3500*sizeof(vertex)); 
     indices = malloc(3500*sizeof(vindex)); 

     for(i = 0; i<3500; i++) 
     { 
      vertices[i].x = 1.0f; 
      vertices[i].y = 1.0f; 
      vertices[i].z = 1.0f; 
      vertices[i].nx = 1.0f; 
      vertices[i].ny = 1.0f; 
      vertices[i].nz = 1.0f; 
      vertices[i].u = 1.0f; 
      vertices[i].v = 1.0f; 
     } 
     for(i = 0; i<3500; i++) 
     { 
      indices[i].first = 1; 
      indices[i].second = 1; 
      indices[i].third = 1; 
     } 
     DataUpload(m, vertices, indices); 
     return; 
} 

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd) 
{ 
    MSG msg; 
    BOOL isActive = 1; 
    window w; 
    WindowShenanigans(&w, &hinstance, WindowProc); 

    glewInit(); 

    Mesh m; 
    MeshGenerate(&m, 1.0f, 1.0f, 1.0f); 

    while(isActive == 1) 
    { 
     SwapBuffers(w.hdc); 
     isActive = ProcessMessage(&msg); 
    } 

    return msg.wParam; 
} 
//////////////////////////////////////////////////////////////////////////////// 
+0

難道僅僅是一個良好的老段錯誤? – vmpstr 2012-03-26 15:38:05

+2

發佈[SSCCE](http://sscce.org/)。 – genpfault 2012-03-26 15:57:09

+0

看看mallocing相同的內存有幫助嗎? – 2012-03-26 15:58:09

回答

2
ogl.c: In function `MeshGenerate': 

ogl.c:200:warning:通過參數DataUpload' from incompatible pointer type ogl.c:200: warning: passing arg 3 of的數據上傳'不兼容的指針類型

我沒有安裝glew,所以我無法獲得正確的工作示例。但這絕對是一個問題。

DataUpload(m, vertices, indices); 

應該

DataUpload(m, indices, vertices); 
+0

是的,我沒有注意到<_ <。現在工作正常 – user1290204 2012-03-26 18:14:01