简体   繁体   English

创建一个基本的OpenGl上下文

[英]Creating a basic OpenGl context

I'm reading the OpenGl red book, and I'm pretty much stuck at the first tutorial. 我正在阅读OpenGl红皮书,而我几乎陷入了第一个教程的困境。 Everything works fine if I use freeglut and glew, but I'd like to handle input and such myself. 如果我使用freeglut和glew,一切都会正常,但是我想自己处理输入。 So I ditched freeglut and glew and wrote my own code. 因此,我放弃了freeglut,并开始编写自己的代码。 I've looked at some other tutorials and finished the code, but nothing is displayed. 我看了其他一些教程并完成了代码,但是什么也没显示。 It seems like FreeGlut does some voodoo magic in the background, but I don't know what I'm missing. 似乎FreeGlut在后台执行了一些巫术魔术,但是我不知道自己缺少什么。 I've tried this: 我已经试过了:

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;

This sets up a graphics context, but is apparently not enough to make everything work. 这样可以设置图形上下文,但是显然不足以使所有功能正常运行。 The tutorial didn't include anything about view or projection matrices, so I'm not sure whether I should add anything like that. 本教程未包含有关视图或投影矩阵的任何内容,因此我不确定是否应添加类似内容。 But the window remains black. 但是窗户仍然是黑色的。

This is the tutorial code, adjusted to my code: 这是教程代码,已调整为我的代码:

#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;
}

Creating a OpenGL context is not trivial. 创建OpenGL上下文并非易事。 Especially if you want to use wglChoosePixelFormatARB which must be loaded through the OpenGL extension mechanism… which requires a functioning OpenGL context to work in the first place. 尤其是如果您要使用必须通过OpenGL扩展机制加载的wglChoosePixelFormatARB ……这首先需要一个运行正常的OpenGL上下文。 I think you see that this is kind of a chicken-and-egg problem. 我认为您看到这是种鸡与蛋的问题。 In addition the Window you use to create an OpenGL context requires certain attributed to work reliably. 另外,用于创建OpenGL上下文的Window需要某些属性才能可靠地工作。 For one the WndClass should have the CS_OWNDC style set and the window style should include WS_CLIPSIBLINGS | WS_CLIPCHILDREN 对于一个WndClass,应该设置CS_OWNDC样式,并且窗口样式应包括WS_CLIPSIBLINGS | WS_CLIPCHILDREN WS_CLIPSIBLINGS | WS_CLIPCHILDREN

I recently approached the aforementioned chicken-and-egg problem with my small wglarb helper tools: https://github.com/datenwolf/wglarb 我最近用我的小型wglarb助手工具处理了上述的鸡和蛋问题: https : //github.com/datenwolf/wglarb

It also comes with a small test program that shows how to use it. 它还带有一个小型测试程序,该程序演示如何使用它。

I suggest you use the functions provided by that. 我建议您使用该功能提供的功能。 I wrote this little helper library in a way, that it is not negatively impacted if your program uses other extension loading mechanisms. 我以某种方式编写了这个小帮助程序库,如果您的程序使用其他扩展加载机制,它不会受到负面影响。 However it's not thread-safe yet; 但是,它还不是线程安全的。 I'll have to add that eventually. 我将不得不最终添加。 I took the time to make the code thread safe. 我花了一些时间使代码线程安全。 You can now use the exposed functions without having to care about synchronization; 现在,您可以使用公开的功能而不必担心同步。 it's all done internally in a reliable way. 所有这些都以可靠的方式在内部完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM