• Create Account

Banner advertising on our site currently available from just \$5!

# Tocs

Member Since 22 Apr 2005
Offline Last Active Dec 15 2014 04:21 PM

### Creating an OpenGL context on Windows with Glew.

26 June 2014 - 11:57 AM

Something weird has happened. I had context creation working just fine. It worked on my desktop and my laptop and I was happily plugging along doing graphics programming. One day I attempt to build my code on my laptop again, suddenly context creation starts to fail. I don't know what has changed.

My original context creation code looks like this

https://gist.github.com/LordTocs/f227528a729986df9643

It's sloppy and has next to no error handling but it at least worked. It still works on my desktop and fails on my laptop.

Specifically wglCreateContextAttribsARB fails.

I started to modify the code in an attempt to figure out what was wrong. I added some "GetLastError()" print outs in hopes I was doing something silly and it would tell me what was wrong. Using "FormatMessage()" to change error code into readable stings.

Instead of a usable error I was greeted with GetLastError() returning 3221692565. Which FormatMessage() had no idea what to do with. A quick cursory internet search lead me to a single result on the opengl forums. Which didn't yield any results

After some reading I was told not to create a forward compatible context. And that I should use wglChoosePixelFormatARB to get the appropriate pixel format. Thinking this was the issue, I tried to use this function, it didn't help.

So now I'm left with this code that doesn't work and I'm very confused.

void DisplayWindowsError()
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);

if (lpMsgBuf)
{
std::cout << "Windows Error:" << dw << ": " << (char *)lpMsgBuf << std::endl;
LocalFree(lpMsgBuf);
}
else
{
std::cout << "Windows Error:" << dw << ": unknown" <<  std::endl;
}
}

GraphicsContext::GraphicsContext(ContextTarget &target)
: Target (target)
{
PIXELFORMATDESCRIPTOR pfd =			// pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR),	// Size Of This Pixel Format Descriptor
1,								// Version Number
PFD_DRAW_TO_WINDOW |			// Format Must Support Window
PFD_SUPPORT_OPENGL |			// Format Must Support OpenGL
PFD_DOUBLEBUFFER,				// Must Support Double Buffering
PFD_TYPE_RGBA,					// Request An RGBA Format
32,								// Select Our Color Depth
0, 0, 0, 0, 0, 0,				// Color Bits Ignored
0,								// No Alpha Buffer
0,								// Shift Bit Ignored
0,								// No Accumulation Buffer
0, 0, 0, 0,						// Accumulation Bits Ignored
24,								// 32Bit Z-Buffer (Depth Buffer)
8,								// No Stencil Buffer
0,								// No Auxiliary Buffer
PFD_MAIN_PLANE,					// Main Drawing Layer
0,								// Reserved
0, 0, 0								// Layer Masks Ignored
};
PixelFormat = 1;
if (!(PixelFormat = ChoosePixelFormat (target.GetHDC (), &pfd)))
{
DisplayWindowsError();
cout << "Failed to choose pixel format." << endl;
}

if (!SetPixelFormat(target.GetHDC(),PixelFormat, &pfd))
{
//DestroyGameWindow (); //Insert Error
DisplayWindowsError();
cout << "Failed to set pixel format." << endl;
}

HGLRC temp;
temp = wglCreateContext(target.GetHDC());
if (!temp)
{
//DestroyGameWindow (); //Insert Error
cout << "Failed to create context" << endl;

}
DisplayWindowsError();
if (!wglMakeCurrent(target.GetHDC (), temp))
{
//DestroyGameWindow ();
cout << "Failed to make current." << endl;
GLErrorCheck();
}
DisplayWindowsError();

GLenum err = glewInit();

if (err != GLEW_OK)
{
char *error = (char *)glewGetErrorString(err);
cout << "GLEW INIT FAIL: " << error << endl;
}

int contextattribs [] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
#ifdef _DEBUG
WGL_CONTEXT_FLAGS_ARB,  WGL_CONTEXT_DEBUG_BIT_ARB,
#endif
0
};

int pfattribs[] =
{
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0
};

if (wglewIsSupported ("WGL_ARB_create_context") == 1)
{
unsigned int formatcount;

if (!wglChoosePixelFormatARB(target.GetHDC(), pfattribs, nullptr, 1, (int *)&PixelFormat, &formatcount))
{
std::cout << "Failed to find a matching pixel format" << std::endl;
DisplayWindowsError();
}

if (!SetPixelFormat(target.GetHDC(), PixelFormat, &pfd))
{
DisplayWindowsError();
std::cout << "Failed to set pixelformat" << std::endl;
}

hRC = wglCreateContextAttribsARB(Target.GetHDC(), nullptr, contextattribs);
if (!hRC)
{
DisplayWindowsError();
std::cout << "Failed to create context." << std::endl;
}
wglMakeCurrent(nullptr, nullptr);
DisplayWindowsError();
wglDeleteContext(temp);
DisplayWindowsError();
GLErrorCheck();
MakeCurrent ();

}
else
{
cout << "Failed to create context again..." << endl;
}

#ifdef _DEBUG
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(dbgcallback, nullptr);
#endif

//GLErrorCheck;
char *version = (char *)glGetString(GL_VERSION);
//GLErrorCheck;
std::cout << "Version: " << version << std::endl << "Shading Version: " << shadeversion << std::endl;

glViewport (0,0,Target.GetWidth (), Target.GetHeight ());
GLErrorCheck ();

SetClearColor (Color(0,0,0,0));
SetClearDepth(1000.0f);
//EnableDepthBuffering ();
//DisableDepthTest ();
NormalBlending ();

glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); //Doesn't get Abstracted
GLErrorCheck();

}


If anyone knows what I'm doing wrong I'd love to know.

Thanks.

### Shader works on laptop, hangs on desktop.

11 January 2014 - 02:32 PM

I recently completed my Single Pass Order Independent Transparency shader.

I decided to add some shadows to my lighting shader. Since my lighting is computed with Tiled Forward Shading I put my shadow maps into texture array of cube maps. When I added the line of code to sample the cube maps. It started to hang on glDrawElements(). After some time the graphics driver kills the program for having too many errors. However it doesn't hang right away, there's a couple seconds of it working correctly before it breaks.

I gave it a try on my laptop (NV 630m) and it works completely, and seemingly smoother than my desktop(NV 770) without the shadows.

If I comment out the line sampling the cube map array for shadows it works.

attenuation *= texture(ShadowMaps, vec4(WL,shadow),comparedepth);

Curiously if I leave the line sampling the shadows, don't call my BRDF portion, and instead output attenuation. The shader doesn't hang.

color += vec4(attenuation,attenuation,attenuation,0.1);

What that looks like:

I've pasted my shaders here. http://pastie.org/8624432#85,92 Since they're kind of large.

And an opengl log, though CodeXL doesn't seem to want to capture the whole log for a single frame.

https://gist.github.com/LordTocs/c2a59de6c3d9fa811d2b

I'm hoping it's not the drivers because I tried updating them to the latest. I hope someone spots something I'm doing incorrectly. I know it's a lot to sift through but I'm running out of ideas.

Screenshot from my laptop: http://i.imgur.com/9WspPLc.png

EDIT:

I've since added a debug callback to my OpenGL context. When the shader locks up, this comes over the debug output.

Debug(api, m): PERFORMANCE - Program/shader state performance warning: Fragment Shader is going to be recompiled because the shader key based on GL state mismatches.

### Managing Materials / Shaders, Their Inputs, and Different Types of Geometry.

09 September 2013 - 09:28 PM

I wanted to have this great "material" system where I could create a simple description of a material in a text file and slap it on just about any geometry I wanted. Different types of geometry are things like static meshes, animated meshes, particles, instanced geometry, ribbon-trails, etc.

These different types of geometry require different vertex shaders, maybe tessellation or geometry shaders as well, and have inputs to go with those shaders such as bone orientations for animated meshes.

So in my head it made sense to create a Geometry class who's purpose is to contribute the vertex processing part of the shaders, handle the vertex processing inputs, and control how the primitives were submitted to the GPU.

Then to go with it I created a Shading class who supplied the fragment processing part of the shaders, the inputs for the fragment processing, and controlled the order in which "bucket" the draw call should go in. (Transparent, Forward Opaque, Deferred, Glowing, Distortion, etc).

There were agreed upon inputs/outputs between shading stages. (Normal, Position, TextureCoordinate) etc.

This turned out horribly, or at least the way I handled it did.

• You couldn't have shading that required special vertex shading. Like this.
• You had to write special shaders for instanced stuff anyway if they were to have any variation in shading. Thus defeating the purpose.
• Particles were a mess because you have the behavior of a particle influence both the vertex and fragment processing ends. And ultimately defeated the purpose of separating geometry and shading.
• Forward lighting became problematic because of the multiple shaders for different types of lights while other types of shading like deferred didn't need to know about the light.

So the system is pretty much broken and I need to replace it with a better way of doing things. So how do you handle minimizing your shader rewriting? How do you pair your "materials" with your "geometry"?

I tried to search around for related information but I wasn't entirely sure what to search for so if I've missed a great thread post me a link.

### LaTeX math via MathJax?

18 July 2013 - 07:28 AM

A few weeks ago I tried to make a post in the math forum with a bit of LaTeX mixed in. A sticky post said to use the "eqn" tag. The tag seems to query a server to render the latex and serve an image. However it seemed quite easy to break the server so it wouldn't output an image at all.

The other day I was stumbling across the internet and found http://www.mathjax.org/ which renders latex into HTML elements. It seems to function quite well. Has anyone considered this for use in the forums / journals? I did a quick search of the forums and couldn't find any mention of it. So I thought I'd post it here.

### Rope Simulation with Point Based Dynamics

17 June 2013 - 01:44 PM

Looks like the eqn tag died, tried to make readable "ascii math"

I tried asking this question on MathOverflow but it doesn't seem to be gaining any speed there... This forum seems much better suited. So I saw some papers on laproscopic surgery and simulating thread and thought "That would make some wicked cool rope to play with" Something to shove together with my Razer Hydra and Oculus. The most current of the papers is  this which in turn references this other paper.

In Müller's paper he talks about constraint functions being C : R^3 -> R Which makes sense because using the constraint solver you solve attempt to get each constraint function either equal to 0 or greater than or equal to 0.

However if you look at fratarcangeli's paper he gives the contact constraint function as

C(p) = [p - (p_n0 + p_v)]

Where p must be some vertex of the rope, p_v is the penetration vector and p_n0 is "the current position of point p. This is where things stop making sense for me. Because it appears that fratarcangeli's constraint equation is in R^3 and not R}. Perhaps I'm miss-understanding the equation?

My second issue with his constraint function is

p_v = (|p_n0 - p_n1| - r) dot (p_n0 - p_n1)/|p_n0 - p_n1|

and he gives a very loose definition of what p, p_n0, p_n1 are.

Perhaps someone can explain what his constraint function is supposed to be?

---------------------------

I attempted to figure out what the constraint function should be.

I assumed if two segments were colliding I would have to apply a contact constraint to all 4 points. Since I'm applying the constraint to both sides I only need to move each mass point halfway out of the collision.

When a collision occurs between two line segments p_1 -> q_1 and  p_2 -> q_2  And p = p1. I get the two closest points c_1 and c_2 on those segments respectively.Most of the time c_1 != p. So I have to define my constraint function with that in mind.

I call the collision normal n = (c_1 - c_2) / |c_1 - c_2| and an offset o = (p - c_1) dot n which is the offset along the collision normal of p down to the contact point. This handles when c_1 != p Note: o is calculated once at the beginning of a collision, it's expected to stay constant.

The goal is to have the constraint function equal to 0 when p has moved halfway to resolve the collision (the other segment will move the other half) and > 0 when the point has moved further than halfway.

So I define

C(p) = -(2r - ((p - c_2) dot n - o))/2

Here's a poorly drawn diagram to illustrate my thoughts.

Which when I punch that through the method described in Müller's paper. I get delta_p = -2C(p)n However when I plug this into my simulation it's stable up until I tie a knot which given the nature of the papers means I've done something wrong. Can anyone elaborate on where I'm going wrong?

PARTNERS