123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- #include "StdInc.h"
- #include <SDL.h>
- #include <SDL_video.h>
- #include "SDL_syswm.h"
- #include <SDL_opengl.h>
- #include "GL2D.h"
- namespace GL2D
- {
- // Variables initialized by initVideo, updated by setScreenRes:
- static SDL_SysWMinfo wmInfo;
- ui32 screenWidth = 0, screenHeight = 0; // Screen/Window size
- // OpenGL 1.3 functions pointers
- PFNGLACTIVETEXTUREPROC glActiveTexture;
- // OpenGL 2.0 functions pointers
- PFNGLCREATEPROGRAMPROC glCreateProgram;
- PFNGLCREATESHADERPROC glCreateShader;
- PFNGLSHADERSOURCEPROC glShaderSource;
- PFNGLCOMPILESHADERPROC glCompileShader;
- PFNGLATTACHSHADERPROC glAttachShader;
- PFNGLLINKPROGRAMPROC glLinkProgram;
- PFNGLUSEPROGRAMPROC glUseProgram;
- PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
- PFNGLUNIFORM1IPROC glUniform1i;
- PFNGLUNIFORM2IPROC glUniform2i;
- PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
- PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
- // Shaders' sources
- static const char frag_palette_bitmap[] = (
- "uniform usampler2DRect bitmap;"
- "uniform sampler1D palette;"
- "uniform ivec2 coordOffs;"
- "layout (origin_upper_left) in vec4 gl_FragCoord;"
- "void main(){"
- "gl_FragColor = texelFetch(palette, int(texelFetch(bitmap, ivec2(gl_FragCoord.xy) - coordOffs).r), 0);"
- "}"
- );
- // Programs' handlers
- static GLuint currentProgram = 0;
- static GLuint colorizeProgram = 0;
- static GLuint paletteBitmapProgram = 0;
- // Uniforms handlers
- static GLint coord_uniform = -1;
- // Print out the information log for a shader object
- void printInfoLog(PFNGLGETPROGRAMINFOLOGPROC logFunc, GLuint object)
- {
- if (logFunc != nullptr)
- {
- GLsizei infoLogLength = 0;
- GLchar infoLog[1024];
- logFunc(object, sizeof(infoLog)-1, &infoLogLength, infoLog);
- if (infoLogLength > 0) tlog1 << infoLog;
- }
- }
- GLuint makeShaderProgram(const char * frg_src)
- {
- // Creating a fragment shader object
- GLuint shader_object = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(shader_object, 1, &frg_src, nullptr); // assigning the shader source
- // Compiling the shader
- glCompileShader(shader_object);
- printInfoLog(glGetShaderInfoLog, shader_object);
- // Creating a program object
- GLuint program_object = glCreateProgram();
- // Attaching the shader into program
- glAttachShader(program_object, shader_object);
- // Link the shaders into a complete GLSL program.
- glLinkProgram(program_object);
- printInfoLog(glGetProgramInfoLog, program_object);
- return program_object;
- }
- void initVideo(ui32 w, ui32 h, bool fullscreen)
- {
- SDL_VERSION(&wmInfo.version);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- if (!setScreenRes(w, h, fullscreen))
- {
- throw std::runtime_error("Video mode setting failed\n");
- }
- glClearColor(0, 0, 0, 0); // Black Background
- glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapBuffers();
- // Dynamic-linked OpenGL 1.3 and 2.0 functions - required to 2D rendeing
- if ( (glActiveTexture = (PFNGLACTIVETEXTUREPROC) SDL_GL_GetProcAddress("glActiveTexture")) == nullptr
- || (glCreateProgram = (PFNGLCREATEPROGRAMPROC) SDL_GL_GetProcAddress("glCreateProgram")) == nullptr
- || (glCreateShader = (PFNGLCREATESHADERPROC) SDL_GL_GetProcAddress("glCreateShader")) == nullptr
- || (glShaderSource = (PFNGLSHADERSOURCEPROC) SDL_GL_GetProcAddress("glShaderSource")) == nullptr
- || (glCompileShader = (PFNGLCOMPILESHADERPROC) SDL_GL_GetProcAddress("glCompileShader")) == nullptr
- || (glAttachShader = (PFNGLATTACHSHADERPROC) SDL_GL_GetProcAddress("glAttachShader")) == nullptr
- || (glLinkProgram = (PFNGLLINKPROGRAMPROC) SDL_GL_GetProcAddress("glLinkProgram")) == nullptr
- || (glUseProgram = (PFNGLUSEPROGRAMPROC) SDL_GL_GetProcAddress("glUseProgram")) == nullptr
- || (glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) SDL_GL_GetProcAddress("glGetUniformLocation")) == nullptr
- || (glUniform1i = (PFNGLUNIFORM1IPROC) SDL_GL_GetProcAddress("glUniform1i")) == nullptr
- || (glUniform2i = (PFNGLUNIFORM2IPROC) SDL_GL_GetProcAddress("glUniform2i")) == nullptr
- )
- {
- tlog1 << "Error: OpenGL2 Extenstions are not available\n";
- tlog1 << "SDL says: " << SDL_GetError() << std::endl;
- throw std::runtime_error("OpenGL2 Extenstions are not available\n");
- }
- glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) SDL_GL_GetProcAddress("glGetProgramInfoLog"); // not required
- glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) SDL_GL_GetProcAddress("glGetShaderInfoLog"); // not required
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_LIGHTING);
- glDisable(GL_DITHER);
- glDisable(GL_TEXTURE_2D);
- glEnable(GL_TEXTURE_RECTANGLE);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- paletteBitmapProgram = makeShaderProgram(frag_palette_bitmap);
- GLint bitmap_uniform = glGetUniformLocation(paletteBitmapProgram, "bitmap");
- GLint palette_uniform = glGetUniformLocation(paletteBitmapProgram, "palette");
- coord_uniform = glGetUniformLocation(paletteBitmapProgram, "coordOffs");
- glUseProgram(currentProgram = paletteBitmapProgram);
- glUniform1i(bitmap_uniform, 0);
- glUniform1i(palette_uniform, 1);
- #ifdef _WIN32
- wglMakeCurrent(NULL, NULL);
- #endif
- }
- void attachToCurrentThread()
- {
- #ifdef _WIN32
- HDC hdc = GetDC(wmInfo.window);
- wglMakeCurrent(hdc, wmInfo.hglrc);
- #endif
- }
- bool setScreenRes(ui32 w, ui32 h, bool fullscreen)
- {
- // Try to use the best screen depth for the display
- int suggestedBpp = SDL_VideoModeOK(w, h, 32, SDL_OPENGL | SDL_ANYFORMAT | (fullscreen?SDL_FULLSCREEN:0));
- if(suggestedBpp == 0)
- {
- tlog1 << "Error: SDL says that " << w << "x" << h << " resolution is not available!\n";
- return false;
- }
-
- if(suggestedBpp != 32)
- {
- tlog2 << "Note: SDL suggests to use " << suggestedBpp << " bpp instead of 32 bpp\n";
- }
- if(SDL_SetVideoMode(w, h, suggestedBpp, SDL_OPENGL | SDL_ANYFORMAT | (fullscreen?SDL_FULLSCREEN:0)) == NULL)
- {
- tlog1 << "Error: Video mode setting failed (" << w << "x" << h << "x" << suggestedBpp << "bpp)\n";
- return false;
- }
- screenWidth = w; screenHeight = h;
- int getwm = SDL_GetWMInfo(&wmInfo);
- if(getwm != 1)
- {
- tlog2 << "Something went wrong, getwm=" << getwm << std::endl;
- tlog2 << "SDL says: " << SDL_GetError() << std::endl;
- return false;
- }
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
- glLoadIdentity(); // Reset The Projection Matrix
- glOrtho(0, w, h, 0, 0, 1);
- glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
- glLoadIdentity(); // Reset The Modelview Matrix
- glTranslatef(0.375, 0.375, 0); // Displacement trick for exact pixelization
-
- return true;
- }
- void assignTexture(ui32 slot, ui32 type, ui32 handle)
- {
- glActiveTexture(slot);
- glBindTexture(type, handle);
- }
- void useNoShader()
- {
- if (currentProgram != 0) {
- glUseProgram(currentProgram = 0);
- }
- }
- void useColorizeShader(const float cm[4][4])
- {
- if (currentProgram != colorizeProgram) {
- glUseProgram(currentProgram = colorizeProgram);
- }
- }
- void usePaletteBitmapShader(si32 x, si32 y)
- {
- if (currentProgram != paletteBitmapProgram) {
- glUseProgram(currentProgram = paletteBitmapProgram);
- }
- glUniform2i(coord_uniform, x, y);
- }
- void usePaletteBitmapShader(si32 x, si32 y, const float cm[4][4])
- {
- if (currentProgram != paletteBitmapProgram) {
- glUseProgram(currentProgram = paletteBitmapProgram);
- }
- glUniform2i(coord_uniform, x, y);
- }
- }
|