Jump to content

  • Log In with Google      Sign In   
  • Create Account

Erik Rufelt

Member Since 17 Apr 2002
Online Last Active Today, 05:19 AM

#5277129 Vulkan is Next-Gen OpenGL

Posted by Erik Rufelt on 20 February 2016 - 04:10 AM

Did anyone create anything with it yet?


I tried it out and it works reasonably well, though feels beta. VSync in particular doesn't work at all when I use the SDK, but if I load the functions from the Nvidia driver directly I can't turn it off (no immediate mode reported and ignored if used anyway). Haven't been able to find how they manage to turn it off from the SDK sources... smile.png

Also the SDK crashes whenever I enable the debug validation.. though if I enable the individual layers but leave out the threading validation layer it seems to work and I get debug output.


Haven't found anything about fullscreen mode. I'm reasonably sure when I first tried a fullscreen top-level window I saw a distinct automatic modeswitch like OpenGL does.. but today it stays in "fullscreen windowed".

Only B8G8R8A8 modes reported for me.. no 30-bit backbuffers in the current Nvidia driver apparently.


Documentation feels somewhat lacking. In particular the swap chain parts, where the various examples do things different ways and none quite make sense. When I do get VSync the blocking seems to be in QueuePresent.. whereas I would expect it to just queue up the present and the wait to be in AcquireImage. Perhaps we're supposed to always present on a separate thread or something... I get the delay in present even if I wait for the queue and device to become idle before I call it so it definitely seems to be a wait for the actual VBlank. EDIT: Actually not entirely sure on that, not used enough to this yet to be sure I do things the right way.


Debug validation seems to work, apart from the crash and again problems with the swap-chain. Docs specifically says I need to transition the image between present mode and color attachment, but ignoring that and transitioning it to whatever insane layout I choose at random doesn't give any warnings and works happily.



Didn't get far past the setup yet so everything else may still be great smile.png

#5274454 Vulkan is Next-Gen OpenGL

Posted by Erik Rufelt on 05 February 2016 - 09:07 AM

Also another link for another calendar door. biggrin.png


They could've upgraded the cover image model to say Vulkan and not OpenGL..

#5274178 Window Creation in Win 7

Posted by Erik Rufelt on 03 February 2016 - 11:47 PM

You need to set the window pixel format and then create an OpenGL context.

You should be able to pick out the parts required to get it running in your window from this example:

#include <windows.h>
#include <gl/gl.h>

#pragma comment (lib, "opengl32.lib")


// Main
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	// Window class
	WNDCLASSEX wc = {};
	wc.cbSize = sizeof(wc);
	wc.lpszClassName = TEXT("MyClass");
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.style = CS_OWNDC;

	// Window
	HWND hWnd = CreateWindowEx(
		TEXT("OpenGL Window"),

	// Get DC
	HDC hDC = GetDC(hWnd);

	// Pixel format
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags =
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 32;

	int pf = ChoosePixelFormat(hDC, &pfd);
	SetPixelFormat(hDC, pf, &pfd);

	// OpenGL context
	HGLRC hGLRC = wglCreateContext(hDC);

	wglMakeCurrent(hDC, hGLRC);

	// Get OpenGL version and set it as window title
	SetWindowTextA(hWnd, (char*)glGetString(GL_VERSION));

	// Main loop
	ShowWindow(hWnd, nCmdShow);
	while(true) {
		MSG msg;
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
			if(msg.message == WM_QUIT)
			else {
		else {
			// Draw
			glClearColor(1.0f, 0.7f, 0.2f, 1.0f);


	// Clean up
	wglMakeCurrent(NULL, NULL);

	UnregisterClass(wc.lpszClassName, hInstance);

	return 0;

// Window proc
	switch(msg) {
		case WM_DESTROY:
		return 0;

		case WM_SIZE:
			// Resize GL rendering area to match window size
			glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
		return 0;

	return DefWindowProc(hWnd, msg, wParam, lParam);

However, that will only really allow you to use quite old OpenGL functionality without some extra work, as the newer version functions aren't readily available in opengl32.lib. The default library only provides version 1.1 or something like that (even when the context version is 4.5).


To load more functions you need to request their function pointers from WGL while your GL context is current, for example to use the glCompileShader function:

PFNGLCOMPILESHADERPROC glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");

The function pointer will match a function in the NVidia or AMD driver for example, not in the system OpenGL DLL.


This is a bit tedious, and if you want to do it manually the best way is probably to download glcorearb.h from opengl.org and write a script that goes through it and loads all the functions into some appropriate wrapper or global pointers or something.

There are libraries written specifically to take care of all this, such as GLEW for example: http://glew.sourceforge.net/

It can take care of checking all extensions etc. for you and help make sure everything is loaded properly and detect when it isn't. This is especially useful when loading extensions that may be available only on some drivers. If you make sure the context version is 4.x and you load only core functionality matching that version it's just about loading all the function pointers.

#5274108 Multiplication and division of four chars packed in one int

Posted by Erik Rufelt on 03 February 2016 - 02:01 PM

What OS is it for?

On Android there's Renderscript that is specifically made for things like image filters that might work. In general you should be able to do a lot of stuff in GLSL shaders. I would investigate that possibility as it could save you a lot of work and improve performance.

#5272824 CreateSwapChain "fullscreen" random fail with DXGI_STATUS_OCCLUDED

Posted by Erik Rufelt on 27 January 2016 - 06:23 AM

Try creating the swap chain in windowed mode and going to fullscreen with SetFullscreenState.

#5272589 Vulkan is Next-Gen OpenGL

Posted by Erik Rufelt on 25 January 2016 - 11:15 AM

Based on Khronos' previous performance I'd say that they're perfectly capable of going from information blackout to full release overnight.


They're also quite capable of scrapping Vulkan and releasing an OpenGL 5.0 that is little more than new extensions layered on the existing mess, even at this late stage.


The estimated release is alarmingly close to April 1 ...

#5272553 WinAPI WNDPROC to Engine/Game MessageHandler

Posted by Erik Rufelt on 25 January 2016 - 01:26 AM

What do you feel isn't elegant about it?

Another way is to capture messages in the main loop when returned from GetMessage/PeekMessage.


One thing I see is that you should probably not always return DefWindowProc at the end, but let 'MessageHandler' decide. Though I'm not entirely clear on what your message handler does, do you pass everything to it or where do you decide what "converted winapi parameters" are?

#5270774 Draw dashed stroke around rectangle/ellipse with single draw call

Posted by Erik Rufelt on 12 January 2016 - 04:51 PM

There is a strip restart index that starts a new strip on the next index. Check the bottom of this page: https://msdn.microsoft.com/en-us/library/windows/desktop/bb205124%28v=vs.85%29.aspx

#5270765 Enable Z buffer only for ALPHA CHANNEL > 0

Posted by Erik Rufelt on 12 January 2016 - 04:16 PM

The code you posted shows no alpha testing (D3DRS_ALPHATESTENABLE), are you sure you're using that one?

#5270609 Enable Z buffer only for ALPHA CHANNEL > 0

Posted by Erik Rufelt on 11 January 2016 - 04:59 PM

Enable Z buffer and use "discard" in your shader, also known as alpha-testing.


Here is info about alpha testing in D3D9:



(Note that if you want the edges of the net to be partly transparent but not completely, or if you want the net to instead be colored partly transparent glass or similar this solution won't help, so in that case you need to draw all opaque geometry like the player first, and then as the final step in your rendering process draw all alpha-blended surfaces sorted back to front).

#5269865 Sorting with dependencies?

Posted by Erik Rufelt on 07 January 2016 - 11:47 AM

Say you have N objects with M "sort values", where M0 is prioritized as required depth order, M1 is shader, M2 is texture, etc...

Start by sorting by M0, to yield X <= N subgroups with equal M0. Then sort X0 by [M1, M2, ...] to minimize state changes when drawing the objects at the back. Then sort X1 the same way, but re-order the shaders in M1 used for that sort so that the last one that was used in X0 is at the front, same with M2 etc.

Loop over all Xi to do the same, always with the internal sort-values in Mi modified to put the last used value in Xi-1 at the front.


If you care about more than M0 and M1, you would have to recurse for new subgroups Y <= NX after sorting Xi to minimize changing texture when the shader changes within Xi.


Should be possible to optimize reasonably, as every recursion would only have to find the matching subgroup of Mi+1 and move it to the front of its parent..



You could make it more advanced by saying that M1 is valued as three M2 for example so if you had to change texture four times to avoid changing shader once you would re-order the priority of M1 vs M2 .. but I can't quite picture the exact complexity of that.. probably significantly worse.

#5269823 A better way to communicate with relay server?

Posted by Erik Rufelt on 07 January 2016 - 07:37 AM


InternetOpen followed by Connect / HttpOpenRequest / HttpSendRequest if you use HTTP(S). Can automatically use system proxy settings where required.

#5269627 How can I draw a svg to a SDL_Surface with nanosvg?

Posted by Erik Rufelt on 06 January 2016 - 09:09 AM

Write the 'img' buffer to a file and open it in some image editor that supports raw files or just in a hex editor to make sure it contains somewhat proper data. If it does then the problem is in getting it onto the SDL surface, and if it doesn't then the problem is in drawing the SVG. Either way you know where to investigate.


(Also, in this case you code seems to do absolutely nothing with the SDL surface.. you create it and lock it... and.. then just exit your function?  Probably some logic error there, maybe you want the surface to be a reference or have your function return a pointer to the new surface).

#5266037 OpenGL Efficient Rendering of 2D Sprites

Posted by Erik Rufelt on 12 December 2015 - 10:17 AM

One thing to remember is that it's usually not too bad with a drawcall for each sprite unless you have on the order of at least several thousand. GL draw-calls are pretty fast, assuming you still use a texture-atlas and don't switch textures for each one (+ sort by texture either way, even with the atlas).

It's uncommon that sprites have any other bottle-neck than fillrate, unless you do something like very many small particles. If your sprites are reasonably large, then sorting by texture or even area of a texture to improve cache usage can give much more benefit in itself than every possible optimization of the vertices does.


When sprites are sorted by texture then changing textures won't matter too much, so several atlases isn't a bad idea, and if you have sprites with many animation frames you will probably end up with one texture per sprite for the animated ones to fit all the frames.

Count the number of texture switches, if you only save a few texture switches by combining an atlas with another then it probably isn't worth it, but if you need to switch atlas between every other sprite then combining them has a large benefit.

#5265960 Issues With Sprite Batching

Posted by Erik Rufelt on 11 December 2015 - 05:56 PM

I don't really know of one... always use interleaved arrays :) But you can have all positions in one VBO and all texture coordinates in another VBO if you really want to.

It could be good in special cases, for example if you have a vertex that is very large, say 128 bytes per vertex, and part of that vertex, say 8 of the bytes, have to be dynamic and be updated for every vertex every frame, whereas the other 120 bytes are static.

If you have 1000 vertices in your model, then you can either use one VBO and update 128k data each frame, or you can use two VBOs and separate the small part of the vertex that needs to be dynamic into its own VBO, and only update the small VBO with 8k data per frame while keeping 120k static.

Another usage can be instancing (though I've never tried it like this). This link talks about it under instanced arrays https://www.opengl.org/wiki/Vertex_Specification