コード例 #1
0
ファイル: mesh.c プロジェクト: Ckef/Groufix
void gfx_mesh_set_index_buffer(

		const GFXMesh*  mesh,
		GFXMeshLayout   layout,
		GFXMeshBuffer   buffer,
		size_t          offset)
{
	GFX_Mesh* internal =
		(GFX_Mesh*)mesh;
	GFXVertexLayout* lay =
		_gfx_mesh_get_layout(internal, layout - 1);

	/* Pass buffer to vertex layout */
	GFXSharedBuffer* buff = (GFXSharedBuffer*)gfx_vector_at(
		&internal->buffers,
		buffer - 1);

	gfx_vertex_layout_set_shared_index_buffer(
		lay,
		buff,
		offset);
}
コード例 #2
0
ファイル: lod_map.c プロジェクト: Ckef/Groufix
static unsigned int _gfx_lod_map_find_data(

		const GFX_LodMap*   map,
		unsigned int        begin,
		unsigned int        end,
		const void*         data,
		GFXVectorIterator*  found)
{
	/* Find the data and count */
	GFXVectorIterator it = gfx_vector_at(&map->data, begin);

	while(begin != end)
	{
		if(!memcmp(it, data, map->map.compSize)) break;

		++begin;
		it = gfx_vector_next(&map->data, it);
	}
	*found = it;

	return begin;
}
コード例 #3
0
ファイル: lod_map.c プロジェクト: Ckef/Groufix
unsigned int gfx_lod_map_has(

		const GFXLodMap*  map,
		unsigned int      level,
		const void*       data)
{
	if(level >= map->levels) return 0;

	const GFX_LodMap* internal =
		(const GFX_LodMap*)map;
	GFXVectorIterator it = gfx_vector_at(
		&internal->levels,
		level);

	/* Get boundaries */
	unsigned int begin;
	unsigned int end;
	_gfx_lod_map_get_boundaries(
		internal,
		it,
		&begin,
		&end
	);

	/* Find all instances */
	unsigned int count;
	for(count = 0; begin != end; ++count)
	{
		begin = _gfx_lod_map_find_data(
			internal,
			begin,
			end,
			data,
			&it
		);
	}

	return count;
}
コード例 #4
0
static int _gfx_thread_pool_push(

		GFX_Pool*  pool,
		GFX_Task   task)
{
	/* Insert the new element */
	size_t elem = gfx_vector_get_size(&pool->tasks);

	GFX_Task* et = gfx_vector_insert(
		&pool->tasks,
		&task,
		pool->tasks.end
	);

	if(et == pool->tasks.end) return 0;

	/* Correct heap again */
	while(elem > 0)
	{
		/* Get parent and compare */
		size_t parent = (elem - 1) >> 1;
		GFX_Task* pt = gfx_vector_at(&pool->tasks, parent);

		if(pt->priority <= et->priority)
			break;

		/* Swap */
		task = *pt;
		*pt = *et;
		*et = task;

		elem = parent;
	}

	return 1;
}
コード例 #5
0
GFX_PlatformWindow _gfx_platform_window_create(

		const GFX_PlatformAttributes* attributes)
{
	/* Setup the x11 window */
	GFX_X11_Window window;
	window.monitor = attributes->monitor;
	window.context = NULL;
	window.flags   = 0;

	window.flags |=
		attributes->flags & GFX_WINDOW_RESIZABLE ?
		GFX_X11_RESIZABLE : 0;
	window.flags |=
		attributes->flags & GFX_WINDOW_HIDDEN ?
		GFX_X11_HIDDEN : 0;

	/* Get display mode & position */
	GFXDisplayMode mode;
	int x = window.monitor->x;
	int y = window.monitor->y;

	if(attributes->flags & GFX_WINDOW_FULLSCREEN)
	{
		window.flags |= GFX_X11_FULLSCREEN;

		GFX_X11_Mode* it = gfx_vector_at(
			&_gfx_x11.modes,
			window.monitor->modes[attributes->mode]
		);

		window.mode = it->id;
		mode = it->mode;
	}
	else
	{
		mode.width  = attributes->w;
		mode.height = attributes->h;
		mode.depth  = *attributes->depth;

		x += attributes->x;
		y += attributes->y;
	}

	/* Get FB Config */
	GLXFBConfig* config = _gfx_x11_get_config(
		window.monitor->screen,
		&mode.depth,
		attributes->flags & GFX_WINDOW_DOUBLE_BUFFER
	);

	if(!config) return NULL;

	/* Get visual from config */
	XVisualInfo* visual = glXGetVisualFromFBConfig(
		_gfx_x11.display,
		*config
	);

	window.config = *config;
	XFree(config);

	/* Create the window attributes */
	unsigned long mask = CWColormap | CWEventMask;
	XSetWindowAttributes attr;

	if(
		attributes->flags & GFX_WINDOW_BORDERLESS ||
		attributes->flags & GFX_WINDOW_FULLSCREEN)
	{
		/* Borderless window */
		mask |= CWBorderPixel;
		attr.border_pixel = 0;
	}

	/* Event mask & Color map */
	Window root =
		XRootWindowOfScreen(window.monitor->screen);

	attr.event_mask =
		KeyPressMask |
		KeyReleaseMask |
		PointerMotionMask |
		EnterWindowMask |
		LeaveWindowMask |
		ButtonPressMask |
		ButtonReleaseMask |
		StructureNotifyMask |
		FocusChangeMask;

	attr.colormap = XCreateColormap(
		_gfx_x11.display,
		root,
		visual->visual,
		AllocNone
	);

	/* Create the actual window */
	window.handle = XCreateWindow(
		_gfx_x11.display,
		root,
		x,
		y,
		mode.width,
		mode.height,
		0,
		visual->depth,
		InputOutput,
		visual->visual,
		mask,
		&attr
	);

	XFree(visual);

	if(window.handle)
	{
		/* Get properties to check for events */
		XWindowAttributes get;
		get.x      = 0;
		get.y      = 0;
		get.width  = 0;
		get.height = 0;
		XGetWindowAttributes(_gfx_x11.display, window.handle, &get);

		window.x      = get.x;
		window.y      = get.y;
		window.width  = get.width;
		window.height = get.height;

		/* Delete protocol & name */
		XSetWMProtocols(
			_gfx_x11.display,
			window.handle,
			&_gfx_x11.WM_DELETE_WINDOW,
			1);

		XStoreName(
			_gfx_x11.display,
			window.handle,
			attributes->name);

		/* Disable decorations */
		if(mask & CWBorderPixel)
		{
			unsigned long hints[5];
			hints[0] = MWM_HINTS_DECORATIONS;
			hints[2] = 0;

			XChangeProperty(
				_gfx_x11.display,
				window.handle,
				_gfx_x11.MOTIF_WM_HINTS,
				_gfx_x11.MOTIF_WM_HINTS,
				32,
				PropModeReplace,
				(unsigned char*)hints,
				5);
		}

		/* Bypass compositor */
		if(attributes->flags & GFX_WINDOW_FULLSCREEN)
		{
			unsigned long bypass = 1;

			XChangeProperty(
				_gfx_x11.display,
				window.handle,
				_gfx_x11.NET_WM_BYPASS_COMPOSITOR,
				XA_CARDINAL,
				32,
				PropModeReplace,
				(unsigned char*)&bypass,
				1
			);
		}

		/* Set size hints */
		if(!(attributes->flags & GFX_WINDOW_RESIZABLE))
		{
			XSizeHints* hints = XAllocSizeHints();
			hints->flags = PMinSize | PMaxSize;

			hints->min_width = mode.width;
			hints->max_width = mode.width;
			hints->min_height = mode.height;
			hints->max_height = mode.height;

			XSetWMNormalHints(_gfx_x11.display, window.handle, hints);

			XFree(hints);
		}

		/* Add window to vector */
		GFXVectorIterator it = gfx_vector_insert(
			&_gfx_x11.windows,
			&window,
			_gfx_x11.windows.end
		);

		if(it != _gfx_x11.windows.end)
		{
			/* Make it visible */
			/* Triggers FocusIn event for fullscreen */
			if(!(attributes->flags & GFX_WINDOW_HIDDEN))
				XMapWindow(_gfx_x11.display, window.handle);

			return GFX_UINT_TO_VOID(window.handle);
		}

		XDestroyWindow(_gfx_x11.display, window.handle);
	}

	XFreeColormap(_gfx_x11.display, attr.colormap);

	return NULL;
}
コード例 #6
0
GFX_PlatformWindow _gfx_platform_window_create(

		const GFX_PlatformAttributes* attributes)
{
	/* Setup the win32 window */
	GFX_Win32_Window window;
	window.monitor = attributes->monitor;
	window.context = NULL;
	window.flags   = 0;

	window.flags |=
		attributes->flags & GFX_WINDOW_RESIZABLE ?
		GFX_WIN32_RESIZABLE : 0;
	window.flags |=
		attributes->flags & GFX_WINDOW_HIDDEN ?
		GFX_WIN32_HIDDEN : 0;

	/* Display mode, style and window rectangle */
	DWORD styleEx =
		WS_EX_APPWINDOW;
	DWORD style =
		(!(attributes->flags & GFX_WINDOW_HIDDEN) ?
		WS_VISIBLE : 0);

	GFXColorDepth depth;
	RECT rect;

	rect.left = window.monitor->x;
	rect.top = window.monitor->y;

	if(attributes->flags & GFX_WINDOW_FULLSCREEN)
	{
		/* Display mode */
		window.flags |= GFX_WIN32_FULLSCREEN;

		window.mode = gfx_vector_at(
			&_gfx_win32.modes,
			window.monitor->modes + attributes->mode);

		_gfx_split_depth(
			window.mode->dmBitsPerPel,
			&depth.redBits,
			&depth.greenBits,
			&depth.blueBits);

		/* Style and rectangle */
		rect.right = window.mode->dmPelsWidth;
		rect.bottom = window.mode->dmPelsHeight;

		styleEx |= WS_EX_TOPMOST;
		style |= WS_POPUP;
	}
	else
	{
		/* Color depth and rectangle */
		depth       = *attributes->depth;
		rect.right  = attributes->w;
		rect.bottom = attributes->h;

		rect.left += attributes->x;
		rect.top += attributes->y;

		/* Style */
		style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

		if(!(attributes->flags & GFX_WINDOW_BORDERLESS))
		{
			/* With a border */
			styleEx |=
				WS_EX_WINDOWEDGE;

			style |=
				WS_CAPTION |
				WS_MINIMIZEBOX |
				WS_OVERLAPPED |
				WS_SYSMENU;

			/* With size options */
			if(attributes->flags & GFX_WINDOW_RESIZABLE) style |=
				WS_MAXIMIZEBOX |
				WS_SIZEBOX;
		}
		else
		{
			/* Borderless */
			styleEx |= WS_EX_TOPMOST;
			style |= WS_POPUP;
		}
	}

	rect.right += rect.left;
	rect.bottom += rect.top;

	/* Make sure the client area is the specified size */
	AdjustWindowRectEx(&rect, style, FALSE, styleEx);

	/* Convert name to UTF-16 */
	WCHAR* name = _gfx_win32_utf8_to_utf16(attributes->name);

	/* Create the actual window */
	window.handle = CreateWindowEx(
		styleEx,
		GFX_WIN32_WINDOW_CLASS,
		name,
		style,
		rect.left,
		rect.top,
		rect.right - rect.left,
		rect.bottom - rect.top,
		NULL,
		NULL,
		GetModuleHandle(NULL),
		NULL
	);

	free(name);

	if(window.handle)
	{
		/* Add window to vector */
		GFXVectorIterator it = gfx_vector_insert(
			&_gfx_win32.windows,
			&window,
			_gfx_win32.windows.end
		);

		if(it != _gfx_win32.windows.end)
		{
			/* Set pixel format */
			_gfx_win32_set_pixel_format(
				window.handle,
				&depth,
				attributes->flags & GFX_WINDOW_DOUBLE_BUFFER
			);

			/* Start tracking the mouse */
			_gfx_win32_track_mouse(window.handle);

			/* Enter fullscreen */
			if(
				(attributes->flags & GFX_WINDOW_FULLSCREEN) &&
				!(attributes->flags & GFX_WINDOW_HIDDEN))
			{
				_gfx_win32_enter_fullscreen(window.monitor, window.mode);
			}

			return window.handle;
		}

		DestroyWindow(window.handle);
	}

	return NULL;
}
コード例 #7
0
static int _gfx_x11_init_monitors(

		int  major,
		int  minor)
{
	/* Iterate over all screens */
	Screen* def = XDefaultScreenOfDisplay(_gfx_x11.display);
	unsigned int count = XScreenCount(_gfx_x11.display);

	while(count--)
	{
		/* Get screen resources */
		Screen* scr =
			XScreenOfDisplay(_gfx_x11.display, count);
		Window root =
			XRootWindowOfScreen(scr);
		XRRScreenResources* res =
			XRRGetScreenResources(_gfx_x11.display, root);
		RROutput prim =
			res->outputs[0];

		/* Get primary if RandR 1.3 is supported */
		if(major > 1 || (major == 1 && minor > 2))
			prim = XRRGetOutputPrimary(_gfx_x11.display, root);

		/* Insert the screen's display modes */
		size_t first = _gfx_x11_init_modes(scr, res);

		/* Iterate through outputs */
		unsigned int i;
		for(i = 0; i < res->noutput; ++i)
		{
			/* Validate output */
			XRROutputInfo* out =
				XRRGetOutputInfo(_gfx_x11.display, res, res->outputs[i]);

			if(out->connection != RR_Connected)
			{
				XRRFreeOutputInfo(out);
				continue;
			}

			/* Create new monitor */
			XRRCrtcInfo* crtc =
				XRRGetCrtcInfo(_gfx_x11.display, res, out->crtc);
			int rot =
				crtc->rotation & (RR_Rotate_90 | RR_Rotate_270);

			GFX_X11_Monitor mon =
			{
				.screen   = scr,
				.crtc     = out->crtc,
				.mode     = crtc->mode,
				.numModes = 0,
				.modes    = malloc(sizeof(size_t) * out->nmode),
				.x        = crtc->x,
				.y        = crtc->y,
				.width    = rot ? crtc->height : crtc->width,
				.height   = rot ? crtc->width : crtc->height
			};

			/* Retrieve output modes */
			unsigned int j;
			if(mon.modes) for(j = 0; j < out->nmode; ++j)
			{
				GFX_X11_Mode* mode;
				for(
					mode = gfx_vector_at(&_gfx_x11.modes, first);
					mode != _gfx_x11.modes.end;
					mode = gfx_vector_next(&_gfx_x11.modes, mode))
				{
					/* Also check if resolution isn't too big */
					if(
						mode->id == out->modes[j] &&
						mode->mode.width <= crtc->width &&
						mode->mode.height <= crtc->height)
					{
						mon.modes[mon.numModes++] = gfx_vector_get_index(
							&_gfx_x11.modes,
							mode
						);
						break;
					}
				}
			}

			/* Insert at beginning if primary */
			GFXVectorIterator monPos =
				scr == def && res->outputs[i] == prim ?
				_gfx_x11.monitors.begin : _gfx_x11.monitors.end;

			monPos = gfx_vector_insert(&_gfx_x11.monitors, &mon, monPos);
			if(monPos == _gfx_x11.monitors.end) free(mon.modes);

			XRRFreeCrtcInfo(crtc);
			XRRFreeOutputInfo(out);
		}

		XRRFreeScreenResources(res);
	}

	/* Need at least one monitor */
	return _gfx_x11.monitors.begin != _gfx_x11.monitors.end;
}

/******************************************************/
static GFXKey _gfx_x11_get_key(

		KeySym symbol)
{
	/* Unicode numbers */
	if(symbol >= XK_0 && symbol <= XK_9)
		return (GFXKey)(symbol - XK_0 + GFX_KEY_0);

	/* Keypad numbers */
	if(symbol >= XK_KP_0 && symbol <= XK_KP_9)
		return (GFXKey)(symbol - XK_KP_0 + GFX_KEY_KP_0);

	/* Unicode capitals */
	if(symbol >= XK_A && symbol <= XK_Z)
		return (GFXKey)(symbol - XK_A + GFX_KEY_A);

	/* Unicode lowercase */
	if(symbol >= XK_a && symbol <= XK_z)
		return (GFXKey)(symbol - XK_a + GFX_KEY_A);

	/* Function keys */
	if(symbol >= XK_F1 && symbol <= XK_F24)
		return (GFXKey)(symbol - XK_F1 + GFX_KEY_F1);

	/* Non-unicode */
	switch(symbol)
	{
		case XK_VoidSymbol   : return GFX_KEY_UNKNOWN;

		case XK_BackSpace    : return GFX_KEY_BACKSPACE;
		case XK_Tab          : return GFX_KEY_TAB;
		case XK_KP_Tab       : return GFX_KEY_TAB;
		case XK_Clear        : return GFX_KEY_CLEAR;
		case XK_Return       : return GFX_KEY_RETURN;
		case XK_Pause        : return GFX_KEY_PAUSE;
		case XK_Scroll_Lock  : return GFX_KEY_SCROLL_LOCK;
		case XK_Escape       : return GFX_KEY_ESCAPE;
		case XK_Delete       : return GFX_KEY_DELETE;
		case XK_KP_Delete    : return GFX_KEY_DELETE;

		case XK_Home         : return GFX_KEY_HOME;
		case XK_KP_Home      : return GFX_KEY_HOME;
		case XK_Left         : return GFX_KEY_LEFT;
		case XK_KP_Left      : return GFX_KEY_LEFT;
		case XK_Up           : return GFX_KEY_UP;
		case XK_KP_Up        : return GFX_KEY_UP;
		case XK_Right        : return GFX_KEY_RIGHT;
		case XK_KP_Right     : return GFX_KEY_RIGHT;
		case XK_Down         : return GFX_KEY_DOWN;
		case XK_KP_Down      : return GFX_KEY_DOWN;
		case XK_Page_Down    : return GFX_KEY_PAGE_DOWN;
		case XK_KP_Page_Down : return GFX_KEY_PAGE_DOWN;
		case XK_Page_Up      : return GFX_KEY_PAGE_UP;
		case XK_KP_Page_Up   : return GFX_KEY_PAGE_UP;
		case XK_End          : return GFX_KEY_END;
		case XK_KP_End       : return GFX_KEY_END;

		case XK_Select       : return GFX_KEY_SELECT;
		case XK_Print        : return GFX_KEY_PRINT;
		case XK_Execute      : return GFX_KEY_EXECUTE;
		case XK_Insert       : return GFX_KEY_INSERT;
		case XK_KP_Insert    : return GFX_KEY_INSERT;
		case XK_Menu         : return GFX_KEY_MENU;
		case XK_Cancel       : return GFX_KEY_CANCEL;
		case XK_Help         : return GFX_KEY_HELP;
		case XK_Num_Lock     : return GFX_KEY_NUM_LOCK;
		case XK_KP_Space     : return GFX_KEY_SPACE;
		case XK_space        : return GFX_KEY_SPACE;

		case XK_KP_Enter     : return GFX_KEY_KP_RETURN;
		case XK_KP_Multiply  : return GFX_KEY_KP_MULTIPLY;
		case XK_KP_Add       : return GFX_KEY_KP_ADD;
		case XK_KP_Separator : return GFX_KEY_KP_SEPARATOR;
		case XK_KP_Subtract  : return GFX_KEY_KP_SUBTRACT;
		case XK_KP_Decimal   : return GFX_KEY_KP_DECIMAL;
		case XK_KP_Divide    : return GFX_KEY_KP_DIVIDE;

		case XK_Shift_L      : return GFX_KEY_SHIFT_LEFT;
		case XK_Shift_R      : return GFX_KEY_SHIFT_RIGHT;
		case XK_Control_L    : return GFX_KEY_CONTROL_LEFT;
		case XK_Control_R    : return GFX_KEY_CONTROL_RIGHT;
		case XK_Alt_L        : return GFX_KEY_ALT_LEFT;
		case XK_Alt_R        : return GFX_KEY_ALT_RIGHT;
		case XK_Super_L      : return GFX_KEY_SUPER_LEFT;
		case XK_Super_R      : return GFX_KEY_SUPER_RIGHT;
	}

	return GFX_KEY_UNKNOWN;
}

/******************************************************/
static void _gfx_x11_create_key_table(void)
{
	/* Get permitted keycodes and their symbols */
	int minKey, maxKey;
	XDisplayKeycodes(_gfx_x11.display, &minKey, &maxKey);
	maxKey = maxKey > GFX_X11_MAX_KEYCODE ? GFX_X11_MAX_KEYCODE : maxKey;

	int numKeys = maxKey - minKey + 1;

	int symbolsPerKey;
	KeySym* symbols = XGetKeyboardMapping(
		_gfx_x11.display,
		minKey,
		numKeys,
		&symbolsPerKey
	);

	/* Use the first symbol of all keycodes */
	size_t i;
	for(i = minKey; i <= maxKey; ++i) _gfx_x11.keys[i] = _gfx_x11_get_key(
		symbols[(i - minKey) * symbolsPerKey]);

	XFree(symbols);
}
コード例 #8
0
ファイル: lod_map.c プロジェクト: Ckef/Groufix
int gfx_lod_map_add(

		GFXLodMap*    map,
		unsigned int  level,
		void*         data)
{
	GFX_LodMap* internal = (GFX_LodMap*)map;

	/* Overflow */
	size_t size = gfx_vector_get_size(&internal->data);
	if(level > map->levels || size == UINT_MAX) return 0;

	/* Get level iterator */
	GFXVectorIterator levIt;

	if(level == map->levels)
	{
		/* Insert the level if it doesn't exist yet */
		unsigned int upper = size;
		levIt = gfx_vector_insert(
			&internal->levels,
			&upper,
			internal->levels.end
		);

		if(levIt == internal->levels.end) return 0;
		++map->levels;
	}
	else
	{
		/* Check single data flag */
		if(map->flags & GFX_LOD_SINGLE_DATA) return 0;
		levIt = gfx_vector_at(&internal->levels, level);
	}

	/* Get boundaries */
	unsigned int begin;
	unsigned int end;
	_gfx_lod_map_get_boundaries(
		internal,
		levIt,
		&begin,
		&end
	);

	/* Insert the data */
	GFXVectorIterator it = gfx_vector_insert_at(
		&internal->data,
		data,
		end
	);

	if(it == internal->data.end)
	{
		if(begin == end)
		{
			gfx_vector_erase(&internal->levels, levIt);
			--map->levels;
		}
		return 0;
	}

	/* Increase upper bounds */
	while(levIt != internal->levels.end)
	{
		++(*(unsigned int*)levIt);
		levIt = gfx_vector_next(&internal->levels, levIt);
	}

	return 1;
}