2
\$\begingroup\$

I have been trying to use OpenGL for two days now. First on Mac, then on Windows. The problem with Mac is that it doesn't support the newer versions of OpenGL. I ran a tutorial that actually did get some things working, but it only works in XCode (i.e., I can't create a new file, paste in the same code, and get it to work). Because of these issues, I moved to Windows. My Windows 7 has OpenGL 4.3, which is the same that is used in alot of other tutorials. However, not one of these tutorials gives any instruction on how to set it up for the first time. I have come across some vague posts saying that some libraries need to be linked. But WHAT libraries, and HOW do I link them?

Please help. I am pretty desperate to set this up as this project is due for work soon. I have actually used OpenGL before at my university, but the computers already had everything set up. The project itself is very easy, but setting up OpenGL is not something I know how to do.

Edit: Using C++.

\$\endgroup\$
  • \$\begingroup\$ OSX supports up to OpenGL 4.1 though. And it does not only work in XCode, you just have to link to the required frameworks with your compiler command. You don't need to setup anything, OSX supports OGL projects out of the box. In Windows, you need to link to opengl32.lib. But in Windows, to have access to anything newer than OGL 1.1, you need to install the Windows SDK as far as I know. \$\endgroup\$ – Appleshell May 29 '14 at 20:58
  • \$\begingroup\$ @AdamS OSX Mavericks supports 4.1, but I was trying to avoid updating to Mavericks since my hard drive has very little space left. Additionally, 4.1 still lacks some features of 4.3. Can you elaborate how to link to these frameworks on Mac? The commands I found online such as -lGL have not worked. Additionally, how would I link to opengl32.lib on Windows? I don't have much experience doing this kind of linking. \$\endgroup\$ – kevin james May 29 '14 at 21:03
  • \$\begingroup\$ You have to use the -framework option, e.g. gcc ogltest.cpp -framework OpenGL. On Windows you probably use Visual Studio, or another IDE? You have to add opengl32.lib in the linker options. After you've done that, I suggest looking into GLFW for context creation and GLEW for binding the latest OGL features. Also read open.gl/context \$\endgroup\$ – Appleshell May 29 '14 at 21:16
  • \$\begingroup\$ Nobody can answer this because you have not even mentioned your language. But generally speaking, if you are using C then you need to link to opengl32.lib. Windows uses a WGL API to manage the render context, whereas on OS X you probably used CGL, AGL or NSOpenGL. Likewise, on Windows anything newer than OpenGL 1.1 has to be resolved at run-time using wglGetProcAddress (...) because the platform ships with a 1.1 implementation and display drivers extend it using Installable Client Drivers. \$\endgroup\$ – Andon M. Coleman May 29 '14 at 23:20
  • \$\begingroup\$ @AdamS: Even if you install the Windows SDK, which has nothing to do with this, you would still be limited to GL 1.1. Microsoft implemented OpenGL 1.1 in GDI 15 years ago and then defined a mechanism (ICDs) for display drivers to extend their implementation. Microsoft has never bothered to update their implementation, and the only way to get something newer is to install Mesa (which is not an ICD) or use a hardware vendor's display drivers. \$\endgroup\$ – Andon M. Coleman May 29 '14 at 23:28
2
\$\begingroup\$

Visual Studio

The Swiftless Tutorials should function as a good basis. I'm going to point out the second paragraph in the Coding section in particular:

So open up Visual Studio and create a new Windows Console Application in C++. Make sure it is empty to begin with, and then create 4 files. I am calling them: “main.cpp, main.h, opengl_3.cpp, opengl_3.h”. I am going to go through these files one by one, starting with the header files, so that we don’t get mixed up shuffling between them.

And its pragmas:

#pragma comment(lib, "glew32.lib")  
#pragma comment(lib, "opengl32.lib")  

Though I'm not particularly familiar with visual studio, so I'm just going to leave you with that tutorial.

CodeBlocks

You can create an OpenGL project in the projects menu. However, that sets up an OpenGL 2.1 project, not an OpenGL 4.2 project. Once you have that project created, you can fallow along with most visual-studio tutorials to the point of copy/past. (only adjusting things here and there for the compiler differences.)

Feel free to stop reading. The following is how I prefer to do it (In codeblocks.) It might not be how you want to do it for whatever reason, it works regardless.

But, since I can: You can add in the code that upgrades it from 2.1 to 4.2 yourself with wglCreateContextAttribsARB(...) Which you would use after the 2.1 context was created. In the particular case of the CodeBlocks projects, that would be by modifying the EnableOpenGL() function.

//#include <GL/gl.h> <- this is OpenGL 2.1 header. You don't want that.
#include <GL/wglext.h> // you might need to download these
#include <GL/gl3.h>

//...

void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
    //...

    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;

    int attributes[] = {
        WGL_CONTEXT_MAJOR_VERSION_ARB, major,
        WGL_CONTEXT_MINOR_VERSION_ARB, minor,
        WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
        0,
    };

    wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");

    if (wglCreateContextAttribsARB == NULL)
    {
        // HANDLE FAILURE
    }

    HGLRC sglcv = wglCreateContextAttribsARB(hDC, NULL, attributes);

    if (sglcv != NULL)
    {
        wglMakeCurrent(NULL, NULL);
        wglDeleteContext(hRC);
        hRC = sglcv;
        wglMakeCurrent(hDC, hRC);

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    }
    else
    {
        // HANDLE FAILURE
    }
}

Then (Only then. You need a context to be bound first.) you can get OpenGL functions as needed with:

PFN$(glFunctionCapitalized)PROC FunctionName;
FunctionName = (PFN$(glFunctionCapitalized)PROC)wglGetProcAddress("$(glFunctionName)");
if (FunctionName == NULL)
{
    // You cannot use that function. Handle as needed.
}

For example:

PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
if (VertexAttribPointer == NULL)
{
    cout << "glVertexAttribPointer could not be loaded. Exiting application." << endl;
    system("pause");
    return FATAL_ERROR;
}

Lastly, changing the 2.1 rendering code that's near the end of the main function, in the program loop. It should be fairly Identifiable. (it uses glBegin, glVertex, and glEnd) The section should be something like this:

        /* OpenGL animation code goes here */

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glPushMatrix();
        glRotatef(theta, 0.0f, 0.0f, 1.0f);

        glBegin(GL_TRIANGLES);

            glColor3f(1.0f, 0.0f, 0.0f);   glVertex2f(0.0f,   1.0f);
            glColor3f(0.0f, 1.0f, 0.0f);   glVertex2f(0.87f,  -0.5f);
            glColor3f(0.0f, 0.0f, 1.0f);   glVertex2f(-0.87f, -0.5f);

        glEnd();

        glPopMatrix();

        SwapBuffers(hDC);

        theta += 1.0f;
        Sleep (1);

Which you can change around to your liking. Any input, or window-stuff you might want to do would be in the WindowProc function, just after the main function.

\$\endgroup\$
  • \$\begingroup\$ just to add to the answer, glew works by default only with vs 2010, you need to recompile it to work with any other versions. I've experienced this first hand with 2013, it wouldn't run, compiled fine but kept on crashing \$\endgroup\$ – Sherlock May 30 '14 at 21:33
1
\$\begingroup\$

There is no way on windows to get "direct" access to OpenGL (e.g. load a header and link a lib), instead you need to ask Windows to give you the pointer to the different functions at run time.

So you need to define a bunch of function pointers like this:

void (*glUseProgram)(GLuint program) = nullptr;
void (*glValidateProgram)(GLuint program) = nullptr;
[... etc ...]

And assign them

glUseProgram = glfwGetProcAddress("glUseProgram");
glValidateProgram = glfwGetProcAddress("glValidateProgram");
[... etc ...]

In this case I am using glfw to get the function pointers, but the same is possible with WGL. (WGL = Windows OpenGL API, glfw wraps multiple different APIs including WGL from different systems into one and makes sure everything just works)

This is of course a lot of redundant code but unfortunately necessary. Using WinAPI directly will make it even more complex in the case of post 2.1 OpenGL so I recommend using GLFW.

Thankfully there are quite a few loader libraries, which do all the function pointer loading for you so you don't have to do it manually: http://www.opengl.org/wiki/OpenGL_Loading_Library

\$\endgroup\$
0
\$\begingroup\$

Use GLEW it does all the platform specific stuff linking what otherwise would you do manually. You also mustn't worry about compatibility, it generates you a list with all possible (and impossible sometimes :D) extensions. Here you are: http://glew.sourceforge.net/ :)

\$\endgroup\$
  • 2
    \$\begingroup\$ No it does not. About the only thing GLEW does for you that helps with cross-platform support is that it calls glXGetProcAddress (...) on X11 and wglGetProcAddress (...) on Win32. There are tons of other platform-specific things related to creating and managing a render context that GLEW has nothing to do with. \$\endgroup\$ – Andon M. Coleman May 29 '14 at 23:24
0
\$\begingroup\$

I recently started learning opengl myself, combined with SDL2; The only changes I needed to make to linking using CodeBlocks under win7 was to add ' -lopengl32 ' to my list.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.