31#include "physfsrwops.h"
49#define OPENGL_REQ_MULTITEX 2
59static int gl_view_x = 0;
60static int gl_view_y = 0;
61static int gl_view_w = 0;
62static int gl_view_h = 0;
63mat4 gl_view_matrix = {{{{0}}}};
96 screenbuf = malloc(
sizeof(GLubyte) * 3 * w*h );
97 surface = SDL_CreateRGBSurface( 0, w, h, 24, RGBAMASK );
100 glPixelStorei(GL_PACK_ALIGNMENT, 1);
101 glReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, screenbuf );
104 for (
int i=0; i<h; i++)
105 memcpy( (GLubyte*)surface->pixels + i * surface->pitch, &screenbuf[ (h - i - 1) * (3*w) ], 3*w );
109 if (!(rw = PHYSFSRWOPS_openWrite( filename )))
110 WARN( _(
"Aborting screenshot") );
112 IMG_SavePNG_RW( surface, rw, 1 );
118 SDL_FreeSurface( surface );
135 if (GLVersion.major >= major && GLVersion.minor >= minor)
144void gl_checkHandleError(
const char *func,
int line )
150 GLenum err = glGetError();
153 if (err == GL_NO_ERROR)
157 case GL_INVALID_ENUM:
158 errstr = _(
"GL invalid enum");
160 case GL_INVALID_VALUE:
161 errstr = _(
"GL invalid value");
163 case GL_INVALID_OPERATION:
164 errstr = _(
"GL invalid operation");
166 case GL_INVALID_FRAMEBUFFER_OPERATION:
167 errstr = _(
"GL invalid framebuffer operation");
169 case GL_OUT_OF_MEMORY:
170 errstr = _(
"GL out of memory");
174 errstr = _(
"GL unknown error");
177 WARN(_(
"OpenGL error [%s:%d]: %s"), func, line, errstr);
185static void GLAPIENTRY gl_debugCallback( GLenum source, GLenum type, GLuint
id, GLenum severity, GLsizei length,
const GLchar* message,
const void* p )
187 static int errors_seen = 0;
194 if (++errors_seen == 10)
195 WARN( _(
"Too many OpenGL diagnostics reported! Suppressing further reports.") );
196 if (errors_seen >= 10)
200 case GL_DEBUG_TYPE_ERROR:
201 typestr =
" GL_DEBUG_TYPE_ERROR";
203 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
204 typestr =
" GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR";
206 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
207 typestr =
" GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR";
209 case GL_DEBUG_TYPE_PORTABILITY:
210 typestr =
" GL_DEBUG_TYPE_PORTABILITY";
212 case GL_DEBUG_TYPE_PERFORMANCE:
213 typestr =
" GL_DEBUG_TYPE_PERFORMANCE";
215 case GL_DEBUG_TYPE_OTHER:
216 typestr =
" GL_DEBUG_TYPE_OTHER";
218 case GL_DEBUG_TYPE_MARKER:
219 case GL_DEBUG_TYPE_PUSH_GROUP:
220 case GL_DEBUG_TYPE_POP_GROUP:
225 WARN( _(
"[type = 0x%x%s], severity = 0x%x, message = %s backtrace:"), type, typestr, severity, message );
226 debug_logBacktrace();
238 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, fallback ? 3 : 4);
239 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, fallback ? 2 : 0);
240 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
241 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
243 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
244 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, conf.
fsaa);
246 SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
248 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
265 SDL_DisplayMode target, closest;
269 target.w = conf.
width;
273 SDL_GetDesktopDisplayMode( display_index, &target );
275 if (SDL_GetClosestDisplayMode( display_index, &target, &closest ) == NULL)
276 SDL_GetDisplayMode( display_index, 0, &closest );
296 return conf.
modesetting ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
307 flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI;
309 flags |= SDL_WINDOW_RESIZABLE;
311 flags |= SDL_WINDOW_BORDERLESS;
315 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
318 ERR(_(
"Unable to create window! %s"), SDL_GetError());
321 SDL_SetHint( SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,
325 for (
int fallback=0; fallback <= 1; fallback++) {
332 ERR(_(
"Unable to create OpenGL context! %s"), SDL_GetError());
336 int ret = SDL_GL_SetSwapInterval( 1 );
340 SDL_GL_SetSwapInterval( 0 );
345 for (
int i=0; i<OPENGL_NUM_FBOS; i++) {
363 SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &
gl_screen.
r );
364 SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &
gl_screen.
g );
365 SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &
gl_screen.
b );
366 SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, &
gl_screen.
a );
367 SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &doublebuf );
368 SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &
gl_screen.
fsaa );
371 if (GLAD_GL_ARB_shader_subroutine && glGetSubroutineIndex && glGetSubroutineUniformLocation && glUniformSubroutinesuiv)
382 DEBUG(_(
"r: %d, g: %d, b: %d, a: %d, db: %s, fsaa: %d, tex: %d"),
384 gl_has(OPENGL_DOUBLEBUF) ? _(
"yes") : _(
"no"),
386 DEBUG(_(
"vsync: %s"), gl_has(OPENGL_VSYNC) ? _(
"yes") : _(
"no"));
387 DEBUG(_(
"Renderer: %s"), glGetString(GL_RENDERER));
388 DEBUG(_(
"Version: %s"), glGetString(GL_VERSION));
392 WARN(_(
"Missing texture units (%d required, %d found)"),
395 WARN(_(
"Unable to get requested FSAA level (%d requested, got %d)"),
408 glDisable( GL_DEPTH_TEST );
409 glEnable( GL_BLEND );
410 glEnable( GL_LINE_SMOOTH );
412 glEnable( GL_DEBUG_OUTPUT );
413 glDebugMessageCallback( gl_debugCallback, 0 );
414 glDebugMessageControl( GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE, GL_DONT_CARE, 0, NULL, GL_FALSE );
415 glDebugMessageControl( GL_DONT_CARE, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, 0, NULL, GL_FALSE );
419 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
449 double scalew, scaleh;
451 DEBUG(_(
"Screen size too small, upscaling..."));
482 SDL_SetHint(
"SDL_WINDOWS_DPI_SCALING",
"1" );
486 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
487 WARN(_(
"Unable to initialize SDL Video: %s"), SDL_GetError());
498 if (!gladLoadGLLoader(SDL_GL_GetProcAddress))
499 ERR(
"Unable to load OpenGL using GLAD");
502 if ( !GLAD_GL_VERSION_3_1 )
503 WARN(
"Naev requires OpenGL 3.1, but got OpenGL %d.%d!", GLVersion.major, GLVersion.minor );
506 glClearColor( 0., 0., 0., 1. );
515 glClear( GL_COLOR_BUFFER_BIT );
527 glGenVertexArrays(1, &VaoId);
528 glBindVertexArray(VaoId);
536 glEnable( GL_FRAMEBUFFER_SRGB );
555 for (
int i=0; i<OPENGL_NUM_FBOS; i++) {
591 gl_view_matrix = proj;
610 gl_viewport( gl_view_x, gl_view_y, gl_view_w, gl_view_h );
645 if (strcmp(s,
"linear")==0)
647 else if (strcmp(s,
"nearest")==0)
660 if (strcmp(s,
"clamp")==0)
661 return GL_CLAMP_TO_EDGE;
662 else if (strcmp(s,
"repeat")==0)
664 else if (strcmp(s,
"mirroredrepeat")==0)
665 return GL_MIRRORED_REPEAT;
681 shader.program = shaders.colourblind.program;
682 shader.VertexPosition = shaders.colourblind.VertexPosition;
683 shader.ClipSpaceFromLocal = shaders.colourblind.ClipSpaceFromLocal;
684 shader.MainTex = shaders.colourblind.MainTex;
685 colourblind_pp = render_postprocessAdd( &shader, PP_LAYER_CORE, 99, PP_SHADER_PERMANENT );
698 for (
int i=0; i<OPENGL_NUM_FBOS; i++) {
715 SDL_QuitSubSystem(SDL_INIT_VIDEO);
void mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
mat4 mat4_ortho(double left, double right, double bottom, double top, double nearVal, double farVal)
Creates an orthographic projection matrix.
Header file with generic functions and naev-specifics.
void gl_setDefViewport(int x, int y, int w, int h)
Sets the default viewport.
void gl_screenshot(const char *filename)
Takes a screenshot.
static int gl_defState(void)
Sets the opengl state to it's default parameters.
static int gl_getGLInfo(void)
Gets some information about the OpenGL window.
void gl_defViewport(void)
Resets viewport to default.
void gl_colourblind(int enable)
Enables or disables the colourblind shader.
void gl_resize(void)
Handles a window resize and resets gl_screen parameters.
void gl_screenToWindowPos(int *wx, int *wy, int sx, int sy)
Translates the screen position to windos position.
GLint gl_stringToFilter(const char *s)
Gets the associated min/mag filter from a string.
void gl_exit(void)
Cleans up OpenGL, the works.
void gl_viewport(int x, int y, int w, int h)
Sets the opengl viewport.
void gl_windowToScreenPos(int *sx, int *sy, int wx, int wy)
Translates the window position to screen position.
static int gl_getFullscreenMode(void)
Returns the fullscreen configuration as SDL2 flags.
static unsigned int colourblind_pp
static int gl_setupAttributes(int fallback)
Tries to set up the OpenGL attributes for the OpenGL context.
static int gl_setupScaling(void)
Sets up dimensions in gl_screen, including scaling as needed.
int gl_init(void)
Initializes SDL/OpenGL and the works.
static int gl_createWindow(unsigned int flags)
Creates the OpenGL window.
GLboolean gl_hasVersion(int major, int minor)
Checks to see if opengl version is at least major.minor.
#define OPENGL_REQ_MULTITEX
GLint gl_stringToClamp(const char *s)
Gets the associated min/mag filter from a string.
int gl_setupFullscreen(void)
Tries to apply the configured display mode to the window.
void gl_exitRender(void)
Cleans up the OpenGL rendering routines.
int gl_initRender(void)
Initializes the OpenGL rendering routines.
void gl_exitTextures(void)
Cleans up the opengl texture subsystem.
int gl_fboCreate(GLuint *fbo, GLuint *tex, GLsizei width, GLsizei height)
Creates a framebuffer and its associated texture.
int gl_initTextures(void)
Initializes the opengl texture subsystem.
int gl_initVBO(void)
Initializes the OpenGL VBO subsystem.
void gl_exitVBO(void)
Exits the OpenGL VBO subsystem.
Stores data about the current opengl environment.
GLuint fbo_tex[OPENGL_NUM_FBOS]
GLuint fbo[OPENGL_NUM_FBOS]