8:00 – 4:00 FP
- Back to commenting the shader library. Done. Now I need to create the standalone documents and fix the commenting as needed.
- Downloaded and installed Doxygen from here
- Here’s the documentation!
8:00 – 4:00 FP
8:00 – 4:30 FP

8:00 – 1:00 FP
1:00 – 4:00 VISIBILITY
8:00 – 1:00 FP
1:00 – 4:00 VISIBILITY
8:00 – FP
// Code to show how to use object queries to get picking behavior. For this code to work,
// You'll need to add your preferred rendering framework. This code was pulled from an
// FLTK framework I've been building for data visualization
// Class-wide global variables here for the sake of a compact file
// Classes that are not part of the OpenGl library are from the OpenGl SuperBible,
// which I highly reccomend: http://www.starstonesoftware.com/OpenGL/
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrustum viewFrustum;
bool isPicking;
// Constructor. Set up picking and the projection and model matrices
PickingExample::PickingExample(int x,int y,int w,int h,const char *l)
: Fl_Gl_Window(x,y,w,h,l)
{
isPicking = false;
pickQueryResult = READY;
glGenQueries(1, &pickQueryID);
if(pickQueryID == 0){
pickQueryResult = PICK_ERROR;
}
viewFrustum.SetPerspective(45.0f, (float)screenWidth/(float)screenHeight, 0.5f, 1000.0f);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
modelViewMatrix.LoadIdentity();
}
// A slightly modified version of the original gluPickMatrix, taken from:
// http://oss.sgi.com/cgi-bin/cvsweb.cgi/projects/ogl-sample/main/gfx/lib/glu/libutil/project.c?rev=1.4;content-type=text%2Fplain
void PickingExample::setPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay, GLint viewport[4])
{
if (deltax <= 0 || deltay <= 0) {
return;
}
projectionMatrix.LoadIdentity();
/* Translate and scale the picked region to the entire window */
GLfloat dx = (float)((viewport[2] - 2 * (x - viewport[0])) / deltax);
GLfloat dy = (float)((viewport[3] - 2 * (y - viewport[1])) / deltay);
projectionMatrix.Translate(dx, dy, 0);
projectionMatrix.Scale((float)(viewport[2] / deltax), (float)(viewport[3] / deltay), 1.0);
projectionMatrix.MultMatrix(viewFrustum.GetProjectionMatrix());
}
// the main drawing method. In this case, only drawing for picking is done, though it would
// be easy enough to glClear() afther the picking code, and draw everything over again with
// a normal perspective
void PickingExample::draw() {
GLint result;
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
modelViewMatrix.PushMatrix();
// Have some Euler angle rotations and translations just to show how
// setPickMatrix() doesn't care about eye or model position
// global eye transformations
modelViewMatrix.Rotate(eyeOrient[1], 0, 1, 0);
modelViewMatrix.Rotate(eyeOrient[0], 1, 0, 0);
modelViewMatrix.Translate(eyePos[0], eyePos[1], eyePos[2]);
// global world transformations
modelViewMatrix.Translate(worldPos[0], worldPos[1], worldPos[2]);
modelViewMatrix.Rotate(worldOrient[0], 1, 0, 0);
modelViewMatrix.Rotate(worldOrient[1], 0, 1, 0);
// set up picking
if(isPicking && (pickQueryResult != PICK_ERROR))
projectionMatrix.PushMatrix();
// set the projection matrix so that it's just looking at a (in this case) 10x10 pixel area
// near the cursor. This method (shown above)
setPickMatrix(mouseX,viewport[3]-mouseY,10,10,viewport);
// for each item that you want to test, bracket it with a glBeginQuery()/glEndQuery()
// You'll need a unique pickQueryID for each model
glBeginQuery(GL_ANY_SAMPLES_PASSED, pickQueryID);
// render your model associated with pickQueryID here. It is assumed that
// the projection matrix and the model matrix will be handled by your shader(s)
// finish the query for this particular model
glEndQuery(GL_ANY_SAMPLES_PASSED);
projectionMatrix.PopMatrix();
// For each item that you queried above, see if at least one pixel was drawn
// Again, you'll need a unique pickQueryID for each model
glGetQueryObjectiv(pickQueryID, GL_QUERY_RESULT, &result);
if(result)
printf("hitn");
else
printf("missn");
isPicking = false;
}
modelViewMatrix.PopMatrix();
}
7:30 – 11:00 VISIBILITY
11:00 – 4:00 FP
Here’s the code in question
static enum TRANSFORM_MODE{UNAVAILABLE, HIT, MISS};
TRANSFORM_MODE pickResult(){
GLint result;
glGetQueryObjectiv(drawQuery, GL_QUERY_RESULT_AVAILABLE, &result);
if(result == 0)
return UNAVAILABLE; // always returns this
glGetQueryObjectiv(drawQuery, GL_QUERY_RESULT, &result); // slows down rendering once called.
if(result)
return HIT;
else
return MISS;
};
8:00 – 12:00 visibility
12:00 – 5:30FP
void Gl_ShaderWindow::setPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay, GLint viewport[4])
{
projectionMatrix.PushMatrix();
if (deltax <= 0 || deltay <= 0) {
return;
}
projectionMatrix.LoadIdentity();
/* Translate and scale the picked region to the entire window */
projectionMatrix.Translate((viewport[2] - 2 * (x - viewport[0])) / deltax, (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
projectionMatrix.Scale(viewport[2] / deltax, viewport[3] / deltay, 1.0);
projectionMatrix.MultMatrix(viewFrustum.GetProjectionMatrix());
}
8:00 – 3:30 FP
glGetIntegerv(GL_MAX_UNIFORM_BUFFERS) glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS)
glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName);
void glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
void glGenQueries(GLsizei n, GLuint *ids)
Gluint myQueries[10];
glGenQueries(10, myQueries);
for(int i = 0; i < 10; ++i){
if(myQueries[i] == 0)
// throw an error
}
// run queries
glBeginQuery(GL_ANY_SAMPLES_PASSED, myQueries);
glEndQuery(GL_ANY_SAMPLES_PASSED);
// usually this should be available immediately, but be careful to handle the case if it isn't
glGetQueryObjectuiv(myQueries[0], GL_QUERY_RESULT_AVAILABLE, &result);
if(result == GL_TRUE)
glGetQueryObjectuiv(myQueries[0], GL_QUERY_RESULT, &result);
// do something based on the result
// then when done...
glDeleteQueries(10, myQueries); // free up space for more queries
GLint viewport[4]; float ratio; glSelectBuffer(BUFSIZE,selectBuf); glGetIntegerv(GL_VIEWPORT,viewport); glRenderMode(GL_SELECT); glInitNames(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPickMatrix(cursorX,viewport[3]-cursorY,5,5,viewport); ratio = (viewport[2]+0.0) / viewport[3]; gluPerspective(45,ratio,0.1,1000); glMatrixMode(GL_MODELVIEW);
8:00 – 9:30 VISIBILITY
9:30 – 4:30 FP

8:30 – 1:30 FP
You create a texture and upload the pixels with glTexImage2D (or glTexImage1D, glTexImage3D). However, the program crashes on upload, or there seems to be diagonal lines going through the resulting image. This is because the alignment of each horizontal line of your pixel array is not multiple of 4. That is, each line of your pixel data is not a multiple of 4. This typically happens to users loading an image that is of the RGB or BGR format (in other words, 24 bpp image).
Example, your image width = 401 and height = 500. The height doesn’t matter. What matters is the width. If we do the math, 401 pixels x 3 bytes = 1203. Is 1203 divisible by 4? In this case, the image’s data alignment is not 4. The question now is, is 1203 divisible by 1? Yes, so the alignment is 1 so you should call glPixelStorei(GL_UNPACK_ALIGNMENT, 1). The default is glPixelStorei(GL_UNPACK_ALIGNMENT, 4). Unpacking means sending data from client side (the client is you) to OpenGL.
And if you are interested, most GPUs like chunks of 4 bytes. In other words, RGBA or BGRA is prefered. RGB and BGR is considered bizarre since most GPUs, most CPUs and any other kind of chip don’t handle 24 bits. This means, the driver converts your RGB or BGR to what the GPU prefers, which typically is BGRA.
Similarly, if you read a buffer with glReadPixels, you might get similar problems. There is a GL_PACK_ALIGNMENT just like the GL_UNPACK_ALIGNMENT. The default GL_PACK_ALIGNMENT is 4 which means each horizontal line must be a multiple of 4 in size. If you read the buffer with a format such as BGRA or RGBA you won’t have any problems since the line is already a multiple of 4. If you read it in a format such as BGR or RGB then you risk running into this problem.
The GL_PACK_ALIGNMENT can only be 1, 2, 4, or 8. So an alignment of 3 is not allowed. You could just change the GL_PACK_ALIGNMENT to 1. Or you can pad your buffer out so that each line, even with only 3 values per pixel, is a multiple of 4.
8:30 – 10:30 VISIBILITY
10:30 – 12:30 FP
12:30 – 2:30 interview
2:30 – 4:30 FP
8:30 – 11:00, 12:30 – 3:00 VISIBILITY
11:00 – 12:30, 3:00 – 5:00 FP
10:00 – 4:30 FP
8:30 – 5:30 FP
8:30 – FP
#version 150
// glow.fs
// outputs the color negative of a texture
//
in vec2 vTexCoord;
uniform int screenWidth;
uniform int screenHeight;
uniform sampler2D textureUnit0;
vec4 getTexOffset(const sampler2D texUnit, const vec2 texCoord, const float dx, const float dy){
vec2 offset = texCoord + vec2(dx, dy);
return texture(textureUnit0, offset);
}
void main(void)
{
float dx = 1.0 / float(screenWidth);
float dy = 1.0 / float (screenHeight);
float x;
float y;
vec4 blurSum = vec4(0, 0, 0, 0);
float patchSize = 4.0;
float xmin = -patchSize*dx;
float xmax = patchSize*dx+dx*0.5;
float ymin = -patchSize*dy;
float ymax = patchSize*dy+dx*0.5;
float count = 0;
for(x = xmin; x < xmax; x += dx){
for(y = ymin; y < ymax; y += dy){
blurSum += getTexOffset(textureUnit1, vTexCoord, x, y);
if(count > 1000){
discard;
}
count += 1.0;
}
}
float weight = 1.0/count;
vec4 blured = vec4(blurSum.r*weight, blurSum.g*weight, blurSum.b*weight, 1.0);
vec4 sharp = texture(textureUnit0, vTexCoord);
float luminance = blured.r + blured.g + blured.b;
if(luminance > 1.0){
gl_FragColor = blured;
}else{
gl_FragColor = sharp;
}
}

#version 150
// glow.fs
// outputs the color negative of a texture
//
in vec2 vTexCoord;
uniform int screenWidth;
uniform int screenHeight;
uniform sampler2D textureUnit0;
void luminanceTest(const sampler2D texUnit, const vec2 texCoord, const float xmin, const float xmax, const float ymin, const float ymax, const float luminance){
vec2 ll = clamp(texCoord + vec2(xmin, ymin), 0.0, 1.0);
vec2 lr = clamp(texCoord + vec2(xmax, ymin), 0.0, 1.0);
vec2 ur = clamp(texCoord + vec2(xmax, ymax), 0.0, 1.0);
vec2 ul = clamp(texCoord + vec2(xmin, ymax), 0.0, 1.0);
vec4 total = texture(texUnit, ll);
total += texture(texUnit, lr);
total += texture(texUnit, ur);
total += texture(texUnit, ul);
float weight = 1.0/4.0;
float val = (total.r + total.g + total.b)*weight;
if(val < luminance){
discard;
}
}
vec4 getTexOffset(const sampler2D texUnit, const vec2 texCoord, const float dx, const float dy){
vec2 offset = texCoord + vec2(dx, dy);
clamp(offset, 0.0, 1.0);
return texture(texUnit, offset);
}
void main(void)
{
float dx = 1.0 / float(screenWidth);
float dy = 1.0 / float (screenHeight);
float x;
float y;
vec4 blurSum = vec4(0, 0, 0, 0);
float patchSize = 4.0;
float xmin = -patchSize*dx;
float xmax = patchSize*dx+dx*0.5;
float ymin = -patchSize*dy;
float ymax = patchSize*dy+dx*0.5;
float count = 0;
luminanceTest(textureUnit0, vTexCoord, xmin, xmax, ymin, ymax, 1.0);
for(x = xmin; x < xmax; x += dx){
for(y = ymin; y < ymax; y += dy){
blurSum += getTexOffset(textureUnit0, vTexCoord, x, y);
if(count > 1000){
discard;
}
count += 1.0;
}
}
vec4 sharp = texture(textureUnit0, vTexCoord);
float weight = 1.0/count;
vec4 blured = vec4(blurSum.r*weight, blurSum.g*weight, blurSum.b*weight, sharp.a);
float luminance = blured.r + blured.g + blured.b;
if(luminance > 1.0){
gl_FragColor = blured;
}else{
gl_FragColor = sharp;
}
}
You must be logged in to post a comment.