Esempio n. 1
0
int main(int argc, char *argv[])
{

    enum STATE state = STATE_INIT;

    /* initialize graphics */
    SDL_Init(SDL_INIT_EVERYTHING);

    /* prepare opengl core profile */
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);

    SDL_Window *main_window = SDL_CreateWindow("glDrawElements", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, SDL_WINDOW_OPENGL);
    SDL_GLContext context = SDL_GL_CreateContext(main_window);
    glewExperimental=GL_TRUE;
    glewInit();

    printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
    printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
    printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
    printf("GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    /* prepare default framebuffer */
    glClearColor(0,0,1,1);

    /* prepare shaders */
    GLuint vs_shader = glCreateShader(GL_VERTEX_SHADER);
    compile_shader(vs_shader, "glsl/pass.vert");
    GLuint fs_shader = glCreateShader(GL_FRAGMENT_SHADER);
    compile_shader(fs_shader, "glsl/pass.frag");

    GLuint program = glCreateProgram();
    glAttachShader(program, vs_shader);
    glAttachShader(program, fs_shader);
    glLinkProgram(program);
    GLint linkStatus = 0;
    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus );
    if ( linkStatus != GL_TRUE )
    {
        GLint logLength;
        glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLength );
        GLchar *infoLog = calloc(logLength+1, sizeof(char));
        glGetProgramInfoLog( program, logLength, NULL, infoLog );
        fprintf(stderr, "Failed to link shader glProgram: %s\n", infoLog);
        free(infoLog);
        exit(EXIT_FAILURE);
    }
    glUseProgram(program);

    /* prepare geometry */
    GLuint vao = 0;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    /* here, besides the vbo for the vertices, there is an array of indexes that will
       define which vertices compose each geometry face */
    GLuint ibo = 0;
    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW);

    GLuint vbo = 0;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(geometry), geometry, GL_STATIC_DRAW);


    GLuint v_pos = glGetAttribLocation(program, "v_pos");
    glEnableVertexAttribArray(v_pos);
    glVertexAttribPointer(v_pos, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0));

    GLuint color = glGetUniformLocation(program, "color");
    glUniform4f(color, 1.f, 0.f, 0.f, 1.f);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    /* event loop */
    state = STATE_RUNNING;
    while(state == STATE_RUNNING)
    {
        /* process input */
        SDL_Event event;
        while(SDL_PollEvent(&event)) {
            switch(event.type)
            {
                case SDL_QUIT:
                    state = STATE_EXIT;
                    break;
            }
        }

        /* draw */
        glClear(GL_COLOR_BUFFER_BIT);
        /* instead of draw arrays, we use draw elements, and pass the index count for the faces */
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
        SDL_GL_SwapWindow(main_window);
    }

    /* destroy */
    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(main_window);

    return 0;
}
Esempio n. 2
0
int main(int argc, char *argv[]) {
#ifdef RPI
	bcm_host_init();
#endif
	putenv((char*)"SDL_VIDEO_CENTERED=1");

	std::string app_name;
	std::string app_name_nice;
	bool landscape;
	NativeGetAppInfo(&app_name, &app_name_nice, &landscape);

	net::Init();

	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) {
		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
		return 1;
	}

#ifdef __APPLE__
	// Make sure to request a somewhat modern GL context at least - the
	// latest supported by MacOSX (really, really sad...)
	// Requires SDL 2.0
	// We really should upgrade to SDL 2.0 soon.
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#endif

#ifdef USING_EGL
	if (EGL_Open())
		return 1;
#endif

	// Get the video info before doing anything else, so we don't get skewed resolution results.
	// TODO: support multiple displays correctly
	SDL_DisplayMode displayMode;
	int should_be_zero = SDL_GetCurrentDisplayMode(0, &displayMode);
	if (should_be_zero != 0) {
		fprintf(stderr, "Could not get display mode: %s\n", SDL_GetError());
		return 1;
	}
	g_DesktopWidth = displayMode.w;
	g_DesktopHeight = displayMode.h;

	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_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetSwapInterval(1);

	Uint32 mode;
#ifdef USING_GLES2
	mode = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN;
#else
	mode = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
#endif
	int set_xres = -1;
	int set_yres = -1;
	bool portrait = false;
	bool set_ipad = false;
	float set_dpi = 1.0f;
	float set_scale = 1.0f;

	for (int i = 1; i < argc; i++) {
		if (!strcmp(argv[i],"--fullscreen"))
			mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
		if (set_xres == -2) {
			set_xres = parseInt(argv[i]);
		} else if (set_yres == -2) {
			set_yres = parseInt(argv[i]);
		}
		if (set_dpi == -2)
			set_dpi = parseFloat(argv[i]);
		if (set_scale == -2)
			set_scale = parseFloat(argv[i]);

		if (!strcmp(argv[i],"--xres"))
			set_xres = -2;
		if (!strcmp(argv[i],"--yres"))
			set_yres = -2;
		if (!strcmp(argv[i],"--dpi"))
			set_dpi = -2;
		if (!strcmp(argv[i],"--scale"))
			set_scale = -2;
	
		if (!strcmp(argv[i],"--ipad"))
			set_ipad = true;
		if (!strcmp(argv[i],"--portrait"))
			portrait = true;
	}

	// Is resolution is too low to run windowed
	if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) {
		mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
	}

	if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) {
		pixel_xres = g_DesktopWidth;
		pixel_yres = g_DesktopHeight;
#ifdef PPSSPP
		g_Config.bFullScreen = true;
#endif
	} else {
		// set a sensible default resolution (2x)
		pixel_xres = 480 * 2 * set_scale;
		pixel_yres = 272 * 2 * set_scale;
		if (portrait) {
			std::swap(pixel_xres, pixel_yres);
		}
#ifdef PPSSPP
		g_Config.bFullScreen = false;
#endif
	}

	set_dpi = 1.0f / set_dpi;

	if (set_ipad) {
		pixel_xres = 1024;
		pixel_yres = 768;
	}
	if (!landscape) {
		std::swap(pixel_xres, pixel_yres);
	}

	if (set_xres > 0) {
		pixel_xres = set_xres;
	}
	if (set_yres > 0) {
		pixel_yres = set_yres;
	}
	float dpi_scale = 1.0f;
	if (set_dpi > 0) {
		dpi_scale = set_dpi;
	}

	dp_xres = (float)pixel_xres * dpi_scale;
	dp_yres = (float)pixel_yres * dpi_scale;

	g_Screen = SDL_CreateWindow(app_name_nice.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()),\
					SDL_WINDOWPOS_UNDEFINED, pixel_xres, pixel_yres, mode);

	if (g_Screen == NULL) {
		fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
		SDL_Quit();
		return 2;
	}

	SDL_GLContext glContext = SDL_GL_CreateContext(g_Screen);
	if (glContext == NULL) {
		fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
		SDL_Quit();
		return 2;
	}

#ifdef USING_EGL
	EGL_Init();
#endif

#ifdef PPSSPP
	SDL_SetWindowTitle(g_Screen, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str());
#endif

#ifdef MOBILE_DEVICE
	SDL_ShowCursor(SDL_DISABLE);
#endif


#ifndef USING_GLES2
	if (GLEW_OK != glewInit()) {
		printf("Failed to initialize glew!\n");
		return 1;
	}

	if (GLEW_VERSION_2_0) {
		printf("OpenGL 2.0 or higher.\n");
	} else {
		printf("Sorry, this program requires OpenGL 2.0.\n");
		return 1;
	}
#endif

#ifdef _MSC_VER
	// VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
	TCHAR path[MAX_PATH];
	SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
	PathAppend(path, (app_name + "\\").c_str());
#else
	// Mac / Linux
	char path[2048];
	const char *the_path = getenv("HOME");
	if (!the_path) {
		struct passwd* pwd = getpwuid(getuid());
		if (pwd)
			the_path = pwd->pw_dir;
	}
	strcpy(path, the_path);
	if (path[strlen(path)-1] != '/')
		strcat(path, "/");
#endif

#ifdef _WIN32
	NativeInit(argc, (const char **)argv, path, "D:\\", "BADCOFFEE");
#else
	NativeInit(argc, (const char **)argv, path, "/tmp", "BADCOFFEE");
#endif

	pixel_in_dps = (float)pixel_xres / dp_xres;
	g_dpi_scale = dp_xres / (float)pixel_xres;

	printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
	printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);

	NativeInitGraphics();
	NativeResized();

	SDL_AudioSpec fmt, ret_fmt;
	memset(&fmt, 0, sizeof(fmt));
	fmt.freq = 44100;
	fmt.format = AUDIO_S16;
	fmt.channels = 2;
	fmt.samples = 2048;
	fmt.callback = &mixaudio;
	fmt.userdata = (void *)0;

	if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
		ELOG("Failed to open audio: %s", SDL_GetError());
	} else {
		if (ret_fmt.samples != fmt.samples) // Notify, but still use it
			ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
		if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
			ELOG("Sound buffer format does not match requested format.");
			ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
			ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
			ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
			ELOG("Provided output format does not match requirement, turning audio off");
			SDL_CloseAudio();
		}
	}

	// Audio must be unpaused _after_ NativeInit()
	SDL_PauseAudio(0);
#ifndef _WIN32
	joystick = new SDLJoystick();
#endif
	EnableFZ();

	int framecount = 0;
	float t = 0;
	float lastT = 0;
	uint32_t pad_buttons = 0;	 // legacy pad buttons
	while (true) {
		input_state.accelerometer_valid = false;
		input_state.mouse_valid = true;

		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			float mx = event.motion.x * g_dpi_scale;
			float my = event.motion.y * g_dpi_scale;

			switch (event.type) {
			case SDL_QUIT:
				g_QuitRequested = 1;
				break;
#if !defined(MOBILE_DEVICE)
			case SDL_WINDOWEVENT:
			switch (event.window.event) {
				case SDL_WINDOWEVENT_RESIZED:
					{
						Uint32 window_flags = SDL_GetWindowFlags(g_Screen);
						bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN);

						pixel_xres = event.window.data1;
						pixel_yres = event.window.data2;
						dp_xres = (float)pixel_xres * dpi_scale;
						dp_yres = (float)pixel_yres * dpi_scale;
						NativeResized();

#if defined(PPSSPP)
						// Set variable here in case fullscreen was toggled by hotkey
						g_Config.bFullScreen = fullscreen;

						// Hide/Show cursor correctly toggling fullscreen
						if (lastUIState == UISTATE_INGAME && fullscreen && !g_Config.bShowTouchControls) {
								SDL_ShowCursor(SDL_DISABLE);
						} else if (lastUIState != UISTATE_INGAME || !fullscreen) {
								SDL_ShowCursor(SDL_ENABLE);
						}
#endif
						break;
					}
					break;
				}
#endif
			case SDL_KEYDOWN:
				{
					int k = event.key.keysym.sym;
					KeyInput key;
					key.flags = KEY_DOWN;
					key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);

					for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
						if (legacyKeyMap[i] == key.keyCode)
							pad_buttons |= 1 << i;
					}
					break;
				}
			case SDL_KEYUP:
				{
					int k = event.key.keysym.sym;
					KeyInput key;
					key.flags = KEY_UP;
					key.keyCode = KeyMapRawSDLtoNative.find(k)->second;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);
					for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
						if (legacyKeyMap[i] == key.keyCode)
							pad_buttons &= ~(1 << i);
					}
					break;
				}
			case SDL_TEXTINPUT:
				{
					int pos = 0;
					int c = u8_nextchar(event.text.text, &pos);
					KeyInput key;
					key.flags = KEY_CHAR;
					key.keyCode = c;
					key.deviceId = DEVICE_ID_KEYBOARD;
					NativeKey(key);
					break;
				}
			case SDL_MOUSEBUTTONDOWN:
				switch (event.button.button) {
				case SDL_BUTTON_LEFT:
					{
						input_state.pointer_x[0] = mx;
						input_state.pointer_y[0] = my;
						input_state.pointer_down[0] = true;
						input_state.mouse_valid = true;
						TouchInput input;
						input.x = mx;
						input.y = my;
						input.flags = TOUCH_DOWN | TOUCH_MOUSE;
						input.id = 0;
						NativeTouch(input);
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_DOWN);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_RIGHT:
					{
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_DOWN);
						NativeKey(key);
					}
					break;
				}
				break;
			case SDL_MOUSEWHEEL:
				{
					KeyInput key;
					key.deviceId = DEVICE_ID_MOUSE;
					if (event.wheel.y > 0) {
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
					} else {
						key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
					}
					key.flags = KEY_DOWN;
					NativeKey(key);

					// SDL2 doesn't consider the mousewheel a button anymore
					// so let's send the KEY_UP right away.
					// Maybe KEY_UP alone will suffice?
					key.flags = KEY_UP;
					NativeKey(key);
				}
			case SDL_MOUSEMOTION:
				if (input_state.pointer_down[0]) {
					input_state.pointer_x[0] = mx;
					input_state.pointer_y[0] = my;
					input_state.mouse_valid = true;
					TouchInput input;
					input.x = mx;
					input.y = my;
					input.flags = TOUCH_MOVE | TOUCH_MOUSE;
					input.id = 0;
					NativeTouch(input);
				}
				break;
			case SDL_MOUSEBUTTONUP:
				switch (event.button.button) {
				case SDL_BUTTON_LEFT:
					{
						input_state.pointer_x[0] = mx;
						input_state.pointer_y[0] = my;
						input_state.pointer_down[0] = false;
						input_state.mouse_valid = true;
						//input_state.mouse_buttons_up = 1;
						TouchInput input;
						input.x = mx;
						input.y = my;
						input.flags = TOUCH_UP | TOUCH_MOUSE;
						input.id = 0;
						NativeTouch(input);
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_1, KEY_UP);
						NativeKey(key);
					}
					break;
				case SDL_BUTTON_RIGHT:
					{
						KeyInput key(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_2, KEY_UP);
						NativeKey(key);
					}
					break;
				}
				break;
			default:
#ifndef _WIN32
				joystick->ProcessInput(event);
#endif
				break;
			}
		}
		if (g_QuitRequested)
			break;
		const uint8 *keys = SDL_GetKeyboardState(NULL);
		SimulateGamepad(keys, &input_state);
		input_state.pad_buttons = pad_buttons;
		UpdateInputState(&input_state, true);
#ifdef PPSSPP
		UpdateRunLoop();
#else
		NativeUpdate(input_state);
		NativeRender();
#endif
		if (g_QuitRequested)
			break;
#if defined(PPSSPP) && !defined(MOBILE_DEVICE)
		if (lastUIState != GetUIState()) {
			lastUIState = GetUIState();
			if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !g_Config.bShowTouchControls)
				SDL_ShowCursor(SDL_DISABLE);
			if (lastUIState != UISTATE_INGAME && g_Config.bFullScreen)
				SDL_ShowCursor(SDL_ENABLE);
		}
#endif

		if (framecount % 60 == 0) {
			// glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
		}

#ifdef USING_EGL
		eglSwapBuffers(g_eglDisplay, g_eglSurface);
#else
		if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0)
		{
			SDL_GL_SwapWindow(g_Screen);
			lastT = t;
		}
#endif

		ToggleFullScreenIfFlagSet();
		time_update();
		t = time_now();
		framecount++;
	}
#ifndef _WIN32
	delete joystick;
#endif
	// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
	// The speed difference is only really noticable on Linux. On Windows you do notice it though
#ifndef MOBILE_DEVICE
	exit(0);
#endif
	NativeShutdownGraphics();
	SDL_PauseAudio(1);
	SDL_CloseAudio();
	NativeShutdown();
#ifdef USING_EGL
	EGL_Close();
#endif
	SDL_GL_DeleteContext(glContext);
	SDL_Quit();
	net::Shutdown();
#ifdef RPI
	bcm_host_deinit();
#endif

	exit(0);
	return 0;
}
Esempio n. 3
0
int main()
{
    WORKING_DIR=SDL_GetBasePath();
    WORKING_DIR=WORKING_DIR.substr(0,WORKING_DIR.find_last_of("/\\"));
    WORKING_DIR=WORKING_DIR.substr(0,WORKING_DIR.find_last_of("/\\"));
    WORKING_DIR=WORKING_DIR.substr(0,WORKING_DIR.find_last_of("/\\"));
#ifdef __gnu_linux__
    WORKING_DIR+="/";
#elif __WIN32
    WORKING_DIR+="\\";
#endif
    std::cout<< WORKING_DIR<<std::endl;

    SDL_Window *mainwindow; /* Our window handle */
    SDL_GLContext maincontext; /* Our opengl context handle */
    Mix_Chunk *pong = NULL;
    Mix_Chunk *pong2 = NULL;
    Mix_Chunk *pong3 = NULL;
    if( SDL_Init( SDL_INIT_VIDEO| SDL_INIT_AUDIO ) < 0 )
    {
        sdldie("SDL could not initialize! SDL Error: %s\n");
    }
    else
    {
        //Use OpenGL 3.3 core
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );

        //Create window
        mainwindow = SDL_CreateWindow( "pong", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenWidth, screenHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN |SDL_WINDOW_RESIZABLE );
        if( mainwindow == NULL )
        {
            sdldie("Unable to create window");
        }
        else
        {
            //Create context
            maincontext = SDL_GL_CreateContext( mainwindow );
            if( maincontext == NULL ){
                sdldie("OpenGL context could not be created! SDL Error: %s\n");
            }
            else
            {
                //Initialize GLEW
                glewExperimental = GL_TRUE;
                GLenum glewError = glewInit();
                if( glewError != GLEW_OK )
                {
                    std::cout<<"Error initializing GLEW! %s\n"<<glewGetErrorString( glewError );
                }

                //Use Vsync
                if( SDL_GL_SetSwapInterval( 1 ) < 0 )
                {
                    std::cout<<"Warning: Unable to set VSync! SDL Error: %s\n"<<SDL_GetError();
                }
                SDL_DisplayMode current;
                int should_be_zero = SDL_GetCurrentDisplayMode(0, &current); //@HACK:should check for multiple monitors
                if(should_be_zero != 0)
                  sdldie("Could not get display mode for video display");
                screenWidth=(3.0f/4.0f)*current.w;
                screenHeight=(3.0f/4.0f)*current.h;
                (*(int*)(&originalScreenHeight))=screenHeight;
                (*(int*)(&originalScreenWidth))=screenWidth;
            }
        }
    }
    //Initialize SDL_mixer
    if( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 2048 ) < 0 ) {
        std::cout<<"SDL_mixer could not initialize! SDL_mixer Error: "<<Mix_GetError();
        return 1;
    }
     //Load sound effects
    pong = Mix_LoadWAV(WORKING_DIR_FILE("assets/sounds/pong.wav"));
    if( pong == NULL ) {
        std::cout<< "Failed to load scratch sound effect! SDL_mixer Error: "<<Mix_GetError();
        return 1;
    }
    pong2 = Mix_LoadWAV(WORKING_DIR_FILE("assets/sounds/pong2.wav"));
    if( pong2 == NULL ) {
        std::cout<< "Failed to load scratch sound effect! SDL_mixer Error: "<<Mix_GetError();
        return 1;
    }
    pong3 = Mix_LoadWAV(WORKING_DIR_FILE("assets/sounds/pong3.wav"));
    if( pong3 == NULL ) {
        std::cout<< "Failed to load scratch sound effect! SDL_mixer Error: "<<Mix_GetError();
        return 1;
    }

    glEnable(GL_DEPTH_TEST);
    glViewport(0, 0, screenWidth, screenHeight);

    /* Clear our buffer with a red background */
    glClearColor ( 1.0, 0.0, 0.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );
    /* Swap our back buffer to the front */
    SDL_GL_SwapWindow(mainwindow);
    /* Wait 2 seconds */
    SDL_Delay(100);

    /* Same as above, but green */
    glClearColor ( 0.0, 1.0, 0.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );
    SDL_GL_SwapWindow(mainwindow);
    SDL_Delay(100);

    /* Same as above, but blue */
    glClearColor ( 0.0, 0.0, 1.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );
    SDL_GL_SwapWindow(mainwindow);
    SDL_Delay(100);


    GLfloat vertices[] = {
         0.5f,  0.5f, 0.0f,  // Top Right
         0.5f, -0.5f, 0.0f,  // Bottom Right
        -0.5f, -0.5f, 0.0f,  // Bottom Left
        -0.5f,  0.5f, 0.0f,   // Top Left
    };
    GLuint indices[] = {  // Note that we start from 0!
        0, 1, 3,  // First Triangle
        1, 2, 3   // Second Triangle
    };

    std::vector<Vertex> vertices2;
    std::vector<GLuint> indices2;
    {
        for(unsigned int i=0;i<(sizeof(vertices)/sizeof(vertices[0]));i+=3){
            Vertex aux;
            aux.position={vertices[i+0],vertices[i+1],vertices[i+2]};
            vertices2.push_back(aux);
        }
        for(unsigned int i=0;i<(sizeof(indices)/sizeof(indices[0]));i++){
            indices2.push_back(indices[i]);
        }

    }
    Sprite sprite(vertices2,indices2);

    GLfloat quadVertices[] = {   // Vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
        // Positions   // TexCoords
        -1.0f,  1.0f,  0.0f, 1.0f,
        -1.0f, -1.0f,  0.0f, 0.0f,
         1.0f, -1.0f,  1.0f, 0.0f,

        -1.0f,  1.0f,  0.0f, 1.0f,
         1.0f, -1.0f,  1.0f, 0.0f,
         1.0f,  1.0f,  1.0f, 1.0f
    };

    // Setup cube VAO
    GLuint quadVAO, quadVBO;
    glGenVertexArrays(1, &quadVAO);
    glGenBuffers(1, &quadVBO);
    glBindVertexArray(quadVAO);
        glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
            glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
            glEnableVertexAttribArray(1);
            glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat)));
    glBindVertexArray(0);


    unsigned int points_p1=0,points_p2=0;
    bool first_point_p1=true,first_point_p2=true;

    GameObject player1(&sprite,{0.0f,2.0f});
    GameObject player2(&sprite,{0.0f,2.0f});
    GameObject ball(&sprite,{0.0f,0.0f});
    Entity roof(&sprite);
    Entity floor(&sprite);
    GameObject leftwall(&sprite,{0.0f,0.0f});
    GameObject rightwall(&sprite,{0.0f,0.0f});
    {
        player1.entity.setPos({-0.95f,0.0f});
        player2.entity.setPos({0.95f,0.0f});
        ball.entity.setPos({0.0f,8.0f});

        roof.setPos({-1.0f,1.10f});
        floor.setPos({-1.0f,-1.10f});
        roof.scale({4.0f,1.0f});
        floor.scale({4.0f,1.0f});

        leftwall.entity.setPos({-1.0f,0.0f});
        rightwall.entity.setPos({1.0f,0.0f});
        leftwall.entity.scale({0.025f,2.0f});
        rightwall.entity.scale({0.025f,2.0f});

        player1.entity.scale({0.025f, 0.49f});
        player2.entity.scale({0.025f, 0.49f});
        ball.entity.scale({0.0625f,0.0625f});
        ball.entity.order(SCALE,ROTATE,TRANSLATE);


    }

    std::vector<CollisionChecker> collisions;
    {
        collisions.push_back(CollisionChecker(&player1.entity,&roof));
        collisions.push_back(CollisionChecker(&player1.entity,&floor));
        collisions.push_back(CollisionChecker(&player2.entity,&roof));
        collisions.push_back(CollisionChecker(&player2.entity,&floor));
    }


    CollisionChecker ball_floor(&ball.entity,&floor);
    CollisionChecker ball_roof(&ball.entity,&roof);
    CollisionChecker ball_p1(&ball.entity,&player1.entity);
    CollisionChecker ball_p2(&ball.entity,&player2.entity);
    CollisionChecker ball_leftwall(&ball.entity,&leftwall.entity);
    CollisionChecker ball_rightwall(&ball.entity,&rightwall.entity);

    SDL_StartTextInput();
    bool quit = false;
    bool started=false;
    glm::vec2 p1_speed_gain(0.0f,0.0f);
    glm::vec2 p2_speed_gain(0.0f,0.0f);
    unsigned int i=0;
    Uint32 lastFrame=0;
    Uint32 deltaTime=0;
    float framerate=0.0f;
    float dt;


    framebuffer fb(originalScreenWidth,originalScreenHeight);
    Shader shader(WORKING_DIR_FILE("assets/shaders/shader.vert"),WORKING_DIR_FILE("assets/shaders/shader.frag"));
    Shader fb_shader(WORKING_DIR_FILE("assets/shaders/framebuffer_shader.vert"),WORKING_DIR_FILE("assets/shaders/framebuffer_shader.frag"));
    while(!quit)
    {
        SDL_PumpEvents();
        Uint32 currentFrame =            SDL_GetTicks();//miliseconds
        deltaTime           =  currentFrame - lastFrame;
        lastFrame           =              currentFrame;
        dt                  =         deltaTime/1000.0f;
        framerate          +=         1000.0f/deltaTime;

        p1_speed_gain={0.0f,0.0f};
        p2_speed_gain={0.0f,0.0f};
        {
            const Uint8 *keystates =                                     SDL_GetKeyboardState( NULL );
            quit                   = keystates[SDL_GetScancodeFromKey(SDLK_q)] || SDL_QuitRequested();
            started                =         started || keystates[SDL_GetScancodeFromKey(SDLK_SPACE)];
            if(started){
                if(keystates[SDL_GetScancodeFromKey(SDLK_w   )])
                {
                    player1.move( dt );
                    p1_speed_gain={ 0.0f , 1.0f };
                }
                if(keystates[SDL_GetScancodeFromKey(SDLK_s   )])
                {
                    player1.move(-dt );
                    p1_speed_gain={ 0.0f ,-1.0f };
                }
                if(keystates[SDL_GetScancodeFromKey(SDLK_UP  )])
                {
                    player2.move( dt );
                    p2_speed_gain={ 0.0f , 1.0f };
                }
                if(keystates[SDL_GetScancodeFromKey(SDLK_DOWN)])
                {
                    player2.move(-dt );
                    p2_speed_gain={ 0.0f ,-1.0f };
                }
                if(keystates[SDL_GetScancodeFromKey(SDLK_j)])
                {
                    player1.entity.rotate(15.0f );
                }

                do_ball_movement(ball,dt);
            }

        }
        {
            unsigned int size=collisions.size();
            for(unsigned int i=0;i<size;i++)
            {
                if(collisions[i].checkCollision())
                    handleCollision(collisions[i]);
            }
        }
        {
            glm::vec3 pos=ball.entity.position;
            glm::vec3 oldpos=ball.entity.oldPosition;
            if(ball_floor.checkCollision()){
                handleCollision(ball_floor);
                ball.speed=glm::normalize(glm::reflect(glm::vec2(pos.x-oldpos.x,pos.y-oldpos.y),glm::vec2(0.0f,1.0f)))*glm::length(ball.speed);
                Mix_PlayChannel( -1, pong2, 0 );
            }
            if(ball_roof.checkCollision()){
                handleCollision(ball_roof);
                ball.speed=glm::normalize(glm::reflect(glm::vec2(pos.x-oldpos.x,pos.y-oldpos.y),glm::vec2(0.0f,-1.0f)))*glm::length(ball.speed);
                Mix_PlayChannel( -1, pong2, 0 );
            }
            if(ball_p1.checkCollision()){
                handleCollision(ball_p1);
                ball.speed=glm::normalize(glm::reflect(glm::vec2(pos.x-oldpos.x,pos.y-oldpos.y),glm::vec2(1.0f,0.0f)) + p1_speed_gain)
                        *
                        (glm::length(ball.speed)+glm::length(p1_speed_gain));
                Mix_PlayChannel( -1, pong, 0 );
            }
            if(ball_p2.checkCollision()){
                handleCollision(ball_p2);
                ball.speed=glm::normalize(glm::reflect(glm::vec2(pos.x-oldpos.x,pos.y-oldpos.y),glm::vec2(-1.0f,0.0f)) + p2_speed_gain)
                        *
                        (glm::length(ball.speed)+glm::length(p2_speed_gain));
                Mix_PlayChannel( -1, pong, 0 );
            }

            if(ball_leftwall.checkCollision()){
                points_p2++;
                ball.entity.setPos({0.0f,8.0f});//scale adjusted due the order it uses...
                ball.speed={0.0f,0.0f};
                Mix_PlayChannel( -1, pong3, 0 );
            }
            if(ball_rightwall.checkCollision()){
                points_p1++;
                ball.entity.setPos({0.0f,8.0f});
                ball.speed={0.0f,0.0f};
                Mix_PlayChannel( -1, pong3, 0 );
            }
            if(((ball.speed.y/ball.speed.x)>3.0f) || ((ball.speed.y/ball.speed.x)<-3.0f)){
                ball.speed.y/=2.0f;
                ball.speed.x*=4.0f;
            }
        }
        if(i==100){
            i=0;
            framerate/=100.0f;
            std::cout<<framerate<<std::endl;
            std::cout<<points_p1<<'-'<<points_p2<<std::endl;
            framerate=0.0f;
        }
        i+=1;
        shader.Use();
            fb.bind();
                glViewport(0,0,originalScreenWidth,originalScreenHeight);
                glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                glEnable(GL_DEPTH_TEST);
                glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

                glm::mat4 projection;//= glm::ortho(-1.0f,1.0f,-1.0f,1.0f,0.0f,1.0f);
                GLint projection_uniform=glGetUniformLocation(shader.Program, "projection");
                glUniformMatrix4fv(projection_uniform, 1, GL_FALSE, glm::value_ptr(projection));


                glm::vec2 position;
                position=glm::vec2(-3.0f*1.06255f*0.125f,0.0f);
                if(points_p1>=5 || points_p2>=5){
                    drawdigit(-1,&shader,position,{0.125f,0.125f},DIGIT_TOP|DIGIT_MIDDLE|DIGIT_TOPLEFT|DIGIT_TOPRIGHT|DIGIT_BOTTOMLEFT);
                    position+=glm::vec2(1.0625f*0.125f,0.0f);
                    drawdigit((points_p1>=5)?1:2,&shader,position,{0.125f,0.125f});
                    position+=glm::vec2(1.0625f*0.125f,0.0f);
                    position+=glm::vec2(1.0625f*0.125f,0.0f);
                    drawdigit(-1,&shader,position,{0.125f,0.125f},DIGIT_TOPLEFT |DIGIT_BOTTOMLEFT |DIGIT_BOTTOMLEFT_MIDDLE|
                                                                  DIGIT_TOPRIGHT|DIGIT_BOTTOMRIGHT|DIGIT_BOTTOMRIGHT_MIDDLE);
                    position+=glm::vec2(1.0625f*0.125f,0.0f);
                    drawdigit(-1,&shader,position,{0.125f,0.125f},DIGIT_TOPMIDDLE|DIGIT_BOTTOMMIDDLE);
                    position+=glm::vec2(1.0625f*0.125f,0.0f);
                    drawdigit(-1,&shader,position,{0.125f,0.125f},DIGIT_BOTTOMLEFT |DIGIT_TOPLEFT|DIGIT_TOPLEFT_BOTTOMRIGHT|
                                                                  DIGIT_BOTTOMRIGHT|DIGIT_TOPRIGHT);
                    position+=glm::vec2(1.0625f*0.125f,0.0f);
                    drawdigit(5,&shader,position,{0.125f,0.125f});
                    started=false;
                }

                player1.entity.draw(&shader);
                player2.entity.draw(&shader);
                if(started) ball.entity.draw(&shader);
                roof.draw(&shader);
                floor.draw(&shader);
                leftwall.entity.draw(&shader);
                rightwall.entity.draw(&shader);




                unsigned int aux=points_p2;
                position=glm::vec2(0.25f,0.5f);
                //NOTE: when one of the points hits 20 I should put a you win screen
                first_point_p2=points_p2? false:true;
                while((aux/10) || (aux%10) || first_point_p2){
                    drawdigit(aux%10,&shader,position,{0.125f,0.125f});
                    position.x-=1.5f*0.125f;
                    aux=aux/10;
                    first_point_p2=false;//endless loop if I dont
                }

                aux=points_p1;
                position={-0.25f,0.5f};
                first_point_p1=points_p1? false:true;
                while((aux/10) || (aux%10) || first_point_p1){
                    drawdigit(aux%10,&shader,position,{0.125f,0.125f});
                    position.x-=1.5f*0.125f;
                    aux=aux/10;
                    first_point_p1=false;
                }


            fb.unbind();
        SDL_GetWindowSize(mainwindow,&screenWidth,&screenHeight);
        glViewport(0,0,screenWidth,screenHeight);
        glClearColor(0.0f, 0.0f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDisable(GL_DEPTH_TEST);
        fb_shader.Use();
            glm::mat4 screenscaler;
            float aspectRatio=(float)screenWidth/(float)screenHeight;
            float inverseAspectRatio=(float)screenHeight/(float)screenWidth;
            if(aspectRatio>1.0f)
            screenscaler = glm::perspective(radians(59.2f),aspectRatio,0.1f,1.0f);
            else
            screenscaler = glm::perspective(radians(59.2f),inverseAspectRatio,0.1f,1.0f);
            GLint model_uniform=glGetUniformLocation(fb_shader.Program, "model");
            glUniformMatrix4fv(model_uniform, 1, GL_FALSE, glm::value_ptr(screenscaler));

            glBindVertexArray(quadVAO);//should scale the scale to the % of resolution
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, fb.texture);
                glDrawArrays(GL_TRIANGLES, 0, 6);
            glBindTexture(GL_TEXTURE_2D,0);
            glBindVertexArray(0);


        SDL_Delay(1);
        SDL_GL_SwapWindow(mainwindow);
        if(points_p1>=5 || points_p2>=5){
            points_p1=0;
            points_p2=0;
            ball.speed={0.0f,0.0f};
            SDL_Delay(3000);
        }
    }
    DESTRUCTOR(fb);
    DESTRUCTOR(shader);
    DESTRUCTOR(fb_shader);
    Mix_FreeChunk(pong);
    Mix_FreeChunk(pong2);
    Mix_FreeChunk(pong3);
    SDL_GL_DeleteContext(maincontext);
    SDL_DestroyWindow(mainwindow);
    SDL_Quit();

    return 0;
}
Esempio n. 4
0
bool Sdl2Application::tryCreateContext(const Configuration& configuration) {
    CORRADE_ASSERT(!_glContext, "Platform::Sdl2Application::tryCreateContext(): context already created", false);

    /* Enable double buffering and 24bt depth buffer */
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    /* Multisampling */
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, configuration.sampleCount() > 1 ? 1 : 0);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, configuration.sampleCount());

    #ifndef CORRADE_TARGET_EMSCRIPTEN
    /* Context flags */
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(configuration.flags()));
    #endif

    /* Flags: if not hidden, set as shown */
    Uint32 windowFlags(configuration.windowFlags());
    if(!(configuration.windowFlags() & Configuration::WindowFlag::Hidden))
        windowFlags |= SDL_WINDOW_SHOWN;

    /** @todo Remove when Emscripten has proper SDL2 support */
    #ifndef CORRADE_TARGET_EMSCRIPTEN
    /* Set context version, if user-specified */
    if(configuration.version() != Version::None) {
        Int major, minor;
        std::tie(major, minor) = version(configuration.version());
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);

        #ifndef MAGNUM_TARGET_GLES
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, configuration.version() >= Version::GL310 ?
            SDL_GL_CONTEXT_PROFILE_CORE : SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
        #else
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
        #endif

    /* Request usable version otherwise */
    } else {
        #ifndef MAGNUM_TARGET_GLES
        /* First try to create core context. This is needed mainly on OS X and
           Mesa, as support for recent OpenGL versions isn't implemented in
           compatibility contexts (which are the default). At least GL 3.2 is
           needed on OSX, at least GL 3.1 is needed on Mesa. Bite the bullet
           and try 3.1 also elsewhere. */
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
        #ifdef CORRADE_TARGET_APPLE
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
        #else
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
        #endif
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
        #else
        /* For ES the major context version is compile-time constant */
        #ifdef MAGNUM_TARGET_GLES3
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
        #elif defined(MAGNUM_TARGET_GLES2)
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
        #else
        #error unsupported OpenGL ES version
        #endif
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
        #endif
    }

    /* Create window */
    if(!(_window = SDL_CreateWindow(configuration.title().data(),
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        configuration.size().x(), configuration.size().y(),
        SDL_WINDOW_OPENGL|windowFlags)))
    {
        Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError();
        return false;
    }

    /* Create context */
    _glContext = SDL_GL_CreateContext(_window);

    #ifndef MAGNUM_TARGET_GLES
    /* Fall back to (forward compatible) GL 2.1, if version is not
       user-specified and either core context creation fails or we are on
       binary NVidia drivers on Linux/Windows. NVidia, instead of creating
       forward-compatible context with highest available version, forces the
       version to the one specified, which is completely useless behavior. */
    constexpr static const char nvidiaVendorString[] = "NVIDIA Corporation";
    if(configuration.version() == Version::None && (!_glContext
        #ifndef CORRADE_TARGET_APPLE
        || std::strncmp(reinterpret_cast<const char*>(glGetString(GL_VENDOR)), nvidiaVendorString, sizeof(nvidiaVendorString)) == 0
        #endif
    )) {
        /* Don't print any warning when doing the NV workaround, because the
           bug will be there probably forever */
        if(!_glContext) Warning()
            << "Platform::Sdl2Application::tryCreateContext(): cannot create core context:"
            << SDL_GetError() << "(falling back to compatibility context)";
        else SDL_GL_DeleteContext(_glContext);

        SDL_DestroyWindow(_window);

        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);

        if(!(_window = SDL_CreateWindow(configuration.title().data(),
            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
            configuration.size().x(), configuration.size().y(),
            SDL_WINDOW_OPENGL|windowFlags)))
        {
            Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError();
            return false;
        }

        /* Create compatibility context */
        _glContext = SDL_GL_CreateContext(_window);
    }
    #endif

    /* Cannot create context (or fallback compatibility context on desktop) */
    if(!_glContext) {
        Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create context:" << SDL_GetError();
        SDL_DestroyWindow(_window);
        _window = nullptr;
        return false;
    }

    #else
    /* Emscripten-specific initialization */
    _glContext = SDL_SetVideoMode(configuration.size().x(), configuration.size().y(), 24, SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF);
    #endif

    /* Return true if the initialization succeeds */
    return !!(_context = Platform::Context::tryCreate());
}
Esempio n. 5
0
SDLWindow::~SDLWindow(){
  SDL_GL_DeleteContext(this->_context);
  SDL_Quit();
}
Esempio n. 6
0
int main(int argc, char* argv[])
{
	printf("press 'z' to toggle microprofile drawing\n");
	printf("press 'right shift' to pause microprofile update\n");
	printf("press 'x' to toggle profiling\n");
	printf("press 'c' to toggle enable of all profiler groups\n");
	MicroProfileOnThreadCreate("Main");

	if(SDL_Init(SDL_INIT_VIDEO) < 0) {
		return 1;
	}


	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_DEPTH_SIZE,  	    24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,  	    8);	
	SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,		    32);	
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,	    1);	
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	SDL_GL_SetSwapInterval(1);

	SDL_Window * pWindow = SDL_CreateWindow("microprofiledemo", 10, 10, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
	if(!pWindow)
		return 1;

	SDL_GLContext glcontext = SDL_GL_CreateContext(pWindow);

	glewExperimental=1;
	GLenum err=glewInit();
	if(err!=GLEW_OK)
	{
		__BREAK();
	}
	glGetError(); //glew generates an error
		


#if MICROPROFILE_ENABLED
	MicroProfileQueryInitGL();
	MicroProfileDrawInit();
	MP_ASSERT(glGetError() == 0);
#endif

	StartFakeWork();
	while(!g_nQuit)
	{
		MICROPROFILE_SCOPE(MAIN);

		SDL_Event Evt;
		while(SDL_PollEvent(&Evt))
		{
			HandleEvent(&Evt);
		}

		glClearColor(0.3f,0.4f,0.6f,0.f);
		glViewport(0, 0, WIDTH, HEIGHT);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


#if 1||FAKE_WORK
		{
			MICROPROFILE_SCOPEI("Main", "Dummy", 0xff3399ff);
			for(uint32_t i = 0; i < 14; ++i)
			{
				MICROPROFILE_SCOPEI("Main", "1ms", 0xff3399ff);
				MICROPROFILE_META_CPU("Sleep",1);

				usleep(1000);
			}
		}
#endif




		MicroProfileMouseButton(g_MouseDown0, g_MouseDown1);
		MicroProfileMousePosition(g_MouseX, g_MouseY, g_MouseDelta);
		g_MouseDelta = 0;


		MicroProfileFlip();
		{
			MICROPROFILE_SCOPEGPUI("GPU", "MicroProfileDraw", 0x88dd44);
			float projection[16];
			float left = 0.f;
			float right = WIDTH;
			float bottom = HEIGHT;
			float top = 0.f;
			float near = -1.f;
			float far = 1.f;
			memset(&projection[0], 0, sizeof(projection));

			projection[0] = 2.0f / (right - left);
			projection[5] = 2.0f / (top - bottom);
			projection[10] = -2.0f / (far - near);
			projection[12] = - (right + left) / (right - left);
			projection[13] = - (top + bottom) / (top - bottom);
			projection[14] = - (far + near) / (far - near);
			projection[15] = 1.f; 
 
 			glEnable(GL_BLEND);
 			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 			glDisable(GL_DEPTH_TEST);
#if MICROPROFILE_ENABLED
			MicroProfileBeginDraw(WIDTH, HEIGHT, &projection[0]);
			MicroProfileDraw(WIDTH, HEIGHT);
			MicroProfileEndDraw();
#endif
			glDisable(GL_BLEND);
		}

		MICROPROFILE_SCOPEI("MAIN", "Flip", 0xffee00);
		SDL_GL_SwapWindow(pWindow);
	}
	StopFakeWork();

	MicroProfileShutdown();

  	SDL_GL_DeleteContext(glcontext);  
 	SDL_DestroyWindow(pWindow);
 	SDL_Quit();


	return 0;
}
Esempio n. 7
0
int rgssThreadFun(void *userdata)
{
	RGSSThreadData *threadData = static_cast<RGSSThreadData*>(userdata);
	SDL_Window *win = threadData->window;
	SDL_GLContext glCtx;

	/* Setup GL context */
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	if (threadData->config.debugMode)
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);

	glCtx = SDL_GL_CreateContext(win);

	if (!glCtx)
	{
		rgssThreadError(threadData, std::string("Error creating context: ") + SDL_GetError());
		return 0;
	}

	try
	{
		initGLFunctions();
	}
	catch (const Exception &exc)
	{
		rgssThreadError(threadData, exc.msg);
		SDL_GL_DeleteContext(glCtx);

		return 0;
	}

	gl.ClearColor(0, 0, 0, 1);
	gl.Clear(GL_COLOR_BUFFER_BIT);
	SDL_GL_SwapWindow(win);

	printGLInfo();

	SDL_GL_SetSwapInterval(threadData->config.vsync ? 1 : 0);

	DebugLogger dLogger;

	/* Setup AL context */
	ALCdevice *alcDev = alcOpenDevice(0);

	if (!alcDev)
	{
		rgssThreadError(threadData, "Error opening OpenAL device");
		SDL_GL_DeleteContext(glCtx);

		return 0;
	}

	ALCcontext *alcCtx = alcCreateContext(alcDev, 0);

	if (!alcCtx)
	{
		rgssThreadError(threadData, "Error creating OpenAL context");
		alcCloseDevice(alcDev);
		SDL_GL_DeleteContext(glCtx);

		return 0;
	}

	alcMakeContextCurrent(alcCtx);

	try
	{
		SharedState::initInstance(threadData);
	}
	catch (const Exception &exc)
	{
		rgssThreadError(threadData, exc.msg);
		alcDestroyContext(alcCtx);
		alcCloseDevice(alcDev);
		SDL_GL_DeleteContext(glCtx);

		return 0;
	}

	/* Start script execution */
	scriptBinding->execute();

	threadData->rqTermAck.set();
	threadData->ethread->requestTerminate();

	SharedState::finiInstance();

	alcDestroyContext(alcCtx);
	alcCloseDevice(alcDev);

	SDL_GL_DeleteContext(glCtx);

	return 0;
}
Esempio n. 8
0
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode( int mode, qboolean fullscreen, qboolean noborder )
{
	const char  *glstring;
	int         perChannelColorBits;
	int         alphaBits, depthBits, stencilBits;
	int         samples;
	int         i = 0;
	SDL_Surface *icon = NULL;
	SDL_DisplayMode desktopMode;
	Uint32      flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
	int         x, y;
	GLenum      glewResult;

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" );

	if ( r_allowResize->integer )
	{
		flags |= SDL_WINDOW_RESIZABLE;
	}

	if ( r_centerWindow->integer )
	{
		// center window on specified display
		x = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer );
		y = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer );
	}
	else
	{
		x = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer );
		y = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer );
	}

	icon = SDL_CreateRGBSurfaceFrom( ( void * ) CLIENT_WINDOW_ICON.pixel_data,
			        CLIENT_WINDOW_ICON.width,
			        CLIENT_WINDOW_ICON.height,
			        CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
			        CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
			        0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
			        0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
					);

	if ( SDL_GetDesktopDisplayMode( r_displayIndex->integer, &desktopMode ) == 0 )
	{
		displayAspect = ( float ) desktopMode.w / ( float ) desktopMode.h;

		ri.Printf( PRINT_ALL, "Display aspect: %.3f\n", displayAspect );
	}
	else
	{
		Com_Memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) );

		ri.Printf( PRINT_ALL, "Cannot determine display aspect (%s), assuming 1.333\n", SDL_GetError() );
	}

	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );

	if ( mode == -2 )
	{
		// use desktop video resolution
		if ( desktopMode.h > 0 )
		{
			glConfig.vidWidth = desktopMode.w;
			glConfig.vidHeight = desktopMode.h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			ri.Printf( PRINT_ALL, "Cannot determine display resolution, assuming 640x480\n" );
		}

		glConfig.windowAspect = ( float ) glConfig.vidWidth / ( float ) glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}

	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );

	do
	{
		if ( glContext != NULL )
		{
			SDL_GL_DeleteContext( glContext );
			glContext = NULL;
		}

		if ( window != NULL )
		{
			SDL_GetWindowPosition( window, &x, &y );
			ri.Printf( PRINT_DEVELOPER, "Existing window at %dx%d before being destroyed\n", x, y );
			SDL_DestroyWindow( window );
			window = NULL;
		}
		// we come back here if we couldn't get a visual and there's
		// something we can switch off

		if ( fullscreen )
		{
			flags |= SDL_WINDOW_FULLSCREEN;
			glConfig.isFullscreen = qtrue;
		}
		else
		{
			if ( noborder )
			{
				flags |= SDL_WINDOW_BORDERLESS;
			}

			glConfig.isFullscreen = qfalse;
		}

		colorBits = r_colorbits->integer;

		if ( ( !colorBits ) || ( colorBits >= 32 ) )
		{
			colorBits = 24;
		}

		alphaBits = r_alphabits->integer;

		if ( alphaBits < 0 )
		{
			alphaBits = 0;
		}

		depthBits = r_depthbits->integer;

		if ( !depthBits )
		{
			depthBits = 24;
		}

		stencilBits = r_stencilbits->integer;
		samples = r_ext_multisample->integer;

		for ( i = 0; i < 16; i++ )
		{
			int testColorBits, testDepthBits, testStencilBits;

			// 0 - default
			// 1 - minus colorbits
			// 2 - minus depthbits
			// 3 - minus stencil
			if ( ( i % 4 ) == 0 && i )
			{
				// one pass, reduce
				switch ( i / 4 )
				{
					case 2:
						if ( colorBits == 24 )
						{
							colorBits = 16;
						}

						break;

					case 1:
						if ( depthBits == 24 )
						{
							depthBits = 16;
						}
						else if ( depthBits == 16 )
						{
							depthBits = 8;
						}

					case 3:
						if ( stencilBits == 24 )
						{
							stencilBits = 16;
						}
						else if ( stencilBits == 16 )
						{
							stencilBits = 8;
						}
				}
			}

			testColorBits = colorBits;
			testDepthBits = depthBits;
			testStencilBits = stencilBits;

			if ( ( i % 4 ) == 3 )
			{
				// reduce colorbits
				if ( testColorBits == 24 )
				{
					testColorBits = 16;
				}
			}

			if ( ( i % 4 ) == 2 )
			{
				// reduce depthbits
				if ( testDepthBits == 24 )
				{
					testDepthBits = 16;
				}
				else if ( testDepthBits == 16 )
				{
					testDepthBits = 8;
				}
			}

			if ( ( i % 4 ) == 1 )
			{
				// reduce stencilbits
				if ( testStencilBits == 24 )
				{
					testStencilBits = 16;
				}
				else if ( testStencilBits == 16 )
				{
					testStencilBits = 8;
				}
				else
				{
					testStencilBits = 0;
				}
			}

			if ( testColorBits == 24 )
			{
				perChannelColorBits = 8;
			}
			else
			{
				perChannelColorBits = 4;
			}

			SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, alphaBits );
			SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits );
			SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits );
			SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
			SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );
			SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
			SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer );
#endif

#if SDL_VERSION_ATLEAST( 2, 0, 0 )
			if ( !r_glAllowSoftware->integer )
			{
				SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
			}

			if ( r_glCoreProfile->integer || r_glDebugProfile->integer )
			{
				int major = r_glMajorVersion->integer;
				int minor = r_glMinorVersion->integer;

				SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, major );
				SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, minor );

				if ( r_glCoreProfile->integer )
				{
					SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
				}
				else
				{
					SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY );
				}

				if ( r_glDebugProfile->integer )
				{
					SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG );
				}
			}
#endif
			window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y, glConfig.vidWidth, glConfig.vidHeight, flags );

			if ( !window )
			{
				ri.Printf( PRINT_DEVELOPER, "SDL_CreateWindow failed: %s\n", SDL_GetError() );
				continue;
			}

			SDL_SetWindowIcon( window, icon );

			glContext = SDL_GL_CreateContext( window );

			if ( !glContext )
			{
				ri.Printf( PRINT_DEVELOPER, "SDL_GL_CreateContext failed: %s\n", SDL_GetError() );
				continue;
			}
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
			SDL_GL_SetSwapInterval( r_swapInterval->integer );
#endif
			SDL_ShowCursor( 0 );

			glConfig.colorBits = testColorBits;
			glConfig.depthBits = testDepthBits;
			glConfig.stencilBits = testStencilBits;

			ri.Printf( PRINT_ALL, "Using %d Color bits, %d depth, %d stencil display.\n",
				glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );

			break;
		}

		if ( samples && ( !glContext || !window ) )
		{
			r_ext_multisample->integer = 0;
		}

	} while ( ( !glContext || !window ) && samples );

	SDL_FreeSurface( icon );

	glewResult = glewInit();

	if ( glewResult != GLEW_OK )
	{
		// glewInit failed, something is seriously wrong
		ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem: %s", glewGetErrorString( glewResult ) );
	}
	else
	{
		ri.Printf( PRINT_ALL, "Using GLEW %s\n", glewGetString( GLEW_VERSION ) );
	}

	int GLmajor, GLminor;
	sscanf( ( const char * ) glGetString( GL_VERSION ), "%d.%d", &GLmajor, &GLminor );
	if ( GLmajor < 2 || ( GLmajor == 2 && GLminor < 1 ) )
	{
		// missing shader support, switch to 1.x renderer
		return RSERR_OLD_GL;
	}

	if ( GLmajor < 3 || ( GLmajor == 3 && GLminor < 2 ) )
	{
		// shaders are supported, but not all GL3.x features
		ri.Printf( PRINT_ALL, "Using enhanced (GL3) Renderer in GL 2.x mode...\n" );
	}
	else
	{
		ri.Printf( PRINT_ALL, "Using enhanced (GL3) Renderer in GL 3.x mode...\n" );
		glConfig.driverType = GLDRV_OPENGL3;
	}
#if defined( SMP ) && !SDL_VERSION_ATLEAST( 2, 0, 0 )
	// setup context for SDL_GL_MakeCurrent
	SDL_GL_GetCurrentContext();
#endif
	GLimp_DetectAvailableModes();

	glstring = ( char * ) glGetString( GL_RENDERER );
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
}
Esempio n. 9
0
int main( int argc, char* argv[] )
{
	GLboolean running;

	// Initialise SDL2
	if( 0 != SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS ) )
	{
		fprintf( stderr, "Failed to initialize SDL2: %s\n", SDL_GetError() );
		exit( EXIT_FAILURE );
	}

	// Open OpenGL window
	SDL_Window * window = SDL_CreateWindow( "SOIL2 Test",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );

	if( NULL == window )
	{
		fprintf( stderr, "Failed to open SDL2 window: %s\n", SDL_GetError() );
		exit( EXIT_FAILURE );
	}

	SDL_GLContext context = SDL_GL_CreateContext( window );

	if ( NULL == context )
	{
		fprintf( stderr, "Failed to create SDL2 OpenGL Context: %s\n", SDL_GetError() );

		SDL_DestroyWindow( window );

		exit( EXIT_FAILURE );
	}

	SDL_GL_SetSwapInterval( 1 );

	SDL_GL_MakeCurrent( window, context );

	//	log what the use is asking us to load
	std::string load_me;

	if ( argc >= 2 )
	{
		load_me = std::string( argv[1] );
	}
	else
	{
		load_me = ResourcePath( "img_test.png" );
	}

	std::cout << "'" << load_me << "'" << std::endl;

	//	1st try to load it as a single-image-cubemap
	//	(note, need DDS ordered faces: "EWUDNS")
	GLuint tex_ID;
	Uint64 time_me;

	std::cout << "Attempting to load as a cubemap" << std::endl;
	time_me = SDL_GetPerformanceCounter();

	tex_ID = SOIL_load_OGL_single_cubemap(
			load_me.c_str(),
			SOIL_DDS_CUBEMAP_FACE_ORDER,
			SOIL_LOAD_AUTO,
			SOIL_CREATE_NEW_ID,
			SOIL_FLAG_POWER_OF_TWO
			| SOIL_FLAG_MIPMAPS
			| SOIL_FLAG_DDS_LOAD_DIRECT
			| SOIL_FLAG_PVR_LOAD_DIRECT
			| SOIL_FLAG_ETC1_LOAD_DIRECT
			);

	std::cout << "the load time was " << get_total_ms(time_me) << " milliseconds" << std::endl;

	if( tex_ID > 0 )
	{
		glEnable( GL_TEXTURE_CUBE_MAP );
		glEnable( GL_TEXTURE_GEN_S );
		glEnable( GL_TEXTURE_GEN_T );
		glEnable( GL_TEXTURE_GEN_R );
		glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
		glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
		glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
		glBindTexture( GL_TEXTURE_CUBE_MAP, tex_ID );
		
		std::cout << "the loaded single cube map ID was " << tex_ID << std::endl;
	}
	else
	{
		std::cout << "Attempting to load as a HDR texture" << std::endl;
		time_me = SDL_GetPerformanceCounter();
		
		tex_ID = SOIL_load_OGL_HDR_texture(
				load_me.c_str(),
				SOIL_HDR_RGBdivA2,
				0,
				SOIL_CREATE_NEW_ID,
				SOIL_FLAG_POWER_OF_TWO
				| SOIL_FLAG_MIPMAPS
				| SOIL_FLAG_GL_MIPMAPS
				);

		std::cout << "the load time was " << get_total_ms(time_me) << " milliseconds" << std::endl;
		
		//	did I fail?
		if( tex_ID < 1 )
		{
			//	loading of the single-image-cubemap failed, try it as a simple texture
			std::cout << "Attempting to load as a simple 2D texture" << std::endl;
			
			//	load the texture, if specified
			time_me = SDL_GetPerformanceCounter();
			
			tex_ID = SOIL_load_OGL_texture(
					load_me.c_str(),
					SOIL_LOAD_AUTO,
					SOIL_CREATE_NEW_ID,
					  SOIL_FLAG_POWER_OF_TWO
					| SOIL_FLAG_MIPMAPS
					| SOIL_FLAG_GL_MIPMAPS
					| SOIL_FLAG_DDS_LOAD_DIRECT
					| SOIL_FLAG_PVR_LOAD_DIRECT
					| SOIL_FLAG_ETC1_LOAD_DIRECT
					| SOIL_FLAG_COMPRESS_TO_DXT
					);

			std::cout << "the load time was " << get_total_ms(time_me) << " milliseconds" << std::endl;
		}

		if( tex_ID > 0 )
		{
			//	enable texturing
			glEnable( GL_TEXTURE_2D );
			
			//  bind an OpenGL texture ID
			glBindTexture( GL_TEXTURE_2D, tex_ID );
			
			//	report
			std::cout << "the loaded texture ID was " << tex_ID << std::endl;
		}
		else
		{
			//	loading of the texture failed...why?
			glDisable( GL_TEXTURE_2D );
			
			std::cout << "Texture loading failed: '" << SOIL_last_result() << "'" << std::endl;
		}
	}

	running = GL_TRUE;

	const float ref_mag = 0.1f;
	float theta = 0.0f;
	float tex_u_max = 1.0f;
	float tex_v_max = 1.0f;
	Uint64 counterOld = SDL_GetPerformanceCounter();

	while( running )
	{
		float dt = (float)((double)(SDL_GetPerformanceCounter() - counterOld) / (double)SDL_GetPerformanceFrequency());
		counterOld = SDL_GetPerformanceCounter();

		SDL_Event evt;

		while (SDL_PollEvent(&evt))
		{
			switch (evt.type)
			{
				case SDL_QUIT:
				{
					running = false;
					break;
				}
				case SDL_KEYUP:
				{
					if ( SDLK_ESCAPE == evt.key.keysym.sym )
					{
						running = false;
					}
					break;
				}
			}
		}

		theta += dt * 40;

		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		
		// Draw our textured geometry (just a rectangle in this instance)
		glPushMatrix();
		glScalef( 0.8f, 0.8f, 0.8f );
		glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
		glNormal3f( 0.0f, 0.0f, 1.0f );
		glBegin(GL_QUADS);
			glNormal3f( -ref_mag, -ref_mag, 1.0f );
			glTexCoord2f( 0.0f, tex_v_max );
			glVertex3f( -1.0f, -1.0f, -0.1f );

			glNormal3f( ref_mag, -ref_mag, 1.0f );
			glTexCoord2f( tex_u_max, tex_v_max );
			glVertex3f( 1.0f, -1.0f, -0.1f );

			glNormal3f( ref_mag, ref_mag, 1.0f );
			glTexCoord2f( tex_u_max, 0.0f );
			glVertex3f( 1.0f, 1.0f, -0.1f );

			glNormal3f( -ref_mag, ref_mag, 1.0f );
			glTexCoord2f( 0.0f, 0.0f );
			glVertex3f( -1.0f, 1.0f, -0.1f );
		glEnd();
		glPopMatrix();

		glPushMatrix();
		glScalef( 0.8f, 0.8f, 0.8f );
		glRotatef(theta, 0.0f, 0.0f, 1.0f);
		glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
		glNormal3f( 0.0f, 0.0f, 1.0f );
		glBegin(GL_QUADS);
			glTexCoord2f( 0.0f, tex_v_max );		glVertex3f( 0.0f, 0.0f, 0.1f );
			glTexCoord2f( tex_u_max, tex_v_max );	glVertex3f( 1.0f, 0.0f, 0.1f );
			glTexCoord2f( tex_u_max, 0.0f );		glVertex3f( 1.0f, 1.0f, 0.1f );
			glTexCoord2f( 0.0f, 0.0f );				glVertex3f( 0.0f, 1.0f, 0.1f );
		glEnd();
		glPopMatrix();

		// Swap buffers
		SDL_GL_SwapWindow( window );
	}

	// Close OpenGL window and terminate SDL2
	SDL_GL_DeleteContext( context );

	SDL_DestroyWindow( window );

	exit( EXIT_SUCCESS );
}
Esempio n. 10
0
File: main.c Progetto: wowk/OpenGL
int main(int argc, char *argv[])
{
    GLuint vao;
    GLuint vbo;
    GLfloat vertices[] = {
        0.5f,   -0.5f,  0.0f,
        -0.5f,  -0.5f,  0.0f,
        0.0f,   0.5f,   0.0f,
    };

    GLfloat colorUniform[3];
    GLint colorUniformLocation;

    GLint status;
    GLuint vertexShader;
    GLuint fragmentShader;
    GLuint program;
    GLchar *pbuffer;
    GLchar buffer[4096];
    GLsizei bufferLen;
    GLchar logBuffer[256];
    GLsizei logBufferLen;

    GLboolean running = GL_FALSE;
    SDL_Window* window = NULL;
    SDL_GLContext glContext = NULL;

    if( 0 > SDL_Init(SDL_INIT_VIDEO) ){
        printf("SDL_Init(Video) failed: %s\n", SDL_GetError());
        goto error_sdl_init;
    }

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    window = SDL_CreateWindow(argv[0], 100, 100, 800, 600, SDL_WINDOW_OPENGL);
    if( !window ){
        printf("SDL_CreateWindow failed: %s\n", SDL_GetError());
        goto error_sdl_create_window;
    }

    glContext = SDL_GL_CreateContext(window);
    if( !glContext ){
        printf("SDL_GL_CreateContext failed: %s\n", SDL_GetError());
        goto error_sdl_gl_create_context;
    }

    if( 0 == gladLoadGLLoader(SDL_GL_GetProcAddress) ){
        printf("gladLoadGLLoader failed\n");
        goto error_glad_load_error;
    }

    /* load vertex data */
    glGenVertexArrays(1, &vao);
    if( 0 == vao ){
        printf("glGenVertexArrays failed: %d\n", glGetError());
        goto error_gl_gen_vertex_arrays;
    }
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    if( 0 == vbo ){
        printf("glGenBuffers failed: %d\n", glGetError());
        goto error_gl_gen_buffers;
    }
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
    glEnableVertexAttribArray(0);

    glBindVertexArray(0);

    program = glCreateProgram();
    if( 0 == program ){
        printf("glCreateProgram failed: %d\n", glGetError());
        goto error_gl_create_program;
    }

    /* load vertex shader */
    bufferLen = sizeof(buffer);
    if( 0 == loadFile("../03_02_UseUniformVariable/shader.vert", buffer, &bufferLen) ){
        goto error_load_vertex_source;
    }

    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    if( 0 == vertexShader ){
        goto error_gl_create_vertex_shader;
    }

    pbuffer = buffer;
    glShaderSource(vertexShader, 1, &pbuffer, &bufferLen);
    glCompileShader(vertexShader);
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
    if( 0 == status ){
        glGetShaderInfoLog(vertexShader, sizeof(logBuffer), &logBufferLen, logBuffer);
        printf("compile shader failed:\n%s\nerror: %s\n", buffer, logBuffer);
        goto error_gl_compile_shader;
    }
    glAttachShader(program, vertexShader);
    glDeleteShader(vertexShader);
    vertexShader = 0;

    /* load fragment shader */
    bufferLen = sizeof(buffer);
    if( 0 == loadFile("../03_02_UseUniformVariable/shader.frag", buffer, &bufferLen) ){
        goto error_load_fragment_source;
    }

    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    if( 0 == fragmentShader ){
        goto error_gl_create_fragment_shader;
    }

    pbuffer = buffer;
    glShaderSource(fragmentShader, 1, &pbuffer, &bufferLen);
    glCompileShader(fragmentShader);
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
    if( 0 == status ){
        glGetShaderInfoLog(fragmentShader, sizeof(logBuffer), &logBufferLen, logBuffer);
        printf("compile shader failed:\n%s\nerror: %s\n", buffer, logBuffer);
        goto error_gl_compile_fragment_shader;
    }
    glAttachShader(program, fragmentShader);

    /* link program */
    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if( 0 == status ){
        glGetProgramInfoLog(program, sizeof(logBuffer), &logBufferLen, logBuffer);
        printf("link program failed: %s\n", logBuffer);
        goto error_link_program;
    }

    colorUniformLocation = glGetUniformLocation(program, "vertColor");
    if( -1 == colorUniformLocation ){
        printf("get uniformm location failed: %d\n", glGetError());
        goto error_get_uniform_vertColor_location;
    }
    glGetUniformfv(program, colorUniformLocation, colorUniform);

    running = GL_TRUE;
    while( running ){
        SDL_Event event;
        while( SDL_PollEvent(&event)){
            if( event.type == SDL_KEYDOWN ){
                switch(event.key.keysym.sym){
                case SDLK_1:
                    if( colorUniform[0] > 0.0f )
                        colorUniform[0] -= 0.05f;
                    break;
                case SDLK_2:
                    if( colorUniform[0] < 1.0f )
                        colorUniform[0] += 0.05f;
                    break;
                case SDLK_3:
                    if( colorUniform[1] > 0.0f )
                        colorUniform[1] -= 0.05f;
                    break;
                case SDLK_4:
                    if( colorUniform[1] < 1.0f )
                        colorUniform[1] += 0.05f;
                    break;
                case SDLK_5:
                    if( colorUniform[2] > 0.0f )
                        colorUniform[2] -= 0.05f;
                    break;
                case SDLK_6:
                    if( colorUniform[2] < 1.0f )
                        colorUniform[2] += 0.05f;
                    break;
                default:
                    printf("quit\n");
                    running = GL_FALSE;
                    break;
                }
            }
        }

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

        glBindVertexArray(vao);
        glUseProgram(program);
        glUniform3fv(colorUniformLocation, 1, colorUniform);
        //glUniform3f(colorUniformLocation, colorUniform[0], colorUniform[1], colorUniform[2]);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glUseProgram(0);
        glBindVertexArray(0);

        SDL_GL_SwapWindow(window);
    }

    glDeleteProgram(program);
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);
    SDL_GL_DeleteContext(glContext);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;

error_get_uniform_vertColor_location:
error_link_program:
error_gl_compile_fragment_shader:
    if( fragmentShader )
        glDeleteShader(fragmentShader);
error_gl_create_fragment_shader:
error_load_fragment_source:
error_gl_compile_shader:
    if( vertexShader )
        glDeleteShader(vertexShader);
error_gl_create_vertex_shader:
error_load_vertex_source:
    glDeleteProgram(program);
error_gl_create_program:
    glDeleteBuffers(1, &vbo);
error_gl_gen_buffers:
    glDeleteVertexArrays(1, &vao);
error_gl_gen_vertex_arrays:
error_glad_load_error:
    SDL_GL_DeleteContext(glContext);
error_sdl_gl_create_context:
    SDL_DestroyWindow(window);
error_sdl_create_window:
    SDL_Quit();
error_sdl_init:

    return -1;
}
Esempio n. 11
0
void SDLDestroyWindow()
{
	SDL_GL_DeleteContext(glContext);
	SDL_DestroyWindow(window);
}
Esempio n. 12
0
WindowSDL::~WindowSDL()
{
	SDL_GL_DeleteContext(m_glContext);
	SDL_DestroyWindow(m_window);
}
Esempio n. 13
0
SDL2Renderer::~SDL2Renderer()
{
    SDL_GL_DeleteContext(m_gl_context);
    SDL_FreeFormat(m_pixelformat);
    SDL_DestroyWindow(m_window);
}
Esempio n. 14
0
int main(int, char**)
{
    // Setup SDL
    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0)
    {
        printf("Error: %s\n", SDL_GetError());
        return -1;
    }

    // Setup window
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_DisplayMode current;
    SDL_GetCurrentDisplayMode(0, &current);
    SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    SDL_GLContext glcontext = SDL_GL_CreateContext(window);

    // Setup ImGui binding
    ImGui_ImplSdlGL2_Init(window);

    // Setup style
    ImGui::StyleColorsClassic();
    //ImGui::StyleColorsDark();

    // Load Fonts
    // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. 
    // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. 
    // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
    // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
    // - Read 'extra_fonts/README.txt' for more instructions and details.
    // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
    //ImGuiIO& io = ImGui::GetIO();
    //io.Fonts->AddFontDefault();
    //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f);
    //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f);
    //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f);
    //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f);
    //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
    //IM_ASSERT(font != NULL);

    bool show_demo_window = true;
    bool show_another_window = false;
    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);

    // Main loop
    bool done = false;
    while (!done)
    {
        // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
        // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
        // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
        // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            ImGui_ImplSdlGL2_ProcessEvent(&event);
            if (event.type == SDL_QUIT)
                done = true;
        }
        ImGui_ImplSdlGL2_NewFrame(window);

        // 1. Show a simple window
        // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug".
        {
            static float f = 0.0f;
            ImGui::Text("Hello, world!");                           // Some text (you can use a format string too)
            ImGui::SliderFloat("float", &f, 0.0f, 1.0f);            // Edit 1 float as a slider from 0.0f to 1.0f
            ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color
            if (ImGui::Button("Demo Window"))                       // Use buttons to toggle our bools. We could use Checkbox() as well.
                show_demo_window ^= 1;
            if (ImGui::Button("Another Window"))
                show_another_window ^= 1;
            ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
        }

        // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window.
        if (show_another_window)
        {
            ImGui::Begin("Another Window", &show_another_window);
            ImGui::Text("Hello from another window!");
            ImGui::End();
        }

        // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow().
        if (show_demo_window)
        {
            ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
            ImGui::ShowDemoWindow(&show_demo_window);
        }

        // Rendering
        glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y);
        glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);
        //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
        ImGui::Render();
        SDL_GL_SwapWindow(window);
    }

    // Cleanup
    ImGui_ImplSdlGL2_Shutdown();
    SDL_GL_DeleteContext(glcontext);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
Esempio n. 15
0
int main(int argc, char *argv[])
{
    char *argv0 = argv[0];
    SDL_Window *window;
    SDL_GLContext context;
    TTF_Font *font;
    SDL_Surface *text;
    int ptsize;
    int i, done;
    SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
    SDL_Color black = { 0x00, 0x00, 0x00, 0 };
    SDL_Color *forecol;
    SDL_Color *backcol;
    GLenum gl_error;
    GLuint texture;
    int x, y, w, h;
    GLfloat texcoord[4];
    GLfloat texMinX, texMinY;
    GLfloat texMaxX, texMaxY;
        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}};
    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}};
    SDL_Event event;
    int renderstyle;
    int dump;
    enum {
        RENDER_LATIN1,
        RENDER_UTF8,
        RENDER_UNICODE
    } rendertype;
    char *message;

    /* Look for special execution mode */
    dump = 0;
    /* Look for special rendering types */
    renderstyle = TTF_STYLE_NORMAL;
    rendertype = RENDER_LATIN1;
    /* Default is black and white */
    forecol = &black;
    backcol = &white;
    for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) {
        if ( strcmp(argv[i], "-utf8") == 0 ) {
            rendertype = RENDER_UTF8;
        } else
        if ( strcmp(argv[i], "-unicode") == 0 ) {
            rendertype = RENDER_UNICODE;
        } else
        if ( strcmp(argv[i], "-b") == 0 ) {
            renderstyle |= TTF_STYLE_BOLD;
        } else
        if ( strcmp(argv[i], "-i") == 0 ) {
            renderstyle |= TTF_STYLE_ITALIC;
        } else
        if ( strcmp(argv[i], "-u") == 0 ) {
            renderstyle |= TTF_STYLE_UNDERLINE;
        } else
        if ( strcmp(argv[i], "-dump") == 0 ) {
            dump = 1;
        } else
        if ( strcmp(argv[i], "-fgcol") == 0 ) {
            int r, g, b;
            if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
                fprintf(stderr, Usage, argv0);
                return(1);
            }
            forecol->r = (Uint8)r;
            forecol->g = (Uint8)g;
            forecol->b = (Uint8)b;
        } else
        if ( strcmp(argv[i], "-bgcol") == 0 ) {
            int r, g, b;
            if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
                fprintf(stderr, Usage, argv0);
                return(1);
            }
            backcol->r = (Uint8)r;
            backcol->g = (Uint8)g;
            backcol->b = (Uint8)b;
        } else {
            fprintf(stderr, Usage, argv0);
            return(1);
        }
    }
    argv += i;
    argc -= i;

    /* Check usage */
    if ( ! argv[0] ) {
        fprintf(stderr, Usage, argv0);
        return(1);
    }

    /* Initialize the TTF library */
    if ( TTF_Init() < 0 ) {
        fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
        SDL_Quit();
        return(2);
    }

    /* Open the font file with the requested point size */
    ptsize = 0;
    if ( argc > 1 ) {
        ptsize = atoi(argv[1]);
    }
    if ( ptsize == 0 ) {
        i = 2;
        ptsize = DEFAULT_PTSIZE;
    } else {
        i = 3;
    }
    font = TTF_OpenFont(argv[0], ptsize);
    if ( font == NULL ) {
        fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",
                    ptsize, argv[0], SDL_GetError());
        cleanup(2);
    }
    TTF_SetFontStyle(font, renderstyle);

    if( dump ) {
        for( i = 48; i < 123; i++ ) {
            SDL_Surface* glyph = NULL;

            glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol );

            if( glyph ) {
                char outname[64];
                sprintf( outname, "glyph-%d.bmp", i );
                SDL_SaveBMP( glyph, outname );
            }

        }
        cleanup(0);
    }

    /* Set a 640x480 video mode */
    window = SDL_CreateWindow("glfont",
                                SDL_WINDOWPOS_UNDEFINED,
                                SDL_WINDOWPOS_UNDEFINED,
                                WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
    if ( window == NULL ) {
        fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
        cleanup(2);
    }

    context = SDL_GL_CreateContext(window);
    if ( context == NULL ) {
        fprintf(stderr, "Couldn't create OpenGL context: %s\n", SDL_GetError());
        cleanup(2);
    }

    /* Render and center the message */
    if ( argc > 2 ) {
        message = argv[2];
    } else {
        message = DEFAULT_TEXT;
    }
    switch (rendertype) {
        case RENDER_LATIN1:
        text = TTF_RenderText_Blended(font, message, *forecol);
        break;

        case RENDER_UTF8:
        text = TTF_RenderUTF8_Blended(font, message, *forecol);
        break;

        case RENDER_UNICODE:
        {
            /* This doesn't actually work because you can't pass
               UNICODE text in via command line, AFAIK, but...
             */
            Uint16 unicode_text[BUFSIZ];
            int index;
            for ( index = 0; (message[0] || message[1]); ++index ) {
                unicode_text[index]  = ((Uint8 *)message)[0];
                unicode_text[index] <<= 8;
                unicode_text[index] |= ((Uint8 *)message)[1];
                message += 2;
            }
            text = TTF_RenderUNICODE_Blended(font,
                    unicode_text, *forecol);
        }
        break;
        default:
        text = NULL; /* This shouldn't happen */
        break;
    }
    if ( text == NULL ) {
        fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError());
        TTF_CloseFont(font);
        cleanup(2);
    }
    x = (WIDTH - text->w)/2;
    y = (HEIGHT - text->h)/2;
    w = text->w;
    h = text->h;
    printf("Font is generally %d big, and string is %hd big\n",
                        TTF_FontHeight(font), text->h);

    /* Convert the text into an OpenGL texture */
    glGetError();
    texture = SDL_GL_LoadTexture(text, texcoord);
    if ( (gl_error = glGetError()) != GL_NO_ERROR ) {
        /* If this failed, the text may exceed texture size limits */
        printf("Warning: Couldn't create texture: 0x%x\n", gl_error);
    }

    /* Make texture coordinates easy to understand */
    texMinX = texcoord[0];
    texMinY = texcoord[1];
    texMaxX = texcoord[2];
    texMaxY = texcoord[3];

    /* We don't need the original text surface anymore */
    SDL_FreeSurface(text);

    /* Initialize the GL state */
    glViewport( 0, 0, WIDTH, HEIGHT );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );

    glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );

    glEnable(GL_DEPTH_TEST);

    glDepthFunc(GL_LESS);

    glShadeModel(GL_SMOOTH);

    /* Wait for a keystroke, and blit text on mouse press */
    done = 0;
    while ( ! done ) {
        while ( SDL_PollEvent(&event) ) {
            switch (event.type) {
                case SDL_MOUSEMOTION:
                x = event.motion.x - w/2;
                y = event.motion.y - h/2;
                break;

                case SDL_KEYDOWN:
                case SDL_QUIT:
                done = 1;
                break;
                default:
                break;
            }
        }

        /* Clear the screen */
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        /* Draw the spinning cube */
        glBegin( GL_QUADS );

            glColor3fv(color[0]);
            glVertex3fv(cube[0]);
            glColor3fv(color[1]);
            glVertex3fv(cube[1]);
            glColor3fv(color[2]);
            glVertex3fv(cube[2]);
            glColor3fv(color[3]);
            glVertex3fv(cube[3]);

            glColor3fv(color[3]);
            glVertex3fv(cube[3]);
            glColor3fv(color[4]);
            glVertex3fv(cube[4]);
            glColor3fv(color[7]);
            glVertex3fv(cube[7]);
            glColor3fv(color[2]);
            glVertex3fv(cube[2]);

            glColor3fv(color[0]);
            glVertex3fv(cube[0]);
            glColor3fv(color[5]);
            glVertex3fv(cube[5]);
            glColor3fv(color[6]);
            glVertex3fv(cube[6]);
            glColor3fv(color[1]);
            glVertex3fv(cube[1]);

            glColor3fv(color[5]);
            glVertex3fv(cube[5]);
            glColor3fv(color[4]);
            glVertex3fv(cube[4]);
            glColor3fv(color[7]);
            glVertex3fv(cube[7]);
            glColor3fv(color[6]);
            glVertex3fv(cube[6]);

            glColor3fv(color[5]);
            glVertex3fv(cube[5]);
            glColor3fv(color[0]);
            glVertex3fv(cube[0]);
            glColor3fv(color[3]);
            glVertex3fv(cube[3]);
            glColor3fv(color[4]);
            glVertex3fv(cube[4]);

            glColor3fv(color[6]);
            glVertex3fv(cube[6]);
            glColor3fv(color[1]);
            glVertex3fv(cube[1]);
            glColor3fv(color[2]);
            glVertex3fv(cube[2]);
            glColor3fv(color[7]);
            glVertex3fv(cube[7]);
        glEnd( );

        /* Rotate the cube */
        glMatrixMode(GL_MODELVIEW);
        glRotatef(5.0, 1.0, 1.0, 1.0);

        /* Show the text on the screen */
        SDL_GL_Enter2DMode(WIDTH, HEIGHT);
        glBindTexture(GL_TEXTURE_2D, texture);
        glBegin(GL_TRIANGLE_STRIP);
        glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
        glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
        glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
        glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
        glEnd();
        SDL_GL_Leave2DMode();

        /* Swap the buffers so everything is visible */
        SDL_GL_SwapWindow(window);
    }
    SDL_GL_DeleteContext(context);
    TTF_CloseFont(font);
    cleanup(0);

    /* Not reached, but fixes compiler warnings */
    return 0;
}
Esempio n. 16
0
int main(int argc, char **argv)
{
	SDL_Window *window;
	SDL_GLContext context;
	SDL_Event evt;
	MOJOSHADER_glContext *shaderContext;
	MOJOSHADER_effect *effect;
	MOJOSHADER_glEffect *glEffect;
	SDL_Surface *bitmap;
	GLuint texture;
	GLuint buffers[2];
	FILE *fileIn;
	unsigned int fileLen;
	unsigned char *effectData;
	unsigned int passes;
	MOJOSHADER_effectStateChanges changes;
	Uint8 run = 1;

	/* Create the window and GL context */
	SDL_Init(SDL_INIT_VIDEO);
	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_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
	window = SDL_CreateWindow(
		"Sprite Test",
		SDL_WINDOWPOS_CENTERED,
		SDL_WINDOWPOS_CENTERED,
		SCREEN_WIDTH,
		SCREEN_HEIGHT,
		SDL_WINDOW_OPENGL
	);
	context = SDL_GL_CreateContext(window);
	shaderContext = MOJOSHADER_glCreateContext(
		MOJOSHADER_PROFILE,
		GetGLProcAddress,
		NULL,
		NULL,
		NULL,
		NULL
	);
	MOJOSHADER_glMakeContextCurrent(shaderContext);

	/* ARB_debug_output setup */
	glDebugMessageCallbackARB(GLDebugCallback, NULL);
	glDebugMessageControlARB(
		GL_DONT_CARE,
		GL_DONT_CARE,
		GL_DONT_CARE,
		0,
		NULL,
		GL_TRUE
	);

	/* Set up the viewport, create the texture/buffer data */
	glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.0f);
	bitmap = SDL_LoadBMP("../Sprite.bmp");
	glTexImage2D(
		GL_TEXTURE_2D,
		0,
		GL_RGB,
		bitmap->w,
		bitmap->h,
		0,
		GL_BGR,
		GL_UNSIGNED_BYTE,
		bitmap->pixels
	);
	SDL_FreeSurface(bitmap);
	glGenBuffersARB(2, buffers);
	glBindBufferARB(GL_ARRAY_BUFFER, buffers[0]);
	glBufferDataARB(
		GL_ARRAY_BUFFER,
		sizeof(vertexstruct_t) * 4,
		vertex_array,
		GL_STATIC_DRAW
	);
	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
	glBufferDataARB(
		GL_ELEMENT_ARRAY_BUFFER,
		12,
		index_array,
		GL_STATIC_DRAW
	);

	/* Load and read the SpriteBatch effect file */
	fileIn = fopen("../SpriteEffect.fxb", "rb");
	fseek(fileIn, 0, SEEK_END);
	fileLen = ftell(fileIn);
	fseek(fileIn, 0, SEEK_SET);
	effectData = (unsigned char*) malloc(fileLen);
	fread(effectData, 1, fileLen, fileIn);
	fclose(fileIn);
	effect = MOJOSHADER_parseEffect(
		MOJOSHADER_PROFILE,
		effectData,
		fileLen,
		NULL,
		0,
		NULL,
		0,
		NULL,
		NULL,
		NULL
	);
	free(effectData);
	glEffect = MOJOSHADER_glCompileEffect(effect);
	MOJOSHADER_effectSetRawValueName(
		effect,
		"MatrixTransform",
		transform_matrix,
		0,
		64
	);

	while (run)
	{
		while (SDL_PollEvent(&evt) > 0)
		{
			if (evt.type == SDL_QUIT)
			{
				run = 0;
			}
		}

		/* Clear the screen to black. */
		glClear(GL_COLOR_BUFFER_BIT);

		/* Bind the effect */
		MOJOSHADER_glEffectBegin(glEffect, &passes, 0, &changes);
		MOJOSHADER_glEffectBeginPass(glEffect, 0);

		/* Set the attrib pointers now, while the effect is bound */
		MOJOSHADER_glSetVertexAttribute(
			MOJOSHADER_USAGE_POSITION,
			0,
			3,
			MOJOSHADER_ATTRIBUTE_FLOAT,
			0,
			sizeof(vertexstruct_t),
			(void*) 0
		);
		MOJOSHADER_glSetVertexAttribute(
			MOJOSHADER_USAGE_COLOR,
			0,
			4,
			MOJOSHADER_ATTRIBUTE_UBYTE,
			1,
			sizeof(vertexstruct_t),
			(void*) 12
		);
		MOJOSHADER_glSetVertexAttribute(
			MOJOSHADER_USAGE_TEXCOORD,
			0,
			2,
			MOJOSHADER_ATTRIBUTE_FLOAT,
			0,
			sizeof(vertexstruct_t),
			(void*) 16
		);

		/* Flush all changes to the shader and constant buffers */
		MOJOSHADER_glProgramReady();

		/* Draw! */
		glDrawRangeElements(
			GL_TRIANGLES,
			0,
			3,
			6,
			GL_UNSIGNED_SHORT,
			NULL
		);

		/* We've finished drawing. Present what we've drawn. */
		MOJOSHADER_glEffectEndPass(glEffect);
		MOJOSHADER_glEffectEnd(glEffect);
		SDL_GL_SwapWindow(window);
	}

	/* Clean up. We out. */
	glDeleteBuffersARB(2, buffers);
	glDeleteTextures(1, &texture);
	MOJOSHADER_glDeleteEffect(glEffect);
	MOJOSHADER_freeEffect(effect);
	MOJOSHADER_glMakeContextCurrent(NULL);
	MOJOSHADER_glDestroyContext(shaderContext);
	SDL_GL_DeleteContext(context);
	SDL_DestroyWindow(window);
	SDL_Quit();
	return 0;
}
Esempio n. 17
0
/*
 * Deconstructor
 */
Window::~Window(){
    SDL_GL_DeleteContext(this->sdl_context);
    SDL_DestroyWindow(this->sdl_window);
    SDL_Quit();
}
Esempio n. 18
0
int main(int argc, char **argv){
    bool want_gl_debugging = false;
    bool want_msaa = false; // doesn't currently work, probably needs extension
    if(argc == 2 && (strncmp(argv[1], "debug_gl", 9) == 0)){
	want_gl_debugging = true;
    }
    START_TIMER(SDL_initialization_and_GL_context_creation);
    if(SDL_Init(SDL_INIT_EVERYTHING) == 1){
	printf("SDL failed to initialize: %s\n", SDL_GetError());
	return 1;
    }
    get_controller();
    SDL_Window *win = SDL_CreateWindow("SDL2/GL4.3", 0, 0, 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);    

    SDL_SetWindowGrab(win, SDL_TRUE);
    
    if(win == NULL){
	printf("SDL failed to create window: %s\n", SDL_GetError());
	return 1;
    }
    if(want_msaa){
	printf("setting msaa\n");
	if(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 4) != 0){
	    printf("failed to set MULTISAMPLEBUFFERS\n");
	}
	if(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16) != 0){
	    printf("failed to set MULTISAMPLESAMPLES\n");
	}
	glEnable(GL_MULTISAMPLE);
    }
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    if(want_gl_debugging){
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
    }
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); // it looks like we always get a core context anyway.
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    
    SDL_GLContext glcontext = SDL_GL_CreateContext(win);
    if(glcontext == NULL){
	printf("SDL failed to create context: %s\n", SDL_GetError());
	return 1;
    }

    int loaded_gl = ogl_LoadFunctions();
    if(!loaded_gl){
	printf("Failed to load OpenGL entry points.\n");
	return 1;
    }
    int context_flags;
    SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &context_flags);
    bool have_debug_context = (context_flags & SDL_GL_CONTEXT_DEBUG_FLAG) == SDL_GL_CONTEXT_DEBUG_FLAG;
    
    printf("OpenGL vendor: " TERMCOLOR_HIGHLIGHT "'%s'\n" TERMCOLOR_DEFAULT, glGetString(GL_VENDOR));
    printf("OpenGL renderer: " TERMCOLOR_HIGHLIGHT "'%s'\n" TERMCOLOR_DEFAULT, glGetString(GL_RENDERER));
    printf("OpenGL version: " TERMCOLOR_HIGHLIGHT "'%s'\n" TERMCOLOR_DEFAULT, glGetString(GL_VERSION));
    printf("GLSL version: " TERMCOLOR_HIGHLIGHT "'%s'\n" TERMCOLOR_DEFAULT, glGetString(GL_SHADING_LANGUAGE_VERSION));
    printf("Debug context: " TERMCOLOR_BOLD "%s" TERMCOLOR_DEFAULT "\n", have_debug_context ? "yes" : "no");
    int profile_flags;
    SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_flags);
    printf("Core context: " TERMCOLOR_BOLD "%s" TERMCOLOR_DEFAULT "\n", (profile_flags & SDL_GL_CONTEXT_PROFILE_CORE) != 0 ? "yes" : "no");

    if(have_debug_context && want_gl_debugging){
	printf(TERMCOLOR_HIGHLIGHT "We have debug extensions & context, installing debug callbacks..." TERMCOLOR_DEFAULT "\n");
	glDebugMessageCallback(debug_callback, stderr);
	glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
    }
    else {
	const char *reason = NULL;
	if(!want_gl_debugging)
	    reason = "debugging not requested (use 'debug_gl command line argument)";
	else if(!have_debug_context)
	    reason = "could not acquire debug context";
	else
	    reason = "unknown";
	printf(TERMCOLOR_ERROR "Not installing GL debug hooks. Reason: %s" TERMCOLOR_DEFAULT "\n", reason);
    }
    STOP_TIMER_AND_PRINT(SDL_initialization_and_GL_context_creation);
    START_TIMER(user_init);
    init(WINDOW_WIDTH, WINDOW_HEIGHT);
    STOP_TIMER_AND_PRINT(user_init);
    START_TIMER(total_renderloop_runtime);
    bool continue_loop = true;
    while(continue_loop){
        continue_loop = render(win);
	SDL_Event e;
	while(SDL_PollEvent(&e)){
	    if(e.type == SDL_QUIT){
		printf("received SDL_QUIT\n");
		goto exiting;
	    }
	    else if(e.type == SDL_MOUSEMOTION){
	      mousemove(e.motion.xrel, e.motion.yrel);
	      //SDL_WarpMouseInWindow(win, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
	      //printf("relative movement: %d, %d\n", e.motion.xrel, e.motion.yrel);
	    }
	    else if(e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_RESIZED){
		resize(e.window.data1, e.window.data2);
	    }
	}
    }
    exiting:
    STOP_TIMER_AND_PRINT(total_renderloop_runtime);

    quit();
    
    SDL_GL_DeleteContext(glcontext);
    SDL_Quit();
    return 0;
}
Esempio n. 19
0
int ProgressLoop (SDL_Window *pWindow, Progress *pProgress, bool &error)
{
    /*
        Since this function runs in a separate thread, we need
        to use a different rendering context.

        Attach it to the same window:
     */
    SDL_GLContext glContext = SDL_GL_CreateContext (pWindow);

    /*
        rect order: x1, y1, x2, y2
        rect 1 is most outside, rect 3 is most inside
     */
    float rects [3][4],
          f, x1, x2;
    for (int i = 0; i < 3; i++)
    {
        f = 2 - i;

        rects [i][0] = -(f * LOAD_BAR_EDGE + LOAD_BAR_WIDTH / 2);
        rects [i][1] = -(f * LOAD_BAR_EDGE + LOAD_BAR_HEIGHT / 2);
        rects [i][2] = f * LOAD_BAR_EDGE + LOAD_BAR_WIDTH / 2;
        rects [i][3] = f * LOAD_BAR_EDGE + LOAD_BAR_HEIGHT / 2;
    }

    std::size_t total, passed;
    do
    {
        total = pProgress->GetTotal ();
        passed = pProgress->GetPassed ();

        int w, h;
        SDL_GL_GetDrawableSize (pWindow, &w, &h);
        glViewport (0, 0, w, h);

        glMatrixMode (GL_PROJECTION);
        matrix4 matScreen = matOrtho (-float (w) / 2, float (w) / 2, -float (h) / 2, float (h) / 2, -1.0f, 1.0f);
        glLoadMatrixf (matScreen.m);

        glMatrixMode (GL_MODELVIEW);
        glLoadIdentity ();

        glClearColor (0,0,0,1);
        glClear (GL_COLOR_BUFFER_BIT);

        glColor4f (1,1,1,1);
        glDisable (GL_CULL_FACE);
        glDisable (GL_LIGHTING);

        // Outer line:
        glBegin (GL_QUAD_STRIP);
        glVertex2f (rects [0][0], rects [0][1]);
        glVertex2f (rects [1][0], rects [1][1]);
        glVertex2f (rects [0][2], rects [0][1]);
        glVertex2f (rects [1][2], rects [1][1]);
        glVertex2f (rects [0][2], rects [0][3]);
        glVertex2f (rects [1][2], rects [1][3]);
        glVertex2f (rects [0][0], rects [0][3]);
        glVertex2f (rects [1][0], rects [1][3]);
        glVertex2f (rects [0][0], rects [0][1]);
        glVertex2f (rects [1][0], rects [1][1]);
        glEnd ();

        // progress bar
        if (total > 0 && passed <= total)
            f = float (passed) / total;
        else
            f = 0;
        x1 = rects [2][0];
        x2 = x1 + f * (rects [2][2] - rects [2][0]);
        glBegin (GL_QUADS);
        glVertex2f (x1, rects [2][1]);
        glVertex2f (x2, rects [2][1]);
        glVertex2f (x2, rects [2][3]);
        glVertex2f (x1, rects [2][3]);
        glEnd ();

        SDL_GL_SwapWindow (pWindow);
    }
    while (!error && passed < total); // keep rendering as long as the other thread loads

    SDL_GL_DeleteContext (glContext);

    return 0;
}
Esempio n. 20
0
void quitSDL() {
	SDL_DestroyWindow(sdl_window);
	SDL_GL_DeleteContext(sdl_gl_context);
	SDL_Quit();
}
Esempio n. 21
0
SDL_Surface *
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
{
    SDL_DisplayMode desktop_mode;
    SDL_DisplayMode mode;
    int window_x = SDL_WINDOWPOS_UNDEFINED;
    int window_y = SDL_WINDOWPOS_UNDEFINED;
    Uint32 window_flags;
    Uint32 desktop_format;
    Uint32 desired_format;
    Uint32 surface_flags;

    if (!SDL_GetVideoDevice()) {
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
            return NULL;
        }
    }

    /* See if we can simply resize the existing window and surface */
    if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) {
        return SDL_PublicSurface;
    }

    /* Destroy existing window */
    SDL_PublicSurface = NULL;
    if (SDL_ShadowSurface) {
        SDL_FreeSurface(SDL_ShadowSurface);
        SDL_ShadowSurface = NULL;
    }
    if (SDL_VideoSurface) {
        SDL_DelPaletteWatch(SDL_VideoSurface->format->palette,
                            SDL_VideoPaletteChanged, NULL);
        SDL_FreeSurface(SDL_VideoSurface);
        SDL_VideoSurface = NULL;
    }
    if (SDL_VideoContext) {
        /* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */
        SDL_GL_DeleteContext(SDL_VideoContext);
        SDL_VideoContext = NULL;
    }
    if (SDL_VideoWindow) {
        SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y);
        SDL_DestroyWindow(SDL_VideoWindow);
    }

    /* Set up the event filter */
    if (!SDL_GetEventFilter(NULL, NULL)) {
        SDL_SetEventFilter(SDL_CompatEventFilter, NULL);
    }

    /* Create a new window */
    window_flags = SDL_WINDOW_SHOWN;
    if (flags & SDL_FULLSCREEN) {
        window_flags |= SDL_WINDOW_FULLSCREEN;
    }
    if (flags & SDL_OPENGL) {
        window_flags |= SDL_WINDOW_OPENGL;
    }
    if (flags & SDL_RESIZABLE) {
        window_flags |= SDL_WINDOW_RESIZABLE;
    }
    if (flags & SDL_NOFRAME) {
        window_flags |= SDL_WINDOW_BORDERLESS;
    }
    GetEnvironmentWindowPosition(width, height, &window_x, &window_y);
    SDL_SetFullscreenDisplayMode(NULL);
    SDL_VideoWindow =
        SDL_CreateWindow(wm_title, window_x, window_y, width, height,
                         window_flags);
    if (!SDL_VideoWindow) {
        return NULL;
    }
    SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon);

    window_flags = SDL_GetWindowFlags(SDL_VideoWindow);
    surface_flags = 0;
    if (window_flags & SDL_WINDOW_FULLSCREEN) {
        surface_flags |= SDL_FULLSCREEN;
    }
    if (window_flags & SDL_WINDOW_OPENGL) {
        surface_flags |= SDL_OPENGL;
    }
    if (window_flags & SDL_WINDOW_RESIZABLE) {
        surface_flags |= SDL_RESIZABLE;
    }
    if (window_flags & SDL_WINDOW_BORDERLESS) {
        surface_flags |= SDL_NOFRAME;
    }

    /* Set up the desired display mode */
    SDL_GetDesktopDisplayMode(&desktop_mode);
    desktop_format = desktop_mode.format;
    if (desktop_format && ((flags & SDL_ANYFORMAT)
                           || (bpp == SDL_BITSPERPIXEL(desktop_format)))) {
        desired_format = desktop_format;
    } else {
        switch (bpp) {
        case 0:
            if (desktop_format) {
                desired_format = desktop_format;
            } else {
                desired_format = SDL_PIXELFORMAT_RGB888;
            }
            bpp = SDL_BITSPERPIXEL(desired_format);
            break;
        case 8:
            desired_format = SDL_PIXELFORMAT_INDEX8;
            break;
        case 15:
            desired_format = SDL_PIXELFORMAT_RGB555;
            break;
        case 16:
            desired_format = SDL_PIXELFORMAT_RGB565;
            break;
        case 24:
            desired_format = SDL_PIXELFORMAT_RGB24;
            break;
        case 32:
            desired_format = SDL_PIXELFORMAT_RGB888;
            break;
        default:
            SDL_SetError("Unsupported bpp in SDL_SetVideoMode()");
            return NULL;
        }
    }
    mode.format = desired_format;
    mode.w = width;
    mode.h = height;
    mode.refresh_rate = 0;

    /* Set the desired display mode */
    if (flags & SDL_FULLSCREEN) {
        if (SDL_SetFullscreenDisplayMode(&mode) < 0) {
            return NULL;
        }
    }

    /* If we're in OpenGL mode, just create a stub surface and we're done! */
    if (flags & SDL_OPENGL) {
        SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow);
        if (!SDL_VideoContext) {
            return NULL;
        }
        if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) {
            return NULL;
        }
        SDL_VideoSurface =
            SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0);
        if (!SDL_VideoSurface) {
            return NULL;
        }
        SDL_VideoSurface->flags |= surface_flags;
        SDL_PublicSurface = SDL_VideoSurface;
        return SDL_PublicSurface;
    }

    /* Create a renderer for the window */
    if (SDL_CreateRenderer
        (SDL_VideoWindow, -1,
         SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0) {
        return NULL;
    }
    SDL_GetRendererInfo(&SDL_VideoRendererInfo);

    /* Create a texture for the screen surface */
    SDL_VideoTexture =
        SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_STREAMING, width,
                          height);

    if (!SDL_VideoTexture) {
        SDL_VideoTexture =
            SDL_CreateTexture(desktop_format,
                              SDL_TEXTUREACCESS_STREAMING, width, height);
    }
    if (!SDL_VideoTexture) {
        return NULL;
    }

    /* Create the screen surface */
    SDL_VideoSurface = CreateVideoSurface(SDL_VideoTexture);
    if (!SDL_VideoSurface) {
        return NULL;
    }
    SDL_VideoSurface->flags |= surface_flags;

    /* Set a default screen palette */
    if (SDL_VideoSurface->format->palette) {
        SDL_VideoSurface->flags |= SDL_HWPALETTE;
        SDL_DitherColors(SDL_VideoSurface->format->palette->colors,
                         SDL_VideoSurface->format->BitsPerPixel);
        SDL_AddPaletteWatch(SDL_VideoSurface->format->palette,
                            SDL_VideoPaletteChanged, SDL_VideoSurface);
        SDL_SetPaletteColors(SDL_VideoSurface->format->palette,
                             SDL_VideoSurface->format->palette->colors, 0,
                             SDL_VideoSurface->format->palette->ncolors);
    }

    /* Create a shadow surface if necessary */
    if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
        && !(flags & SDL_ANYFORMAT)) {
        SDL_ShadowSurface =
            SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
        if (!SDL_ShadowSurface) {
            return NULL;
        }
        SDL_ShadowSurface->flags |= surface_flags;

        /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */
        if (SDL_ShadowSurface->format->palette) {
            SDL_ShadowSurface->flags |= SDL_HWPALETTE;
            if (SDL_VideoSurface->format->palette) {
                SDL_SetSurfacePalette(SDL_ShadowSurface,
                                      SDL_VideoSurface->format->palette);
            } else {
                SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
                                 SDL_ShadowSurface->format->BitsPerPixel);
            }
            SDL_AddPaletteWatch(SDL_ShadowSurface->format->palette,
                                SDL_VideoPaletteChanged, SDL_ShadowSurface);
        }
    }
    SDL_PublicSurface =
        (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface);

    SDL_VideoFlags = flags;

    ClearVideoSurface();

    SetupScreenSaver(flags);

    /* We're finally done! */
    return SDL_PublicSurface;
}
Esempio n. 22
0
int main(int, char**)
{
    // Setup SDL
    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0)
    {
        printf("Error: %s\n", SDL_GetError());
        return -1;
    }

    // Setup window
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_DisplayMode current;
    SDL_GetCurrentDisplayMode(0, &current);
    SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    SDL_GL_SetSwapInterval(1); // Enable vsync

    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls

    // Setup Dear ImGui style
    ImGui::StyleColorsDark();
    //ImGui::StyleColorsClassic();

    // Setup Platform/Renderer bindings
    ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
    ImGui_ImplOpenGL2_Init();

    // Load Fonts
    // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
    // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
    // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
    // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
    // - Read 'misc/fonts/README.txt' for more instructions and details.
    // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
    //io.Fonts->AddFontDefault();
    //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
    //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
    //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
    //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
    //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
    //IM_ASSERT(font != NULL);

    bool show_demo_window = true;
    bool show_another_window = false;
    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);

    // Main loop
    bool done = false;
    while (!done)
    {
        // Poll and handle events (inputs, window resize, etc.)
        // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
        // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
        // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
        // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            ImGui_ImplSDL2_ProcessEvent(&event);
            if (event.type == SDL_QUIT)
                done = true;
        }

        // Start the Dear ImGui frame
        ImGui_ImplOpenGL2_NewFrame();
        ImGui_ImplSDL2_NewFrame(window);
        ImGui::NewFrame();

        // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
        if (show_demo_window)
            ImGui::ShowDemoWindow(&show_demo_window);

        // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
        {
            static float f = 0.0f;
            static int counter = 0;

            ImGui::Begin("Hello, world!");                          // Create a window called "Hello, world!" and append into it.

            ImGui::Text("This is some useful text.");               // Display some text (you can use a format strings too)
            ImGui::Checkbox("Demo Window", &show_demo_window);      // Edit bools storing our window open/close state
            ImGui::Checkbox("Another Window", &show_another_window);

            ImGui::SliderFloat("float", &f, 0.0f, 1.0f);            // Edit 1 float using a slider from 0.0f to 1.0f
            ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color

            if (ImGui::Button("Button"))                            // Buttons return true when clicked (most widgets return true when edited/activated)
                counter++;
            ImGui::SameLine();
            ImGui::Text("counter = %d", counter);

            ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
            ImGui::End();
        }

        // 3. Show another simple window.
        if (show_another_window)
        {
            ImGui::Begin("Another Window", &show_another_window);   // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
            ImGui::Text("Hello from another window!");
            if (ImGui::Button("Close Me"))
                show_another_window = false;
            ImGui::End();
        }

        // Rendering
        ImGui::Render();
        glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
        glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);
        //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
        ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
        SDL_GL_SwapWindow(window);
    }

    // Cleanup
    ImGui_ImplOpenGL2_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();

    SDL_GL_DeleteContext(gl_context);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
Esempio n. 23
0
bool Render_OpenGL31::uninit()
{
    glDeleteTextures(1, &(_dummyTexture.texture));
    SDL_GL_DeleteContext(PGE_Window::glcontext);
    return true;
}
Esempio n. 24
0
void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
{
   AssertFatal( SDL_WasInit(SDL_INIT_VIDEO), "");

   PlatformGL::init(); // for hints about context creation

    // Create a dummy window & openGL context so that gl functions can be used here
   SDL_Window* tempWindow =  SDL_CreateWindow(
        "",                                // window title
        SDL_WINDOWPOS_UNDEFINED,           // initial x position
        SDL_WINDOWPOS_UNDEFINED,           // initial y position
        640,                               // width, in pixels
        480,                               // height, in pixels
        SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN // flags - see below
    );

   SDL_ClearError();
   SDL_GLContext tempContext = SDL_GL_CreateContext( tempWindow );
   if( !tempContext )
   {
       const char *err = SDL_GetError();
       Con::printf( err );
       AssertFatal(0, err );
       return;
   }

   SDL_ClearError();
   SDL_GL_MakeCurrent( tempWindow, tempContext );

   const char *err = SDL_GetError();
   if( err && err[0] )
   {
       Con::printf( err );
       AssertFatal(0, err );
   }

   //check minimun Opengl 3.2
   int major, minor;
   glGetIntegerv(GL_MAJOR_VERSION, &major);
   glGetIntegerv(GL_MINOR_VERSION, &minor);
   if( major < 3 || ( major == 3 && minor < 2 ) )
   {
      Con::errorf("GFXGLDevice: Error! Need OpenGL 3.2 at least, have %i.%i.", major, minor);
      return;
   }

   loadGLCore();
    
   GFXAdapter *toAdd = new GFXAdapter;
   toAdd->mIndex = 0;

   const char* renderer = (const char*) glGetString( GL_RENDERER );
   AssertFatal( renderer != NULL, "GL_RENDERER returned NULL!" );

   if (renderer)
   {
      dStrcpy(toAdd->mName, renderer);
      dStrncat(toAdd->mName, " OpenGL", GFXAdapter::MaxAdapterNameLen);
   }
   else
      dStrcpy(toAdd->mName, "OpenGL");

   toAdd->mType = OpenGL;
   toAdd->mShaderModel = 0.f;
   toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance;

   // Enumerate all available resolutions:
   EnumerateVideoModes(toAdd->mAvailableModes);

   // Add to the list of available adapters.
   adapterList.push_back(toAdd);

   // Cleanup window & open gl context
   SDL_DestroyWindow( tempWindow );
   SDL_GL_DeleteContext( tempContext );
}
Esempio n. 25
0
EmuWindow_SDL2::~EmuWindow_SDL2() {
    SDL_GL_DeleteContext(gl_context);
    SDL_Quit();
}
Esempio n. 26
0
int
main(int argc, char *argv[])
{
    int x,y,width, height;
    SDL_Window *win;
    SDL_GLContext glContext;
    NVGcontext *vg = NULL;

    int running = 1;
    unsigned int started;
    unsigned int dt;
    struct zr_user_font font;
    struct file_browser browser;
    const char *font_path;
    int icon_sheet;

    font_path = argv[1];
    if (argc < 2)
        die("missing argument!: <font> <icons>");

    /* SDL */
    SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    win = SDL_CreateWindow("File Explorer",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN);
    glContext = SDL_GL_CreateContext(win);
    SDL_GetWindowSize(win, &width, &height);
    SDL_GetWindowPosition(win, &x, &y);

    /* OpenGL */
    glewExperimental = 1;
    if (glewInit() != GLEW_OK)
        die("[GLEW] failed setup\n");
    glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

    /* nanovg */
    vg = nvgCreateGLES2(NVG_ANTIALIAS|NVG_DEBUG);
    if (!vg) die("[NVG]: failed to init\n");
    nvgCreateFont(vg, "fixed", font_path);
    nvgFontFace(vg, "fixed");
    nvgFontSize(vg, 14);
    nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE);

    /* GUI */
    memset(&browser, 0, sizeof browser);
    font.userdata.ptr = vg;
    nvgTextMetrics(vg, NULL, NULL, &font.height);
    font.width = font_get_width;
    file_browser_init(&browser, vg, &font, width, height);

    while (running) {
        /* Input */
        SDL_Event evt;
        started = SDL_GetTicks();
        zr_input_begin(&browser.input);
        while (SDL_PollEvent(&evt)) {
            if (evt.type == SDL_WINDOWEVENT) resize(&evt);
            else if (evt.type == SDL_QUIT) goto cleanup;
            else if (evt.type == SDL_KEYUP) key(&browser.input, &evt, zr_false);
            else if (evt.type == SDL_KEYDOWN) key(&browser.input, &evt, zr_true);
            else if (evt.type == SDL_MOUSEBUTTONDOWN) btn(&browser.input, &evt, zr_true);
            else if (evt.type == SDL_MOUSEBUTTONUP) btn(&browser.input, &evt, zr_false);
            else if (evt.type == SDL_MOUSEMOTION) motion(&browser.input, &evt);
            else if (evt.type == SDL_TEXTINPUT) text(&browser.input, &evt);
            else if (evt.type == SDL_MOUSEWHEEL) zr_input_scroll(&browser.input, evt.wheel.y);
        }
        zr_input_end(&browser.input);

        SDL_GetWindowSize(win, &width, &height);
        running = file_browser_run(&browser, width, height);

        /* Draw */
        glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        draw(vg, &browser.queue, width, height);
        SDL_GL_SwapWindow(win);
    }

cleanup:
    /* Cleanup */
    free(browser.memory);
    nvgDeleteGLES2(vg);
    SDL_GL_DeleteContext(glContext);
    SDL_DestroyWindow(win);
    SDL_Quit();
    return 0;
}
Esempio n. 27
0
bool GraphicsManager::setFSAA(int level) {
	// Force calling it from the main thread
	if (!Common::isMainThread()) {
		Events::MainThreadFunctor<bool> functor(boost::bind(&GraphicsManager::setFSAA, this, level));

		return RequestMan.callInMainThread(functor);
	}

	if (_fsaa == level)
		// Nothing to do
		return true;

	// Check if we have the support for that level
	if (level > _fsaaMax)
		return false;

	// Backup the old level and set the new level
	int oldFSAA = _fsaa;
	_fsaa = level;

	destroyContext();

	uint32 flags = SDL_GetWindowFlags(_screen);

	int x, y;
	SDL_GetWindowPosition(_screen, &x, &y);

	SDL_GL_DeleteContext(_glContext);
	SDL_DestroyWindow(_screen);

	// Set the multisample level
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (_fsaa > 0) ? 1 : 0);
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, _fsaa);

	// Now try to change the screen
	_screen = SDL_CreateWindow(_windowTitle.c_str(), x, y, _width, _height, flags);

	if (!_screen) {
		// Failed changing, back up

		_fsaa = oldFSAA;

		// Set the multisample level
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (_fsaa > 0) ? 1 : 0);
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, _fsaa);
		_screen = SDL_CreateWindow(_windowTitle.c_str(), x, y, _width, _height, flags);

		// There's no reason how this could possibly fail, but ok...
		if (!_screen)
			throw Common::Exception("Failed reverting to the old FSAA settings");
	}

	setWindowIcon(*_screen);

	// Initial call to setupSDLGL has already identified which GL context we can use.
	if (_gl3) {
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, _glProfile);
	} else {
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, _glProfile);
	}
	_glContext = SDL_GL_CreateContext(_screen);
	rebuildContext();

	return _fsaa == level;
}
Esempio n. 28
0
/*
 * Initializes the OpenGL window
 */
static qboolean
GLimp_InitGraphics(qboolean fullscreen)
{
	int flags;
	int msaa_samples;
	int stencil_bits;
	int width, height;
	char title[24];

	if (GetWindowSize(&width, &height) && (width == vid.width) && (height == vid.height))
	{
		/* If we want fullscreen, but aren't */
		if (fullscreen != IsFullscreen())
		{
#if SDL_VERSION_ATLEAST(2, 0, 0)
			SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
#else
			SDL_WM_ToggleFullScreen(window);
#endif

			Cvar_SetValue("vid_fullscreen", fullscreen);
		}

		/* Are we now? */
		if (fullscreen == IsFullscreen())
		{
			return true;
		}
	}

	/* Is the surface used? */
	if (window)
	{
#if SDL_VERSION_ATLEAST(2, 0, 0)
		SDL_GL_DeleteContext(context);
		SDL_DestroyWindow(window);
#else
		SDL_FreeSurface(window);
#endif
	}

	/* Create the window */
	VID_NewWindow(vid.width, vid.height);

	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_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

	if ((int)Cvar_VariableValue("cl_stereo") == 1){
		SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
	} else {
		SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
	}

	if (gl_msaa_samples->value)
	{
		msaa_samples = gl_msaa_samples->value;

		if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) < 0)
		{
			Com_Printf("MSAA is unsupported: %s\n", SDL_GetError());
			Cvar_SetValue ("gl_msaa_samples", 0);
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
		}
		else if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples) < 0)
		{
			Com_Printf("MSAA %ix is unsupported: %s\n", msaa_samples, SDL_GetError());
			Cvar_SetValue("gl_msaa_samples", 0);
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
		}
	}

	/* Initiate the flags */
	flags = SDL_OPENGL;

	if (fullscreen)
	{
		flags |= SDL_FULLSCREEN;
	}

#if !SDL_VERSION_ATLEAST(2, 0, 0)
	/* For SDL1.2, these things must be done before creating the window */

	/* Set the icon */
	SetSDLIcon();

	/* Set vsync */
	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, gl_swapinterval->value ? 1 : 0);
#endif

	while (1)
	{
		if (!CreateSDLWindow(flags))
		{
			if (gl_msaa_samples->value)
			{
				VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n",
						SDL_GetError());
				VID_Printf(PRINT_ALL, "Reverting to %s gl_mode %i (%ix%i) without MSAA.\n",
						(flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed",
						(int)Cvar_VariableValue("gl_mode"), vid.width, vid.height);

				/* Try to recover */
				Cvar_SetValue("gl_msaa_samples", 0);
				SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
				SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
			}
			else if ((int)Cvar_VariableValue("cl_stereo") == 1) {
				VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n", SDL_GetError());
				Cvar_SetValue("cl_stereo", 0);
				SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
			}
			else if (vid.width != 640 || vid.height != 480 || (flags & SDL_FULLSCREEN))
			{
				VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n",
						SDL_GetError());
				VID_Printf(PRINT_ALL, "Reverting to windowed gl_mode 4 (640x480).\n");

				/* Try to recover */
				Cvar_SetValue("gl_mode", 4);
				Cvar_SetValue("vid_fullscreen", 0);
				vid.width = 640;
				vid.height = 480;
				flags &= ~SDL_FULLSCREEN;
			}
			else
			{
				VID_Error(ERR_FATAL, "Failed to revert to gl_mode 4. Exiting...\n");
				return false;
			}
		}
		else
		{
			break;
		}
	}
	if (gl_msaa_samples->value)
	{
		if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples) == 0)
		{
			Cvar_SetValue("gl_msaa_samples", msaa_samples);
		}
	}

#if SDL_VERSION_ATLEAST(2, 0, 0)
	/* For SDL2, these things must be done after creating the window */

	/* Set the icon */
	SetSDLIcon();

	/* Set vsync - TODO: -1 could be set for "late swap tearing" */
	SDL_GL_SetSwapInterval(gl_swapinterval->value ? 1 : 0);
#endif

	/* Initialize the stencil buffer */
	if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits))
	{
		VID_Printf(PRINT_ALL, "Got %d bits of stencil.\n", stencil_bits);

		if (stencil_bits >= 1)
		{
			have_stencil = true;
		}
	}

	/* Initialize hardware gamma */
	InitGamma();

	/* Window title */
	snprintf(title, sizeof(title), "Yamagi Quake II %s", YQ2VERSION);
#if SDL_VERSION_ATLEAST(2, 0, 0)
	SDL_SetWindowTitle(window, title);
#else
	SDL_WM_SetCaption(title, title);
#endif

	/* No cursor */
	SDL_ShowCursor(0);

	return true;
}
Esempio n. 29
0
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
	const char *glstring;
	int perChannelColorBits;
	int colorBits, depthBits, stencilBits;
	//int samples;
	int i = 0;
	SDL_Surface *icon = NULL;
	Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
	SDL_DisplayMode desktopMode;
	int display = 0;
	int x = 0, y = 0;

	Com_Printf( "Initializing OpenGL display\n");

	if ( r_allowResize->integer )
		flags |= SDL_WINDOW_RESIZABLE;

	/*icon = SDL_CreateRGBSurfaceFrom(
			(void *)CLIENT_WINDOW_ICON.pixel_data,
			CLIENT_WINDOW_ICON.width,
			CLIENT_WINDOW_ICON.height,
			CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
			CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
			0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
			0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
			);*/

	// If a window exists, note its display index
	if( screen != NULL )
		display = SDL_GetWindowDisplayIndex( screen );

	if( SDL_GetDesktopDisplayMode( display, &desktopMode ) == 0 )
	{
		displayAspect = (float)desktopMode.w / (float)desktopMode.h;

		Com_Printf( "Display aspect: %.3f\n", displayAspect );
	}
	else
	{
		memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) );

		Com_Printf( "Cannot determine display aspect, assuming 1.333\n" );
	}

	Com_Printf( "...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( desktopMode.h > 0 )
		{
			glConfig.vidWidth = desktopMode.w;
			glConfig.vidHeight = desktopMode.h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			Com_Printf( "Cannot determine display resolution, assuming 640x480\n" );
		}

		//glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, /*&glConfig.windowAspect,*/ mode ) )
	{
		Com_Printf( " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	Com_Printf( " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	// Center window
	if( r_centerWindow->integer && !fullscreen )
	{
		x = ( desktopMode.w / 2 ) - ( glConfig.vidWidth / 2 );
		y = ( desktopMode.h / 2 ) - ( glConfig.vidHeight / 2 );
	}

	// Destroy existing state if it exists
	if( opengl_context != NULL )
	{
		SDL_GL_DeleteContext( opengl_context );
		opengl_context = NULL;
	}

	if( screen != NULL )
	{
		SDL_GetWindowPosition( screen, &x, &y );
		Com_DPrintf( "Existing window at %dx%d before being destroyed\n", x, y );
		SDL_DestroyWindow( screen );
		screen = NULL;
	}

	if( fullscreen )
	{
		flags |= SDL_WINDOW_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if( noborder )
			flags |= SDL_WINDOW_BORDERLESS;

		glConfig.isFullscreen = qfalse;
	}

	colorBits = r_colorbits->value;
	if ((!colorBits) || (colorBits >= 32))
		colorBits = 24;

	if (!r_depthbits->value)
		depthBits = 24;
	else
		depthBits = r_depthbits->value;

	stencilBits = r_stencilbits->value;
	//samples = r_ext_multisample->value;

	for (i = 0; i < 16; i++)
	{
		int testColorBits, testDepthBits, testStencilBits;

		// 0 - default
		// 1 - minus colorBits
		// 2 - minus depthBits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
				case 2 :
					if (colorBits == 24)
						colorBits = 16;
					break;
				case 1 :
					if (depthBits == 24)
						depthBits = 16;
					else if (depthBits == 16)
						depthBits = 8;
				case 3 :
					if (stencilBits == 24)
						stencilBits = 16;
					else if (stencilBits == 16)
						stencilBits = 8;
			}
		}

		testColorBits = colorBits;
		testDepthBits = depthBits;
		testStencilBits = stencilBits;

		if ((i % 4) == 3)
		{ // reduce colorBits
			if (testColorBits == 24)
				testColorBits = 16;
		}

		if ((i % 4) == 2)
		{ // reduce depthBits
			if (testDepthBits == 24)
				testDepthBits = 16;
			else if (testDepthBits == 16)
				testDepthBits = 8;
		}

		if ((i % 4) == 1)
		{ // reduce stencilBits
			if (testStencilBits == 24)
				testStencilBits = 16;
			else if (testStencilBits == 16)
				testStencilBits = 8;
			else
				testStencilBits = 0;
		}

		if (testColorBits == 24)
			perChannelColorBits = 8;
		else
			perChannelColorBits = 4;

#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
		if (perChannelColorBits == 4)
			perChannelColorBits = 0; /* Use minimum size for 16-bit color */

		/* Need alpha or else SGIs choose 36+ bit RGB mode */
		SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits );

		/*SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );*/

		if(r_stereo->integer)
		{
			glConfig.stereoEnabled = qtrue;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
		}
		else
		{
			glConfig.stereoEnabled = qfalse;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		}

		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

		// If not allowing software GL, demand accelerated
		if( !r_allowSoftwareGL->integer )
			SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );

		if( ( screen = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y,
				glConfig.vidWidth, glConfig.vidHeight, flags ) ) == 0 )
		{
			Com_DPrintf( "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
			continue;
		}

		if( fullscreen )
		{
			SDL_DisplayMode mode;

			switch( testColorBits )
			{
				case 16: mode.format = SDL_PIXELFORMAT_RGB565; break;
				case 24: mode.format = SDL_PIXELFORMAT_RGB24;  break;
				default: Com_DPrintf( "testColorBits is %d, can't fullscreen\n", testColorBits ); continue;
			}

			mode.w = glConfig.vidWidth;
			mode.h = glConfig.vidHeight;
			mode.refresh_rate = glConfig.displayFrequency = ri.Cvar_VariableIntegerValue( "r_displayRefresh" );
			mode.driverdata = NULL;

			if( SDL_SetWindowDisplayMode( screen, &mode ) < 0 )
			{
				Com_DPrintf( "SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError( ) );
				continue;
			}
		}

		SDL_SetWindowTitle( screen, CLIENT_WINDOW_TITLE );
		SDL_SetWindowIcon( screen, icon );

		if( ( opengl_context = (QGLContext)SDL_GL_CreateContext( screen ) ) == NULL )
		{
			Com_Printf( "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
			continue;
		}

		if( SDL_GL_MakeCurrent( screen, opengl_context ) < 0 )
		{
			Com_Printf( "SDL_GL_MakeCurrent failed: %s\n", SDL_GetError( ) );
			continue;
		}

		SDL_GL_SetSwapInterval( r_swapInterval->integer );

		glConfig.colorBits = testColorBits;
		glConfig.depthBits = testDepthBits;
		glConfig.stencilBits = testStencilBits;

		Com_Printf( "Using %d color bits, %d depth, %d stencil display.\n",
				glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
		break;
	}

	/*SDL_FreeSurface( icon );*/

	GLimp_DetectAvailableModes();

	glstring = (char *) qglGetString (GL_RENDERER);
	Com_Printf( "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
#if 0
	const char*   glstring;
	int sdlcolorbits;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int samples;
	int i = 0;
	Uint32 flags = SDL_WINDOW_OPENGL;

	Com_Printf( "Initializing OpenGL display\n");

	if ( r_allowResize->integer )
		flags |= SDL_WINDOW_RESIZABLE;

	if( videoInfo == NULL )
	{
		static SDL_DisplayMode sVideoInfo;
		static SDL_PixelFormat sPixelFormat;

		if (SDL_GetCurrentDisplayMode( 0, &sVideoInfo ) < 0)
		  Com_Error(ERR_FATAL, "SDL_GetCurrentDisplayMode failed : %s\n", SDL_GetError());

		// Take a copy of the videoInfo
		sPixelFormat.format = sVideoInfo.format;
		sPixelFormat.palette = NULL; // Should already be the case
		//Com_Memcpy( &sVideoInfo, videoInfo, sizeof( SDL_DisplayMode ) );
		sVideoInfo.format = sPixelFormat.format;
		videoInfo = &sVideoInfo;

		if( videoInfo->h > 0 )
		{
			glConfig.displayWidth = videoInfo->w;
			glConfig.displayHeight = videoInfo->h;

			// Guess the display aspect ratio through the desktop resolution
			// by assuming (relatively safely) that it is set at or close to
			// the display's native aspect ratio
			glConfig.displayAspect = (float)videoInfo->w / (float)videoInfo->h;

			Com_Printf( "Estimated display aspect: %.3f\n", glConfig.displayAspect );
		}
		else
		{
			glConfig.displayWidth = 480;
			glConfig.displayHeight = 640;
			glConfig.displayAspect = 1.333f;

			Com_Printf(
					"Cannot estimate display resolution/aspect, assuming 640x480/1.333\n" );
		}
	}

	Com_Printf( "...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( videoInfo->h > 0 )
		{
			glConfig.vidWidth = videoInfo->w;
			glConfig.vidHeight = videoInfo->h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			Com_Printf(
					"Cannot determine display resolution, assuming 640x480\n" );
		}

		glConfig.displayAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, /*&glConfig.displayAspect,*/ mode ) )
	{
		Com_Printf( " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	Com_Printf( " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	if (fullscreen)
	{
		flags |= SDL_WINDOW_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if (noborder)
			flags |= SDL_WINDOW_BORDERLESS;

		glConfig.isFullscreen = qfalse;
	}

	colorbits = r_colorbits->value;
	if ((!colorbits) || (colorbits >= 32))
		colorbits = 24;

	if (!r_depthbits->value)
		depthbits = 24;
	else
		depthbits = r_depthbits->value;
	stencilbits = r_stencilbits->value;
	//samples = r_ext_multisample->value;

	for (i = 0; i < 16; i++)
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
				case 2 :
					if (colorbits == 24)
						colorbits = 16;
					break;
				case 1 :
					if (depthbits == 24)
						depthbits = 16;
					else if (depthbits == 16)
						depthbits = 8;
				case 3 :
					if (stencilbits == 24)
						stencilbits = 16;
					else if (stencilbits == 16)
						stencilbits = 8;
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ((i % 4) == 3)
		{ // reduce colorbits
			if (tcolorbits == 24)
				tcolorbits = 16;
		}

		if ((i % 4) == 2)
		{ // reduce depthbits
			if (tdepthbits == 24)
				tdepthbits = 16;
			else if (tdepthbits == 16)
				tdepthbits = 8;
		}

		if ((i % 4) == 1)
		{ // reduce stencilbits
			if (tstencilbits == 24)
				tstencilbits = 16;
			else if (tstencilbits == 16)
				tstencilbits = 8;
			else
				tstencilbits = 0;
		}

		sdlcolorbits = 4;
		if (tcolorbits == 24)
			sdlcolorbits = 8;

#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
		if (sdlcolorbits == 4)
			sdlcolorbits = 0; /* Use minimum size for 16-bit color */

		/* Need alpha or else SGIs choose 36+ bit RGB mode */
		SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );

		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );

		/*if(r_stereoEnabled->integer)
		{
			glConfig.stereoEnabled = qtrue;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
		}
		else
		{*/
			glConfig.stereoEnabled = qfalse;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		//}

		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

#if 0 // See http://bugzilla.icculus.org/show_bug.cgi?id=3526
		// If not allowing software GL, demand accelerated
		if( !r_allowSoftwareGL->integer )
		{
			if( SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ) < 0 )
			{
				Com_Printf( "Unable to guarantee accelerated "
						"visual with libSDL < 1.2.10\n" );
			}
		}
#endif

		if( SDL_GL_SetSwapInterval(r_swapInterval->integer ) < 0 )
			Com_Printf( "SDL_GL_SetSwapInterval not supported\n" );

#ifdef USE_ICON
		{
			SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
					(void *)CLIENT_WINDOW_ICON.pixel_data,
					CLIENT_WINDOW_ICON.width,
					CLIENT_WINDOW_ICON.height,
					CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
					CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
					0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
					0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
					);

			SDL_WM_SetIcon( icon, NULL );
			SDL_FreeSurface( icon );
		}
#endif

		// FIXME: Product name
		cvar_t *com_productName = ri.Cvar_Get("com_productName", "OpenJK" /* PRODUCT_NAME */, CVAR_ROM);
		//SDL_SetWindowTitle(com_productName->string, com_productName->string);
		SDL_ShowCursor(0);

		if (!(window = SDL_CreateWindow(com_productName->string, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, glConfig.vidWidth, glConfig.vidHeight, flags)))
		{
			Com_Printf( "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
			continue;
		}

		opengl_context = SDL_GL_CreateContext(window);

		Com_Printf( "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	GLimp_DetectAvailableModes();

	if (!window)
	{
		Com_Printf( "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	screen = window;

	// FIXME: Defines needed here
	glstring = (char *) qglGetString (GL_RENDERER);
	Com_Printf( "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
#endif
}
Esempio n. 30
0
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
	const char *glstring;
	int perChannelColorBits;
	int colorBits, depthBits, stencilBits;
	int samples;
	int i = 0;
	SDL_Surface *icon = NULL;
	Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
	SDL_DisplayMode desktopMode;
	int display = 0;
	int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");

	if ( r_allowResize->integer )
		flags |= SDL_WINDOW_RESIZABLE;

#ifdef USE_ICON
	icon = SDL_CreateRGBSurfaceFrom(
			(void *)CLIENT_WINDOW_ICON.pixel_data,
			CLIENT_WINDOW_ICON.width,
			CLIENT_WINDOW_ICON.height,
			CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
			CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
			0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
			0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
			);
#endif

	// If a window exists, note its display index
	if( SDL_window != NULL )
		display = SDL_GetWindowDisplayIndex( SDL_window );

	if( SDL_GetDesktopDisplayMode( display, &desktopMode ) == 0 )
	{
		displayAspect = (float)desktopMode.w / (float)desktopMode.h;

		ri.Printf( PRINT_ALL, "Display aspect: %.3f\n", displayAspect );
	}
	else
	{
		Com_Memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) );

		ri.Printf( PRINT_ALL,
				"Cannot determine display aspect, assuming 1.333\n" );
	}

	ri.Printf (PRINT_ALL, "...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( desktopMode.h > 0 )
		{
			glConfig.vidWidth = desktopMode.w;
			glConfig.vidHeight = desktopMode.h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			ri.Printf( PRINT_ALL,
					"Cannot determine display resolution, assuming 640x480\n" );
		}

		glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	// Center window
	if( r_centerWindow->integer && !fullscreen )
	{
		x = ( desktopMode.w / 2 ) - ( glConfig.vidWidth / 2 );
		y = ( desktopMode.h / 2 ) - ( glConfig.vidHeight / 2 );
	}

	// Destroy existing state if it exists
	if( SDL_glContext != NULL )
	{
		SDL_GL_DeleteContext( SDL_glContext );
		SDL_glContext = NULL;
	}

	if( SDL_window != NULL )
	{
		SDL_GetWindowPosition( SDL_window, &x, &y );
		ri.Printf( PRINT_DEVELOPER, "Existing window at %dx%d before being destroyed\n", x, y );
		SDL_DestroyWindow( SDL_window );
		SDL_window = NULL;
	}

	if( fullscreen )
	{
		flags |= SDL_WINDOW_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if( noborder )
			flags |= SDL_WINDOW_BORDERLESS;

		glConfig.isFullscreen = qfalse;
	}

	colorBits = r_colorbits->value;
	if ((!colorBits) || (colorBits >= 32))
		colorBits = 24;

	if (!r_depthbits->value)
		depthBits = 24;
	else
		depthBits = r_depthbits->value;

	stencilBits = r_stencilbits->value;
	samples = r_ext_multisample->value;

	for (i = 0; i < 16; i++)
	{
		int testColorBits, testDepthBits, testStencilBits;

		// 0 - default
		// 1 - minus colorBits
		// 2 - minus depthBits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
				case 2 :
					if (colorBits == 24)
						colorBits = 16;
					break;
				case 1 :
					if (depthBits == 24)
						depthBits = 16;
					else if (depthBits == 16)
						depthBits = 8;
				case 3 :
					if (stencilBits == 24)
						stencilBits = 16;
					else if (stencilBits == 16)
						stencilBits = 8;
			}
		}

		testColorBits = colorBits;
		testDepthBits = depthBits;
		testStencilBits = stencilBits;

		if ((i % 4) == 3)
		{ // reduce colorBits
			if (testColorBits == 24)
				testColorBits = 16;
		}

		if ((i % 4) == 2)
		{ // reduce depthBits
			if (testDepthBits == 24)
				testDepthBits = 16;
			else if (testDepthBits == 16)
				testDepthBits = 8;
		}

		if ((i % 4) == 1)
		{ // reduce stencilBits
			if (testStencilBits == 24)
				testStencilBits = 16;
			else if (testStencilBits == 16)
				testStencilBits = 8;
			else
				testStencilBits = 0;
		}

		if (testColorBits == 24)
			perChannelColorBits = 8;
		else
			perChannelColorBits = 4;

#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
		if (perChannelColorBits == 4)
			perChannelColorBits = 0; /* Use minimum size for 16-bit color */

		/* Need alpha or else SGIs choose 36+ bit RGB mode */
		SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits );

		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );

		if(r_stereoEnabled->integer)
		{
			glConfig.stereoEnabled = qtrue;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
		}
		else
		{
			glConfig.stereoEnabled = qfalse;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		}
		
		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

#if 0 // if multisampling is enabled on X11, this causes create window to fail.
		// If not allowing software GL, demand accelerated
		if( !r_allowSoftwareGL->integer )
			SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
#endif

		if( ( SDL_window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y,
				glConfig.vidWidth, glConfig.vidHeight, flags ) ) == 0 )
		{
			ri.Printf( PRINT_DEVELOPER, "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
			continue;
		}

		if( fullscreen )
		{
			SDL_DisplayMode mode;

			switch( testColorBits )
			{
				case 16: mode.format = SDL_PIXELFORMAT_RGB565; break;
				case 24: mode.format = SDL_PIXELFORMAT_RGB24;  break;
				default: ri.Printf( PRINT_DEVELOPER, "testColorBits is %d, can't fullscreen\n", testColorBits ); continue;
			}

			mode.w = glConfig.vidWidth;
			mode.h = glConfig.vidHeight;
			mode.refresh_rate = glConfig.displayFrequency = ri.Cvar_VariableIntegerValue( "r_displayRefresh" );
			mode.driverdata = NULL;

			if( SDL_SetWindowDisplayMode( SDL_window, &mode ) < 0 )
			{
				ri.Printf( PRINT_DEVELOPER, "SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError( ) );
				continue;
			}
		}

		SDL_SetWindowIcon( SDL_window, icon );

		if( ( SDL_glContext = SDL_GL_CreateContext( SDL_window ) ) == NULL )
		{
			ri.Printf( PRINT_DEVELOPER, "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
			continue;
		}

		qglClearColor( 0, 0, 0, 1 );
		qglClear( GL_COLOR_BUFFER_BIT );
		SDL_GL_SwapWindow( SDL_window );

		SDL_GL_SetSwapInterval( r_swapInterval->integer );

		glConfig.colorBits = testColorBits;
		glConfig.depthBits = testDepthBits;
		glConfig.stencilBits = testStencilBits;

		ri.Printf( PRINT_ALL, "Using %d color bits, %d depth, %d stencil display.\n",
				glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
		break;
	}

	SDL_FreeSurface( icon );

	if( !SDL_window )
	{
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	GLimp_DetectAvailableModes();

	glstring = (char *) qglGetString (GL_RENDERER);
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
}