Я читаю красную книгу OpenGl, и я почти застрял в первом учебнике. Все работает нормально, если я использую freeglut и glew, но я бы хотел обработать ввод и сам. Таким образом я бросил freeglut и glew и написал свой собственный код. Я просмотрел некоторые другие уроки и закончил код, но ничего не отображается. Кажется, что FreeGlut делает магию вуду в фоновом режиме, но я не знаю, чего мне не хватает. Я пробовал это:
int attributeListInt[19];
int pixelFormat[1];
unsigned int formatCount;
int result;
PIXELFORMATDESCRIPTOR pixelFormatDescriptor;
int attributeList[5];
context = GetDC (hwnd);
if (!context)
return -1;
attributeListInt[0] = WGL_SUPPORT_OPENGL_ARB;
attributeListInt[1] = TRUE;
attributeListInt[2] = WGL_DRAW_TO_WINDOW_ARB;
attributeListInt[3] = TRUE;
attributeListInt[4] = WGL_ACCELERATION_ARB;
attributeListInt[5] = WGL_FULL_ACCELERATION_ARB;
attributeListInt[6] = WGL_COLOR_BITS_ARB;
attributeListInt[7] = 24;
attributeListInt[8] = WGL_DEPTH_BITS_ARB;
attributeListInt[9] = 24;
attributeListInt[10] = WGL_DOUBLE_BUFFER_ARB;
attributeListInt[11] = TRUE;
attributeListInt[12] = WGL_SWAP_METHOD_ARB;
attributeListInt[13] = WGL_SWAP_EXCHANGE_ARB;
attributeListInt[14] = WGL_PIXEL_TYPE_ARB;
attributeListInt[15] = WGL_TYPE_RGBA_ARB;
attributeListInt[16] = WGL_STENCIL_BITS_ARB;
attributeListInt[17] = 8;
attributeListInt[18] = 0;
result = wglChoosePixelFormatARB (context, attributeListInt, NULL, 1, pixelFormat, &formatCount);
if (result != 1)
return -1;
result = SetPixelFormat (context, pixelFormat[0], &pixelFormatDescriptor);
if (result != 1)
return -1;
attributeList[0] = WGL_CONTEXT_MAJOR_VERSION_ARB;
attributeList[1] = 4;
attributeList[2] = WGL_CONTEXT_MINOR_VERSION_ARB;
attributeList[3] = 2;
attributeList[4] = 0;
rendercontext = wglCreateContextAttribsARB (context, 0, attributeList);
if (rendercontext == NULL)
return -1;
result = wglMakeCurrent (context, rendercontext);
if (result != 1)
return -1;
glClearDepth (1.0f);
glFrontFace (GL_CCW);
glEnable (GL_CULL_FACE);
glCullFace (GL_BACK);
return 0;
Это создает графический контекст, но, по-видимому, этого недостаточно, чтобы все работало. В учебнике не было ничего о матрицах представлений или проекций, поэтому я не уверен, что я должен добавить что-нибудь подобное. Но окно остается черным.
Это код учебника, скорректированный на мой код:
#define BUFFER_OFFSET(offset) ((void *)(offset))
bool init ();
bool mainloop ();
enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices = 6;
int main (int argc, char** argv)
{
Window w;
w.init (&mainloop);
if (!init ())
return 0;
w.run ();
w.shutdown ();
return 0;
}
bool init ()
{
glGenVertexArrays (NumVAOs, VAOs);
glBindVertexArray (VAOs[Triangles]);
GLfloat vertices[NumVertices][2] = {
{-0.90f, -0.90f}, // Triangle 1
{0.85f, -0.90f},
{-0.90f, 0.85f},
{0.90f, -0.85f}, // Triangle 2
{0.90f, 0.90f},
{-0.85f, 0.90f}
};
glGenBuffers (NumBuffers, Buffers);
glBindBuffer (GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
glBufferData (GL_ARRAY_BUFFER, sizeof(vertices),
vertices, GL_STATIC_DRAW);
ShaderInfo shaders[] = {
{GL_VERTEX_SHADER, "triangles.vert"},
{GL_FRAGMENT_SHADER, "triangles.frag"},
{GL_NONE, NULL}
};
GLuint program = LoadShaders (shaders);
glUseProgram (program);
glVertexAttribPointer (vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET (0));
glEnableVertexAttribArray (vPosition);
return true;
}
bool mainloop ()
{
glClear (GL_COLOR_BUFFER_BIT);
glBindVertexArray (VAOs[Triangles]);
glDrawArrays (GL_TRIANGLES, 0, NumVertices);
glFlush ();
return true;
}
Создание контекста OpenGL не является тривиальным. Особенно, если вы хотите использовать wglChoosePixelFormatARB
который должен быть загружен через механизм расширения OpenGL..., который требует, чтобы работающий контекст OpenGL работал в первую очередь. Я думаю, вы видите, что это своего рода проблема с курицей и яйцом. Кроме того, Окно, которое вы используете для создания контекста OpenGL, требует определенных функций для надежной работы. Для одного WndClass должен иметь набор CS_OWNDC, а стиль окна должен включать WS_CLIPSIBLINGS | WS_CLIPCHILDREN
WS_CLIPSIBLINGS | WS_CLIPCHILDREN
Недавно я подошел к вышеупомянутой проблемы курицы и яйца с моими маленькими wglarb
подручными инструментами: https://github.com/datenwolf/wglarb
Он также поставляется с небольшой тестовой программой, которая показывает, как ее использовать.
Я предлагаю вам использовать функции, предоставляемые этим. Я написал эту небольшую вспомогательную библиотеку таким образом, что на нее не оказывают негативного влияния, если ваша программа использует другие механизмы загрузки добавок. Однако он еще не потокобезопасен; В конце концов, я должен добавить это. Я потратил время, чтобы сделать поток кода безопасным. Теперь вы можете использовать открытые функции, не заботясь о синхронизации; все это сделано внутренне надежным способом.