Exemplo n.º 1
2
	//[-------------------------------------------------------]
	//[ Public methods                                        ]
	//[-------------------------------------------------------]
	TextureBufferDsa::TextureBufferDsa(OpenGLRenderer &openGLRenderer, uint32_t numberOfBytes, Renderer::TextureFormat::Enum textureFormat, const void *data, Renderer::BufferUsage bufferUsage) :
		TextureBuffer(openGLRenderer)
	{
		if (openGLRenderer.getExtensions().isGL_ARB_direct_state_access())
		{
			{ // Buffer part
				// Create the OpenGL texture buffer
				glCreateBuffers(1, &mOpenGLTextureBuffer);

				// Upload the data
				// -> Usage: These constants directly map to "GL_ARB_vertex_buffer_object" and OpenGL ES 2 constants, do not change them
				glNamedBufferData(mOpenGLTextureBuffer, static_cast<GLsizeiptr>(numberOfBytes), data, static_cast<GLenum>(bufferUsage));
			}

			{ // Texture part
				// Create the OpenGL texture instance
				glCreateTextures(GL_TEXTURE_BUFFER_ARB, 1, &mOpenGLTexture);

				// Attach the storage for the buffer object to the buffer texture
				glTextureBuffer(mOpenGLTexture, Mapping::getOpenGLInternalFormat(textureFormat), mOpenGLTextureBuffer);
			}
		}
		else
		{
			// Create the OpenGL texture buffer
			glGenBuffersARB(1, &mOpenGLTextureBuffer);

			// Create the OpenGL texture instance
			glGenTextures(1, &mOpenGLTexture);

			// Buffer part
			// -> Upload the data
			// -> Usage: These constants directly map to "GL_ARB_vertex_buffer_object" and OpenGL ES 2 constants, do not change them
			glNamedBufferDataEXT(mOpenGLTextureBuffer, static_cast<GLsizeiptr>(numberOfBytes), data, static_cast<GLenum>(bufferUsage));

			{ // Texture part
				#ifndef OPENGLRENDERER_NO_STATE_CLEANUP
					// Backup the currently bound OpenGL texture
					GLint openGLTextureBackup = 0;
					glGetIntegerv(GL_TEXTURE_BINDING_BUFFER_ARB, &openGLTextureBackup);
				#endif

				// Make this OpenGL texture instance to the currently used one
				glBindTexture(GL_TEXTURE_BUFFER_ARB, mOpenGLTexture);

				// Attaches the storage for the buffer object to the active buffer texture
				// -> Sadly, there's no direct state access (DSA) function defined for this in "GL_EXT_direct_state_access"
				glTexBufferARB(GL_TEXTURE_BUFFER_ARB, Mapping::getOpenGLInternalFormat(textureFormat), mOpenGLTextureBuffer);

				#ifndef OPENGLRENDERER_NO_STATE_CLEANUP
					// Be polite and restore the previous bound OpenGL texture
					glBindTexture(GL_TEXTURE_BUFFER_ARB, static_cast<GLuint>(openGLTextureBackup));
				#endif
			}
		}
	}
Exemplo n.º 2
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint tex, bo;

	piglit_require_gl_version(20);
	piglit_require_extension("GL_ARB_texture_buffer_object");

	glGenTextures(1, &tex);
	glGenBuffers(1, &bo);

	pass = expect(GL_TEXTURE_BINDING_BUFFER, 0) && pass;
	glBindTexture(GL_TEXTURE_BUFFER, tex);
	pass = expect(GL_TEXTURE_BINDING_BUFFER, tex) && pass;

	pass = expect(GL_TEXTURE_BUFFER, 0) && pass;
	glBindBuffer(GL_TEXTURE_BUFFER, bo);
	pass = expect(GL_TEXTURE_BUFFER, bo) && pass;

	pass = expect(GL_TEXTURE_BUFFER_FORMAT_ARB,
		      piglit_is_core_profile ? GL_R8 : GL_LUMINANCE8) && pass;

	glTexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA8, 0);
	pass = expect(GL_TEXTURE_BUFFER_FORMAT_ARB, GL_RGBA8) && pass;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Exemplo n.º 3
0
void
piglit_init(int argc, char **argv)
{
    bool pass = true;
    GLuint list, tex, bo;
    GLint ret;

    piglit_require_gl_version(20);
    piglit_require_extension("GL_ARB_texture_buffer_object");

    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_BUFFER, tex);

    glGenBuffers(1, &bo);
    glBindBuffer(GL_TEXTURE_BUFFER, bo);

    list = glGenLists(1);
    glNewList(list, GL_COMPILE);
    glTexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA8, bo);
    glEndList();

    ret = 0xd0d0d0d0;
    glGetIntegerv(GL_TEXTURE_BUFFER_DATA_STORE_BINDING, &ret);
    if (ret != bo) {
        fprintf(stderr,
                "GL_TEXTURE_BUFFER_DATA_STORE after display list "
                "compile was %d, expected %d\n", ret, bo);
        pass = false;
    }

    /* Make sure the list is empty. */
    glTexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA8, 0);
    glCallList(list);
    if (!piglit_check_gl_error(0))
        pass = false;

    glGetIntegerv(GL_TEXTURE_BUFFER_DATA_STORE_BINDING, &ret);
    if (ret != 0) {
        fprintf(stderr,
                "GL_TEXTURE_BUFFER_DATA_STORE after display list "
                "compile was %d, expected %d\n", ret, 0);
        pass = false;
    }

    piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Exemplo n.º 4
0
void
piglit_init(int argc, char **argv)
{
	GLuint tex;

	piglit_require_extension("GL_ARB_texture_buffer_object");

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_BUFFER, tex);
	glTexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA8, 0xd0d0d0d0);
	if (!piglit_check_gl_error(GL_INVALID_OPERATION))
		piglit_report_result(PIGLIT_FAIL);

	piglit_report_result(PIGLIT_PASS);
}
Exemplo n.º 5
0
void upload_mesh(mesh_chunk *mc, uint8 *vertex_build_buffer, uint8 *face_buffer)
{
   glGenBuffersARB(1, &mc->vbuf);
   glBindBufferARB(GL_ARRAY_BUFFER_ARB, mc->vbuf);
   glBufferDataARB(GL_ARRAY_BUFFER_ARB, mc->num_quads*4*sizeof(uint32), vertex_build_buffer, GL_STATIC_DRAW_ARB);
   glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

   glGenBuffersARB(1, &mc->fbuf);
   glBindBufferARB(GL_TEXTURE_BUFFER_ARB, mc->fbuf);
   glBufferDataARB(GL_TEXTURE_BUFFER_ARB, mc->num_quads*sizeof(uint32), face_buffer , GL_STATIC_DRAW_ARB);
   glBindBufferARB(GL_TEXTURE_BUFFER_ARB, 0);

   glGenTextures(1, &mc->fbuf_tex);
   glBindTexture(GL_TEXTURE_BUFFER_ARB, mc->fbuf_tex);
   glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_RGBA8UI, mc->fbuf);
   glBindTexture(GL_TEXTURE_BUFFER_ARB, 0);
}
void ParticleInstancingRenderer::BuildTBO(const GLuint tbo, const GLuint tex, size_t tbo_size,  \
                                          GLenum usage, GLenum internal_format)
{
    debug1 << "\tbuilding texture buffer for instance data of size " << FormatBytes(tbo_size) << endl;

    glBindBufferARB(GL_TEXTURE_BUFFER_ARB, tbo);
    CheckOpenGLError();

    glBufferDataARB(GL_TEXTURE_BUFFER_ARB, tbo_size, 0, usage);
    CheckOpenGLError();

    glBindTexture(GL_TEXTURE_BUFFER_ARB, tex );
    CheckOpenGLError();

    glTexBufferARB(GL_TEXTURE_BUFFER_ARB, internal_format, tbo);
    CheckOpenGLError();

    // clear texture / bufer bindings
    glBindBufferARB(GL_TEXTURE_BUFFER_ARB, 0);
    CheckOpenGLError();
    glBindTexture(GL_TEXTURE_BUFFER_ARB, 0);
    CheckOpenGLError();
}
Exemplo n.º 7
0
void
piglit_init(int argc, char **argv)
{
	GLenum targets[] = {
		0,
		GL_TEXTURE_2D,
		GL_TEXTURE_BUFFER + 1,
	};
	GLuint tex;
	int i;

	piglit_require_extension("GL_ARB_texture_buffer_object");

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_BUFFER, tex);

	for (i = 0; i < ARRAY_SIZE(targets); i++) {
		glTexBufferARB(targets[i], GL_RGBA8, 0);
		if (!piglit_check_gl_error(GL_INVALID_ENUM))
			piglit_report_result(PIGLIT_FAIL);
	}

	piglit_report_result(PIGLIT_PASS);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBTextureBufferObject_nglTexBufferARB(JNIEnv *env, jclass clazz, jint target, jint internalformat, jint buffer, jlong function_pointer) {
	glTexBufferARBPROC glTexBufferARB = (glTexBufferARBPROC)((intptr_t)function_pointer);
	glTexBufferARB(target, internalformat, buffer);
}
Exemplo n.º 9
0
///////////////////////////////////////////////////////////////////////////////
// OpenGL related startup code is safe to put here. Load textures, etc.
void SetupRC(void)
{
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        /* Problem: glewInit failed, something is seriously wrong. */
        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
    }

    glEnable(GL_DEPTH_TEST);

    exposure = 1.0f;

    // Light Blue
    glClearColor(vSkyBlue[0], vSkyBlue[1], vSkyBlue[2], vSkyBlue[3]);

    // Load geometry
    GLfloat alpha = 0.25f;
    floorBatch.Begin(GL_TRIANGLE_FAN, 4, 1);
        floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
        floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        floorBatch.Normal3f(0.0, 1.0f, 0.0f);
        floorBatch.Vertex3f(-20.0f, -0.41f, 20.0f);

        floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
        floorBatch.MultiTexCoord2f(0, 1.00f, 0.0f);
        floorBatch.Normal3f(0.0, 1.0f, 0.0f);
        floorBatch.Vertex3f(20.0f, -0.41f, 20.0f);

        floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
        floorBatch.MultiTexCoord2f(0, 1.00f, 1.00f);
        floorBatch.Normal3f(0.0, 1.0f, 0.0f);
        floorBatch.Vertex3f(20.0f, -0.41f, -20.0f);

        floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
        floorBatch.MultiTexCoord2f(0, 0.0f, 1.00f);
        floorBatch.Normal3f(0.0, 1.0f, 0.0f);
        floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
    floorBatch.End();

    windowBatch.Begin(GL_TRIANGLE_FAN, 4, 1);
        windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f);
        windowBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        windowBatch.Normal3f( 0.0f, 1.0f, 0.0f);
        windowBatch.Vertex3f(-1.0f, 0.0f, 0.0f);

        windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f);
        windowBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        windowBatch.Normal3f(0.0f, 1.0f, 0.0f);
        windowBatch.Vertex3f(1.0f, 0.0f, 0.0f);

        windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f);
        windowBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        windowBatch.Normal3f(0.0f, 1.0f, 0.0f);
        windowBatch.Vertex3f(1.0f, 2.0f, 0.0f);

        windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f);
        windowBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        windowBatch.Normal3f( 0.0f, 1.0f, 0.0f);
        windowBatch.Vertex3f(-1.0f, 2.0f, 0.0f);
    windowBatch.End();

    const float width = 0.2f;
    windowBorderBatch.Begin(GL_TRIANGLE_STRIP, 13);
        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(-1.01f, width, 0.01f);

        windowBorderBatch.Normal3f(0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(-1.01f, 0.0f, 0.01f);

        windowBorderBatch.Normal3f(0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(1.01f, width, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(1.01f, 0.0f, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(1.01-width, 0.0f, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(1.01f, 2.0f, 0.01f);
            
        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(1.01-width, 2.0f, 0.01f);
            
        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(1.01f, 2.0-width, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(-1.01f, 2.f, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(-1.01f, 2.0-width, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(-1.01+width, 2.f, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(-1.01f, 0.0f, 0.01f);

        windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f);
        windowBorderBatch.Vertex3f(-1.01+width, 0.0f, 0.01f);
    windowBorderBatch.End();

    const float gridWidth = (float)0.01;
    const int gridLineCount = 24;
    windowGridBatch.Begin(GL_TRIANGLES, gridLineCount*2*6);
        // bottom horizontal
        
        for(int i=0; i<gridLineCount; i++)
        {
            float offset = 2*((float)(i+1)/(float)(gridLineCount+1));
            windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(-1.0f, offset+gridWidth, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(-1.0f, offset-gridWidth, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(1.0f, offset-gridWidth, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(1.0f,offset-gridWidth, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(1.0f, offset+gridWidth, 0.01f);

            windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(-1.0f, offset+gridWidth, 0.01f);
        }

        //  Verticals
        for(int i=0; i<gridLineCount; i++)
        {
            float offset = 2*((float)(i+1)/(float)(gridLineCount+1)) - 1.0;
            windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(offset+gridWidth, 0.0f, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(offset-gridWidth, 0.0f, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(offset-gridWidth, 2.0f, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(offset-gridWidth, 2.0f, 0.01f);

            windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(offset+gridWidth, 2.0, 0.01f);

            windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f);
            windowGridBatch.Vertex3f(offset+gridWidth, 0.0f, 0.01f);
        }
    
    windowGridBatch.End();

    glGenTextures(1, textures);
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    LoadBMPTexture("marble.bmp", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);

    // Setup HDR render texture
    glGenTextures(1, hdrTextures);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, hdrTextures[0]);
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB16F, screenWidth, screenHeight, GL_FALSE);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

    // Attach HDR texture to fbo
    // Create and bind an FBO
    glGenFramebuffers(1,hdrFBO);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, hdrFBO[0]);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hdrTextures[0], 0);
    
    // Create window texture
    glGenTextures(1, &windowTexture);
    glBindTexture(GL_TEXTURE_2D, windowTexture);
    GLuint texWidth = 0;
    GLuint texHeight = 0;
    // Load HDR image from EXR file
    LoadOpenEXRImage("window.exr", windowTexture, texWidth, texHeight);

    // Load flat color shader
    flatColorProg =  gltLoadShaderPairWithAttributes("basic.vs", "color.fs", 3, 
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_NORMAL, "vNormal", 
                            GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0");
    glBindFragDataLocation(flatColorProg, 0, "oColor");
    glBindFragDataLocation(flatColorProg, 1, "oBright");
    glLinkProgram(flatColorProg);

    // Load texture replace shader
    texReplaceProg =  gltLoadShaderPairWithAttributes("basic.vs", "tex_replace.fs", 3, 
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_NORMAL, "vNormal", 
                            GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0");
    glBindFragDataLocation(texReplaceProg, 0, "oColor");
    glBindFragDataLocation(texReplaceProg, 1, "oBright");
    glLinkProgram(texReplaceProg);

    // Load bloom shader
    hdrResolve =  gltLoadShaderPairWithAttributes("basic.vs", "hdr_exposure.fs", 3, 
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_NORMAL, "vNormal", 
                            GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0");
    glBindFragDataLocation(hdrResolve, 0, "oColor");
    glLinkProgram(hdrResolve);

    // Uncomment the line below to get the correct behavior.
    floorBatch.Draw();

    // Get the location of each multisample sample
    int sampleCount = 0;
    glGetIntegerv(GL_SAMPLES, &sampleCount);

    float positions[64]; // Enough for at least 32 samples
    for(int i =0; i < sampleCount; i++)
    {
        glGetMultisamplefv(GL_SAMPLE_POSITION, i, &positions[i*2]);
    }

    // Limit sample count to 8x
    //assert(sampleCount >= 8);
    sampleCount = 8;

    float invertedSampleDistances[8];
    // The maxDist is used for doing the distance inversion
    // You could use the actual max dist a sample could be, but that
    // would mean that sample would receive a weighting of 0, use 1.0 instead.
    //float maxDist = sqrt(0.5*0.5*2);
    float maxDist = 1.0f;

    // calculate the distance of each sample from the center,
    // then invert it so that samples closer to the center recieve more weight
    for(int i=0; i<8; i++)
    {
        double xDist = positions[i*2  ]-0.5;
        double yDist = positions[i*2+1]-0.5;
        invertedSampleDistances[i] = maxDist - sqrt(xDist*xDist + yDist*yDist);
    }
    
    // zero out sample weights array
    for(int i=0; i<8; i++)
    {
        for(int j=0; j<8; j++)
        {
            sampleWeights[i][j] = 0.0f;
        }
    }

    // First array is easy, 1 sample so that samples weight is 1
    sampleWeights[0][0] = 1.0f;

    // Add up the distances to get the total used for calculating weights
    for(int i=1; i<8; i++)
    {
        float totalWeight = 0.0f;
        for(int j=0; j<=i; j++)
            totalWeight += invertedSampleDistances[j];

        // Invert to get the factor used for each sample, the sum of all sample weights is always 1.0
        float perSampleFactor = 1 / totalWeight;
        for(int j=0; j<=i; j++)
            sampleWeights[i][j] = invertedSampleDistances[j] * perSampleFactor;
    }
    
    // Setup a texture buffer object for holding the sample weights
    glGenBuffers(1, &sampleWeightBuf);
    glBindBuffer(GL_TEXTURE_BUFFER_ARB, sampleWeightBuf);
    glBufferData(GL_TEXTURE_BUFFER_ARB, sizeof(float)*8, sampleWeights, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_TEXTURE_BUFFER_ARB, 0);

    // Load the texBO into texture 1
	glActiveTexture(GL_TEXTURE1);
    glGenTextures(1, &texBOTexture);
	glBindTexture(GL_TEXTURE_BUFFER_ARB, texBOTexture);
	glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_R32F, sampleWeightBuf); 
	glActiveTexture(GL_TEXTURE0);

    // Reset framebuffer binding
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

}
///////////////////////////////////////////////////////////////////////////////
// Update the camera based on user input, toggle display modes
// 
void SpecialKeys(int key, int x, int y)
{
	static CStopWatch cameraTimer;
	float fTime = cameraTimer.GetElapsedSeconds();
	cameraTimer.Reset(); 

	float linear = fTime * 3.0f;
	float angular = fTime * float(m3dDegToRad(60.0f));

	if(key == GLUT_KEY_UP)
		cameraFrame.MoveForward(linear);

	if(key == GLUT_KEY_DOWN)
		cameraFrame.MoveForward(-linear);

	if(key == GLUT_KEY_LEFT)
		cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);

	if(key == GLUT_KEY_RIGHT)
		cameraFrame.RotateWorld(-angular, 0.0f, 1.0f, 0.0f);

	static bool bF2IsDown = false;
	if(key == GLUT_KEY_F2)
	{
		if(bF2IsDown == false)
		{
			bF2IsDown = true;
			bUseFBO = !bUseFBO;
		}
	}
	else
	{
		bF2IsDown = false; 
	}

#ifndef OPENGL_ES
	if(key == GLUT_KEY_F3)
	{
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_BUFFER_ARB, texBOTexture);
		glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_R32F, texBO[0]); // FIX THIS IN GLEE
		glActiveTexture(GL_TEXTURE0);
	}
	else if(key == GLUT_KEY_F4)
	{
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_BUFFER_ARB, texBOTexture);
		glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_R32F, texBO[1]); // FIX THIS IN GLEE
		glActiveTexture(GL_TEXTURE0);
	}
	else if(key == GLUT_KEY_F5)
	{
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_BUFFER_ARB, texBOTexture);
		glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_R32F, texBO[2]); // FIX THIS IN GLEE
		glActiveTexture(GL_TEXTURE0);
	}
#endif

	 // Refresh the Window
	 glutPostRedisplay();
}
///////////////////////////////////////////////////////////////////////////////
// OpenGL related startup code is safe to put here. Load textures, etc.
void SetupRC()
{
#ifndef ANGLE
    GLenum err = glewInit();
	if (GLEW_OK != err)
	{
		/* Problem: glewInit failed, something is seriously wrong. */
		fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
	}
#endif

	// Initialze Shader Manager
	shaderManager.InitializeStockShaders();

	glEnable(GL_DEPTH_TEST);

	// Black
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

#if defined __APPLE__ || defined ANGLE
    ninja.LoadFromSBM("ninja.sbm",
                      GLT_ATTRIBUTE_VERTEX,
                      GLT_ATTRIBUTE_NORMAL,
                      GLT_ATTRIBUTE_TEXTURE0);    
#else
    ninja.LoadFromSBM("../../../Src/Models/Ninja/ninja.sbm",
        GLT_ATTRIBUTE_VERTEX,
        GLT_ATTRIBUTE_NORMAL,
        GLT_ATTRIBUTE_TEXTURE0);
#endif
	gltMakeTorus(torusBatch, 0.4f, 0.15f, 35, 35);
	gltMakeSphere(sphereBatch, 0.1f, 26, 13);

	GLfloat alpha = 0.25f;
	floorBatch.Begin(GL_TRIANGLE_FAN, 4, 1);
		floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
		floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
		floorBatch.Normal3f(0.0, 1.0f, 0.0f);
		floorBatch.Vertex3f(-20.0f, -0.41f, 20.0f);

		floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
		floorBatch.MultiTexCoord2f(0, 10.0f, 0.0f);
		floorBatch.Normal3f(0.0, 1.0f, 0.0f);
		floorBatch.Vertex3f(20.0f, -0.41f, 20.0f);

		floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
		floorBatch.MultiTexCoord2f(0, 10.0f, 10.0f);
		floorBatch.Normal3f(0.0, 1.0f, 0.0f);
		floorBatch.Vertex3f(20.0f, -0.41f, -20.0f);

		floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha);
		floorBatch.MultiTexCoord2f(0, 0.0f, 10.0f);
		floorBatch.Normal3f(0.0, 1.0f, 0.0f);
		floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
	floorBatch.End();

	glGenTextures(1, textures);
	glBindTexture(GL_TEXTURE_2D, textures[0]);
	LoadBMPTexture("marble.bmp", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);

    glGenTextures(1, ninjaTex);
	glBindTexture(GL_TEXTURE_2D, ninjaTex[0]);
#if defined __APPLE__
	LoadBMPTexture("NinjaComp.bmp", GL_LINEAR, GL_LINEAR, GL_CLAMP);
#elif defined ANGLE
	LoadBMPTexture("NinjaComp.bmp", GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);
#else
	LoadBMPTexture("../../../Src/Models/Ninja/NinjaComp.bmp", GL_LINEAR, GL_LINEAR, GL_CLAMP);
#endif

	glGenFramebuffers(1,&fboName);

	// Create depth renderbuffer
	glGenRenderbuffers(1, &depthBufferName);
	glBindRenderbuffer(GL_RENDERBUFFER, depthBufferName);
#ifndef ANGLE
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, screenWidth, screenHeight);
#else
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screenWidth, screenHeight);
#endif

	// Create 3 color renderbuffers
	glGenRenderbuffers(3, renderBufferNames);
	glBindRenderbuffer(GL_RENDERBUFFER, renderBufferNames[0]);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, screenWidth, screenHeight);
	glBindRenderbuffer(GL_RENDERBUFFER, renderBufferNames[1]);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, screenWidth, screenHeight);
	glBindRenderbuffer(GL_RENDERBUFFER, renderBufferNames[2]);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, screenWidth, screenHeight);

	// Attach all 4 renderbuffers to FBO
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboName);
	glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBufferName);
	glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBufferNames[0]);
#ifndef OPENGL_ES
	glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, renderBufferNames[1]);
	glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, renderBufferNames[2]);
#endif

	// See bind frag location in Chapter 9
    processProg =  gltLoadShaderPairWithAttributes("multibuffer.vs", "multibuffer_frag_location.fs", 3,
								GLT_ATTRIBUTE_VERTEX, "vVertex", 
								GLT_ATTRIBUTE_NORMAL, "vNormal", 
								GLT_ATTRIBUTE_TEXTURE0, "texCoord0");
#ifndef OPENGL_ES
	glBindFragDataLocation(processProg, 0, "oStraightColor");
	glBindFragDataLocation(processProg, 1, "oGreyscale");
	glBindFragDataLocation(processProg, 2, "oLumAdjColor"); 
#endif
	glLinkProgram(processProg);

#ifndef OPENGL_ES
	// Create 3 new buffer objects
	glGenBuffers(3,texBO);
	glGenTextures(1, &texBOTexture);
	
	int count = 0;
	float* fileData = 0;

	// Load first texBO with a tangent-like curve, 1024 values
	fileData = LoadFloatData("LumTan.data", &count);
	if (count > 0)
	{
		glBindBuffer(GL_TEXTURE_BUFFER_ARB, texBO[0]);
		glBufferData(GL_TEXTURE_BUFFER_ARB, sizeof(float)*count, fileData, GL_STATIC_DRAW);
		delete fileData;
	}

	// Load second texBO with a sine-like curve, 1024 values
	fileData = LoadFloatData("LumSin.data", &count);
	if (count > 0)
	{
		glBindBuffer(GL_TEXTURE_BUFFER_ARB, texBO[1]);
		glBufferData(GL_TEXTURE_BUFFER_ARB, sizeof(float)*count, fileData, GL_STATIC_DRAW);
		delete fileData;
	}

	// Load third texBO with a linear curve, 1024 values
	fileData = LoadFloatData("LumLinear.data", &count);
	if (count > 0)
	{
		glBindBuffer(GL_TEXTURE_BUFFER_ARB, texBO[2]);
		glBufferData(GL_TEXTURE_BUFFER_ARB, sizeof(float)*count, fileData, GL_STATIC_DRAW);
		delete fileData;
	}

	// Load the Tan ramp first
	glBindBuffer(GL_TEXTURE_BUFFER_ARB, 0);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_BUFFER_ARB, texBOTexture);
	glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_R32F, texBO[0]); 
#endif
	glActiveTexture(GL_TEXTURE0);

	// Reset framebuffer binding
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

	// Make sure all went well
	gltCheckErrors();
}
GLboolean ParticleInstancingRenderer::CopyParticleDataToGpuBuffers(size_t start, size_t count, \
                                                                   GLuint tbo_position_radius, GLuint tex_position_radius, GLuint tbo_color, GLuint tex_color )
{
    const size_t number_of_particles = count;

    float* mapped_position_radius = 0;
    unsigned char* mapped_color = 0;


    // bind the buffers and get a mapped pointer to the elements
    glBindBufferARB ( GL_TEXTURE_BUFFER_ARB, tbo_position_radius );
    CheckOpenGLError();

    // rebind the texture to the buffer
    // it's not clear why this is needed, but if we don't do it 
    // occasionally no objects get rendered.
    glBindTexture(GL_TEXTURE_BUFFER_ARB, tex_position_radius);
    CheckOpenGLError();
    glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_RGBA32F_ARB, tbo_position_radius);
    CheckOpenGLError();
    glBindTexture(GL_TEXTURE_BUFFER_ARB, 0);
    CheckOpenGLError();

//#define GLMAPBUFFER
#ifdef GLMAPBUFFER
    mapped_position_radius = reinterpret_cast<float*>(glMapBufferARB(GL_TEXTURE_BUFFER_ARB, GL_WRITE_ONLY));
    CheckOpenGLError();

    if(!mapped_position_radius)
        cerr << " mapped_position_radius null " << endl;
#else
    glBufferData(GL_TEXTURE_BUFFER_ARB, count*4*sizeof(float), &particle_position_radius[start], GL_DYNAMIC_DRAW);
    CheckOpenGLError();
#endif


    // bind the buffers and get a mapped pointer to the elements
    glBindBufferARB ( GL_TEXTURE_BUFFER_ARB, tbo_color);
    CheckOpenGLError();

    // rebind the texture to the buffer
    // it's not clear why this is needed, but if we don't do it 
    // occasionally no objects get rendered.
    glBindTexture(GL_TEXTURE_BUFFER_ARB, tex_color);
    CheckOpenGLError();
    glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_RGBA8, tbo_color);
    CheckOpenGLError();
    glBindTexture(GL_TEXTURE_BUFFER_ARB, 0);
    CheckOpenGLError();

#ifdef GLMAPBUFFER
    mapped_color = reinterpret_cast<unsigned char*>(glMapBufferARB(GL_TEXTURE_BUFFER_ARB, GL_WRITE_ONLY));
    CheckOpenGLError();

    if(!mapped_color)
        cerr << "mapping failed: mapped_color null" << endl;
#else
    glBufferData(GL_TEXTURE_BUFFER_ARB, count*4*sizeof(unsigned char), &particle_color[start], GL_DYNAMIC_DRAW);
    CheckOpenGLError();
#endif

#ifdef GLMAPBUFFER

    // now fill the buffer, this could be accelerated using OpenMP
    for(size_t i = 0; i < number_of_particles; ++ i)
    {
        const size_t p = start + i;

        mapped_position_radius[4 * i + 0] = particle_position_radius[p*4+0];
        mapped_position_radius[4 * i + 1] = particle_position_radius[p*4+1];
        mapped_position_radius[4 * i + 2] = particle_position_radius[p*4+2];
        mapped_position_radius[4 * i + 3] = particle_position_radius[p*4+3];

        mapped_color[4 * i + 0] = particle_color[p*4+0];
        mapped_color[4 * i + 1] = particle_color[p*4+1];
        mapped_color[4 * i + 2] = particle_color[p*4+2];
        mapped_color[4 * i + 3] = particle_color[p*4+3];
    }


    // unmap buffers
    const GLboolean unmapped_color = glUnmapBufferARB(GL_TEXTURE_BUFFER_ARB);
    CheckOpenGLError();

    glBindBufferARB(GL_TEXTURE_BUFFER_ARB, tbo_position_radius);
    CheckOpenGLError();

    const GLboolean unmapped_position_radius = glUnmapBufferARB(GL_TEXTURE_BUFFER_ARB);
    CheckOpenGLError();

#endif
    glBindBufferARB(GL_TEXTURE_BUFFER_ARB, 0);
    CheckOpenGLError();

    /*
    if(!(unmapped_color==GL_TRUE &&  unmapped_position_radius==GL_TRUE))
        cerr << "unmapping failed: unmapped_color" << static_cast<unsigned int>(unmapped_color) << " unmapped_position_radius" << static_cast<unsigned int>(unmapped_position_radius) << endl;

    return unmapped_color &&  unmapped_position_radius;
    */
    return true;
}