Нужно загружать функции OpenGL и вызывать их через указатель. Все бы ничего, но преподаватель заставил вместо указателя использовать std::function. С ним возникает проблема, вроде все запускается, но работает не корректно.
Минимальный пример:
typedef void ( * PGLCLEARCOLORPROC ) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
std::function <void (GLclampf, GLclampf, GLclampf, GLclampf)> _glClearColor = NULL;
void glClearColor ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
if(_glClearColor == NULL)
_glClearColor = ( PGLCLEARCOLORPROC ) SDL_GL_GetProcAddress( "glClearColor" );
else
_glClearColor ( red, green, blue, alpha );
}
Весь код:
mygl.h
#ifndef LAB1_HL_S11_V1_MYGL_H
#define LAB1_HL_S11_V1_MYGL_H
typedef unsigned int GLenum;
typedef unsigned int GLbitfield;
typedef unsigned int GLuint;
typedef int GLint;
typedef int GLsizei;
typedef unsigned char GLboolean;
typedef signed char GLbyte;
typedef short GLshort;
typedef unsigned char GLubyte;
typedef unsigned short GLushort;
typedef unsigned long GLulong;
typedef float GLfloat;
typedef float GLclampf;
typedef double GLdouble;
typedef double GLclampd;
typedef void GLvoid;
typedef char GLchar;
#define GL_COLOR_BUFFER_BIT 0x00004000
typedef void ( * PGLCLEARPROC ) (GLbitfield mask);
typedef void ( * PGLCLEARCOLORPROC ) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
bool mygl_Init(const char *);
void mygl_Quit();
void glClear(GLbitfield mask);
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
#endif //LAB1_HL_S11_V1_MYGL_H
mygl.cpp
#include "mygl.h"
#include <iostream>
#include <functional>
#include <SDL2/SDL.h>
std::function <void (GLclampf, GLclampf, GLclampf, GLclampf)> _glClearColor = NULL;
std::function <void (GLbitfield)> _glClear = NULL;
bool mygl_Init(const char *str)
{
if (SDL_GL_LoadLibrary(str) < 0)
{
std::cerr << "Error in load library" << std::endl;
return false;
}
return true;
}
void mygl_Quit()
{
SDL_GL_UnloadLibrary();
}
void glClearColor ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
if(_glClearColor == NULL)
_glClearColor = ( PGLCLEARCOLORPROC ) SDL_GL_GetProcAddress( "glClearColor" );
else
_glClearColor ( red, green, blue, alpha );
}
void glClear (GLbitfield mask)
{
if( _glClear == NULL) {
_glClear = (PGLCLEARPROC) SDL_GL_GetProcAddress("glClearColor");
std::cout << "glClear is NULL" << std::endl;
}
else
_glClear (mask);
}
main.cpp
#include <iostream>
#include "mygl.h"
#include <SDL2/SDL.h>
int main()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Event e;
bool quit = false;
if (!mygl_Init(NULL))
return 0;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_Window *window = SDL_CreateWindow("Lab 1", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 480, SDL_WINDOW_OPENGL);
if(!window)
{
std::cerr << "Error in create window" << std::endl;
return 0;
}
SDL_GLContext glContext = SDL_GL_CreateContext(window);
if(!glContext)
{
std::cerr << "Error in create gl context" << std::endl;
return 0;
}
while( e.type != SDL_QUIT && !quit)
{
while(SDL_PollEvent(&e))
{
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
if(e.key.keysym.sym == SDLK_q && SDL_GetModState() & KMOD_CTRL)
quit = true;
}
}
SDL_GL_DeleteContext(glContext);
SDL_DestroyWindow(window);
mygl_Quit();
SDL_Quit();
return 0;
}
Результат работы: