testgl2.c
Go to the documentation of this file.
/*
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "SDL_test_common.h"
#ifdef __MACOS__
#define HAVE_OPENGL
#endif
#ifdef HAVE_OPENGL
#include "SDL_opengl.h"
typedef struct GL_Context
{
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
#include "../src/render/opengl/SDL_glfuncs.h"
#undef SDL_PROC
} GL_Context;
/* Undefine this if you want a flat cube instead of a rainbow cube */
#define SHADED_CUBE
static SDLTest_CommonState *state;
static SDL_GLContext context;
static GL_Context ctx;
static int LoadContext(GL_Context * data)
{
#if SDL_VIDEO_DRIVER_UIKIT
#define __SDL_NOGETPROCADDR__
#elif SDL_VIDEO_DRIVER_ANDROID
#define __SDL_NOGETPROCADDR__
#elif SDL_VIDEO_DRIVER_PANDORA
#define __SDL_NOGETPROCADDR__
#endif
#if defined __SDL_NOGETPROCADDR__
#define SDL_PROC(ret,func,params) data->func=func;
#else
#define SDL_PROC(ret,func,params) \
do { \
data->func = SDL_GL_GetProcAddress(#func); \
if ( ! data->func ) { \
return SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \
} \
} while ( 0 );
#endif /* __SDL_NOGETPROCADDR__ */
#include "../src/render/opengl/SDL_glfuncs.h"
#undef SDL_PROC
return 0;
}
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit(int rc)
{
if (context) {
/* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
SDL_GL_DeleteContext(context);
}
SDLTest_CommonQuit(state);
exit(rc);
}
static void
Render()
{
static float color[8][3] = {
{1.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{0.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 1.0, 1.0},
{1.0, 1.0, 1.0},
{1.0, 0.0, 1.0},
{0.0, 0.0, 1.0}
};
static float cube[8][3] = {
{0.5, 0.5, -0.5},
{0.5, -0.5, -0.5},
{-0.5, -0.5, -0.5},
{-0.5, 0.5, -0.5},
{-0.5, 0.5, 0.5},
{0.5, 0.5, 0.5},
{0.5, -0.5, 0.5},
{-0.5, -0.5, 0.5}
};
/* Do our drawing, too. */
ctx.glClearColor(0.0, 0.0, 0.0, 1.0);
ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ctx.glBegin(GL_QUADS);
#ifdef SHADED_CUBE
ctx.glColor3fv(color[0]);
ctx.glVertex3fv(cube[0]);
ctx.glColor3fv(color[1]);
ctx.glVertex3fv(cube[1]);
ctx.glColor3fv(color[2]);
ctx.glVertex3fv(cube[2]);
ctx.glColor3fv(color[3]);
ctx.glVertex3fv(cube[3]);
ctx.glColor3fv(color[3]);
ctx.glVertex3fv(cube[3]);
ctx.glColor3fv(color[4]);
ctx.glVertex3fv(cube[4]);
ctx.glColor3fv(color[7]);
ctx.glVertex3fv(cube[7]);
ctx.glColor3fv(color[2]);
ctx.glVertex3fv(cube[2]);
ctx.glColor3fv(color[0]);
ctx.glVertex3fv(cube[0]);
ctx.glColor3fv(color[5]);
ctx.glVertex3fv(cube[5]);
ctx.glColor3fv(color[6]);
ctx.glVertex3fv(cube[6]);
ctx.glColor3fv(color[1]);
ctx.glVertex3fv(cube[1]);
ctx.glColor3fv(color[5]);
ctx.glVertex3fv(cube[5]);
ctx.glColor3fv(color[4]);
ctx.glVertex3fv(cube[4]);
ctx.glColor3fv(color[7]);
ctx.glVertex3fv(cube[7]);
ctx.glColor3fv(color[6]);
ctx.glVertex3fv(cube[6]);
ctx.glColor3fv(color[5]);
ctx.glVertex3fv(cube[5]);
ctx.glColor3fv(color[0]);
ctx.glVertex3fv(cube[0]);
ctx.glColor3fv(color[3]);
ctx.glVertex3fv(cube[3]);
ctx.glColor3fv(color[4]);
ctx.glVertex3fv(cube[4]);
ctx.glColor3fv(color[6]);
ctx.glVertex3fv(cube[6]);
ctx.glColor3fv(color[1]);
ctx.glVertex3fv(cube[1]);
ctx.glColor3fv(color[2]);
ctx.glVertex3fv(cube[2]);
ctx.glColor3fv(color[7]);
ctx.glVertex3fv(cube[7]);
#else /* flat cube */
ctx.glColor3f(1.0, 0.0, 0.0);
ctx.glVertex3fv(cube[0]);
ctx.glVertex3fv(cube[1]);
ctx.glVertex3fv(cube[2]);
ctx.glVertex3fv(cube[3]);
ctx.glColor3f(0.0, 1.0, 0.0);
ctx.glVertex3fv(cube[3]);
ctx.glVertex3fv(cube[4]);
ctx.glVertex3fv(cube[7]);
ctx.glVertex3fv(cube[2]);
ctx.glColor3f(0.0, 0.0, 1.0);
ctx.glVertex3fv(cube[0]);
ctx.glVertex3fv(cube[5]);
ctx.glVertex3fv(cube[6]);
ctx.glVertex3fv(cube[1]);
ctx.glColor3f(0.0, 1.0, 1.0);
ctx.glVertex3fv(cube[5]);
ctx.glVertex3fv(cube[4]);
ctx.glVertex3fv(cube[7]);
ctx.glVertex3fv(cube[6]);
ctx.glColor3f(1.0, 1.0, 0.0);
ctx.glVertex3fv(cube[5]);
ctx.glVertex3fv(cube[0]);
ctx.glVertex3fv(cube[3]);
ctx.glVertex3fv(cube[4]);
ctx.glColor3f(1.0, 0.0, 1.0);
ctx.glVertex3fv(cube[6]);
ctx.glVertex3fv(cube[1]);
ctx.glVertex3fv(cube[2]);
ctx.glVertex3fv(cube[7]);
#endif /* SHADED_CUBE */
ctx.glEnd();
ctx.glMatrixMode(GL_MODELVIEW);
ctx.glRotatef(5.0, 1.0, 1.0, 1.0);
}
int
main(int argc, char *argv[])
{
int fsaa, accel;
int value;
int i, done;
SDL_DisplayMode mode;
SDL_Event event;
Uint32 then, now, frames;
int status;
int dw, dh;
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
/* Initialize parameters */
fsaa = 0;
accel = -1;
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
if (!state) {
return 1;
}
for (i = 1; i < argc;) {
int consumed;
consumed = SDLTest_CommonArg(state, i);
if (consumed == 0) {
if (SDL_strcasecmp(argv[i], "--fsaa") == 0 && i+1 < argc) {
fsaa = atoi(argv[i+1]);
consumed = 2;
} else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i+1 < argc) {
accel = atoi(argv[i+1]);
consumed = 2;
} else {
consumed = -1;
}
}
if (consumed < 0) {
SDL_Log("Usage: %s %s [--fsaa n] [--accel n]\n", argv[0],
SDLTest_CommonUsage(state));
quit(1);
}
i += consumed;
}
/* Set OpenGL parameters */
state->window_flags |= SDL_WINDOW_OPENGL;
state->gl_red_size = 5;
state->gl_green_size = 5;
state->gl_blue_size = 5;
state->gl_depth_size = 16;
state->gl_double_buffer = 1;
if (fsaa) {
state->gl_multisamplebuffers = 1;
state->gl_multisamplesamples = fsaa;
}
if (accel >= 0) {
state->gl_accelerated = accel;
}
if (!SDLTest_CommonInit(state)) {
quit(2);
}
/* Create OpenGL context */
context = SDL_GL_CreateContext(state->windows[0]);
if (!context) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError());
quit(2);
}
/* Important: call this *after* creating the context */
if (LoadContext(&ctx) < 0) {
SDL_Log("Could not load GL functions\n");
quit(2);
return 0;
}
if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
/* try late-swap-tearing first. If not supported, try normal vsync. */
if (SDL_GL_SetSwapInterval(-1) == -1) {
SDL_GL_SetSwapInterval(1);
}
} else {
SDL_GL_SetSwapInterval(0); /* disable vsync. */
}
SDL_GetCurrentDisplayMode(0, &mode);
SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format));
SDL_Log("Swap Interval : %d\n", SDL_GL_GetSwapInterval());
SDL_GetWindowSize(state->windows[0], &dw, &dh);
SDL_Log("Window Size : %d,%d\n", dw, dh);
SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh);
SDL_Log("Draw Size : %d,%d\n", dw, dh);
SDL_Log("\n");
SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR));
SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER));
SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION));
SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS));
SDL_Log("\n");
status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
if (!status) {
SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", SDL_GetError());
}
status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
if (!status) {
SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", SDL_GetError());
}
status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
if (!status) {
SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", SDL_GetError());
}
status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
if (!status) {
SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", 16, value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", SDL_GetError());
}
if (fsaa) {
status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
if (!status) {
SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n",
SDL_GetError());
}
status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
if (!status) {
SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n",
SDL_GetError());
}
}
if (accel >= 0) {
status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
if (!status) {
SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d\n", accel,
value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n",
SDL_GetError());
}
}
/* Set rendering settings */
ctx.glMatrixMode(GL_PROJECTION);
ctx.glLoadIdentity();
ctx.glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
ctx.glMatrixMode(GL_MODELVIEW);
ctx.glLoadIdentity();
ctx.glEnable(GL_DEPTH_TEST);
ctx.glDepthFunc(GL_LESS);
ctx.glShadeModel(GL_SMOOTH);
/* Main render loop */
frames = 0;
then = SDL_GetTicks();
done = 0;
while (!done) {
/* Check for events */
++frames;
while (SDL_PollEvent(&event)) {
SDLTest_CommonEvent(state, &event, &done);
}
for (i = 0; i < state->num_windows; ++i) {
int w, h;
if (state->windows[i] == NULL)
continue;
SDL_GL_MakeCurrent(state->windows[i], context);
SDL_GL_GetDrawableSize(state->windows[i], &w, &h);
ctx.glViewport(0, 0, w, h);
Render();
SDL_GL_SwapWindow(state->windows[i]);
}
}
/* Print out some timing information */
now = SDL_GetTicks();
if (now > then) {
SDL_Log("%2.2f frames per second\n",
((double) frames * 1000) / (now - then));
}
quit(0);
return 0;
}
#else /* HAVE_OPENGL */
int
main(int argc, char *argv[])
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system\n");
return 1;
}
#endif /* HAVE_OPENGL */
SDL_PollEvent
#define SDL_PollEvent
Definition: SDL_dynapi_overrides.h:122
SDL_GetError
#define SDL_GetError
Definition: SDL_dynapi_overrides.h:113
SDLTest_CommonState::gl_accelerated
int gl_accelerated
Definition: SDL_test_common.h:108
SDL_GL_CreateContext
#define SDL_GL_CreateContext
Definition: SDL_dynapi_overrides.h:559
GL_VENDOR
#define GL_VENDOR
Definition: SDL_opengl.h:713
GL_PROJECTION
#define GL_PROJECTION
Definition: SDL_opengl.h:272
SDLTest_CommonCreateState
SDLTest_CommonState * SDLTest_CommonCreateState(char **argv, Uint32 flags)
Parse command line parameters and create common state.
Definition: SDL_test_common.c:48
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
state
struct xkb_state * state
Definition: SDL_waylandsym.h:113
SDLTest_CommonArg
int SDLTest_CommonArg(SDLTest_CommonState *state, int index)
Process one common argument.
Definition: SDL_test_common.c:106
context
static screen_context_t context
Definition: video.c:25
SDL_DisplayMode
The structure that defines a display mode.
Definition: SDL_video.h:53
GL_DEPTH_BUFFER_BIT
#define GL_DEPTH_BUFFER_BIT
Definition: SDL_opengl.h:736
SDL_GL_ACCELERATED_VISUAL
Definition: SDL_video.h:197
GL_EXTENSIONS
#define GL_EXTENSIONS
Definition: SDL_opengl.h:716
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:181
GL_VERSION
#define GL_VERSION
Definition: SDL_opengl.h:715
SDL_GL_RED_SIZE
Definition: SDL_video.h:182
SDL_strcasecmp
#define SDL_strcasecmp
Definition: SDL_dynapi_overrides.h:419
SDL_test_common.h
SDLTest_CommonInit
SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
Open test window.
Definition: SDL_test_common.c:726
SDLTest_CommonState::gl_double_buffer
int gl_double_buffer
Definition: SDL_test_common.h:99
SDLTest_CommonState::windows
SDL_Window ** windows
Definition: SDL_test_common.h:78
SDL_LogError
#define SDL_LogError
Definition: SDL_dynapi_overrides.h:36
SDL_opengl.h
SDLTest_CommonState::num_windows
int num_windows
Definition: SDL_test_common.h:77
SDL_GetWindowSize
#define SDL_GetWindowSize
Definition: SDL_dynapi_overrides.h:527
SDLTest_CommonState::window_flags
Uint32 window_flags
Definition: SDL_test_common.h:63
SDL_Log
#define SDL_Log
Definition: SDL_dynapi_overrides.h:31
SDL_GL_GetDrawableSize
#define SDL_GL_GetDrawableSize
Definition: SDL_dynapi_overrides.h:563
SDL_GLContext
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:175
SDL_GL_GetSwapInterval
#define SDL_GL_GetSwapInterval
Definition: SDL_dynapi_overrides.h:565
SDLTest_CommonEvent
void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
Common event handler for test windows.
Definition: SDL_test_common.c:1425
SDLTest_CommonState::gl_multisamplebuffers
int gl_multisamplebuffers
Definition: SDL_test_common.h:105
SDL_GetTicks
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
SDLTest_CommonState::gl_depth_size
int gl_depth_size
Definition: SDL_test_common.h:97
SDL_GL_MULTISAMPLEBUFFERS
Definition: SDL_video.h:195
quit
void quit(int rc)
Definition: teststreaming.c:64
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_GL_SetSwapInterval
#define SDL_GL_SetSwapInterval
Definition: SDL_dynapi_overrides.h:564
done
int done
Definition: checkkeys.c:28
mode
GLenum mode
Definition: SDL_opengl_glext.h:1122
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
SDLTest_CommonState::gl_multisamplesamples
int gl_multisamplesamples
Definition: SDL_test_common.h:106
GL_LESS
#define GL_LESS
Definition: SDL_opengl.h:320
SDL_LOG_PRIORITY_INFO
Definition: SDL_log.h:106
main
int main(int argc, char *argv[])
Definition: testgl2.c:410
SDLTest_CommonUsage
const char * SDLTest_CommonUsage(SDLTest_CommonState *state)
Returns common usage information.
Definition: SDL_test_common.c:478
GL_COLOR_BUFFER_BIT
#define GL_COLOR_BUFFER_BIT
Definition: SDL_opengl.h:742
SDL_GL_DEPTH_SIZE
Definition: SDL_video.h:188
SDLTest_CommonState
Definition: SDL_test_common.h:51
SDLTest_CommonState::gl_green_size
int gl_green_size
Definition: SDL_test_common.h:93
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_LogSetPriority
#define SDL_LogSetPriority
Definition: SDL_dynapi_overrides.h:236
NULL
#define NULL
Definition: begin_code.h:164
GL_MODELVIEW
#define GL_MODELVIEW
Definition: SDL_opengl.h:271
GL_RENDERER
#define GL_RENDERER
Definition: SDL_opengl.h:714
SDLTest_CommonState::gl_blue_size
int gl_blue_size
Definition: SDL_test_common.h:94
SDL_GL_MakeCurrent
#define SDL_GL_MakeCurrent
Definition: SDL_dynapi_overrides.h:560
color
GLuint color
Definition: SDL_opengl_glext.h:1148
SDL_GL_MULTISAMPLESAMPLES
Definition: SDL_video.h:196
SDL_Event
General event structure.
Definition: SDL_events.h:525
GL_DEPTH_TEST
#define GL_DEPTH_TEST
Definition: SDL_opengl.h:327
SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
SDL_GL_GetAttribute
#define SDL_GL_GetAttribute
Definition: SDL_dynapi_overrides.h:558
GL_SMOOTH
#define GL_SMOOTH
Definition: SDL_opengl.h:365
SDL_DisplayMode::format
Uint32 format
Definition: SDL_video.h:55
SDL_GL_DeleteContext
#define SDL_GL_DeleteContext
Definition: SDL_dynapi_overrides.h:567
SDLTest_CommonState::gl_red_size
int gl_red_size
Definition: SDL_test_common.h:92
SDL_GL_GREEN_SIZE
Definition: SDL_video.h:183
SDL_GetCurrentDisplayMode
#define SDL_GetCurrentDisplayMode
Definition: SDL_dynapi_overrides.h:508
SDL_GL_BLUE_SIZE
Definition: SDL_video.h:184
SDL_LOG_CATEGORY_APPLICATION
Definition: SDL_log.h:66
SDL_BITSPERPIXEL
#define SDL_BITSPERPIXEL(X)
Definition: SDL_pixels.h:127
SDL_GL_SwapWindow
#define SDL_GL_SwapWindow
Definition: SDL_dynapi_overrides.h:566
SDLTest_CommonQuit
void SDLTest_CommonQuit(SDLTest_CommonState *state)
Close test window.
Definition: SDL_test_common.c:1751
SDL_INIT_VIDEO
#define SDL_INIT_VIDEO
Definition: SDL.h:78
GL_QUADS
#define GL_QUADS
Definition: SDL_opengl.h:223
SDLTest_CommonState::render_flags
Uint32 render_flags
Definition: SDL_test_common.h:82
ctx
EGLContext ctx
Definition: eglext.h:208