예제 #1
0
// Map for data access
U8* LLVertexBuffer::mapBuffer(S32 access)
{
    LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
    if (mFinal)
    {
        llwarns << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
    }
    if (!useVBOs() && !mMappedData && !mMappedIndexData)
    {
        llwarns << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
    }

    if (!mLocked && useVBOs())
    {
        setBuffer(0);
        mLocked = TRUE;
        stop_glerror();
        mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
        stop_glerror();
        mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
        stop_glerror();

        if (!mMappedData)
        {
            //--------------------
            //print out more debug info before crash
            llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
            GLint size ;
            glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
            llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
            //--------------------

            GLint buff;
            glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
            if (buff != mGLBuffer)
            {
                llwarns << "Invalid GL vertex buffer bound: " << buff << llendl;
            }


            llwarns << "glMapBuffer returned NULL (no vertex data)" << llendl;
        }

        if (!mMappedIndexData)
        {
            GLint buff;
            glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
            if (buff != mGLIndices)
            {
                llwarns << "Invalid GL index buffer bound: " << buff << llendl;
            }

            llwarns << "glMapBuffer returned NULL (no index data)" << llendl;
        }

        sMappedCount++;
    }

    return mMappedData;
}
// copy image and process using OpenCL
//*****************************************************************************
void processImage()
{
    // activate destination buffer
    glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo_source);

    //// read data into pbo. note: use BGRA format for optimal performance
    glReadPixels(0, 0, image_width, image_height, GL_BGRA, GL_UNSIGNED_BYTE, NULL); 

    if (bPostprocess)
    {
        if (iProcFlag == 0) 
        {
            pboRegister();
            executeKernel(blur_radius);
            pboUnregister();
        } 
        else 
        {
            // map the PBOs
            glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbo_source);    
            glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_dest);    
            
            unsigned int* source_ptr = (unsigned int*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
                                                                     GL_READ_ONLY_ARB);
            
            unsigned int* dest_ptr = (unsigned int*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
                                                                   GL_WRITE_ONLY_ARB);
            
            // Postprocessing on the CPU
            postprocessHost(source_ptr, dest_ptr, image_width, image_height, 0, blur_radius, 0.8f, 4.0f);
            
            // umap the PBOs
            glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
            glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
            glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); 
            glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
        }

        // download texture from PBO
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_dest);
        glBindTexture(GL_TEXTURE_2D, tex_screen);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 
                        image_width, image_height, 
                        GL_BGRA, GL_UNSIGNED_BYTE, NULL);

    } 
    else 
    {
        // download texture from PBO
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_source);
        glBindTexture(GL_TEXTURE_2D, tex_screen);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 
                        image_width, image_height, 
                        GL_BGRA, GL_UNSIGNED_BYTE, NULL);
        
    }
}
예제 #3
0
파일: ofxPBO.cpp 프로젝트: alg-a/GAmuza
void ofxPBO::loadData(const ofPixels & pixels){
	if(pboIds.empty()){
		ofLogError() << "pbo not allocated";
		return;
	}
    index = (index + 1) % pboIds.size();
    int nextIndex = (index + 1) % pboIds.size();
    
	// bind PBO to update pixel values
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboIds[nextIndex]);
    
	// map the buffer object into client's memory
	// Note that glMapBufferARB() causes sync issue.
	// If GPU is working with this buffer, glMapBufferARB() will wait(stall)
	// for GPU to finish its job. To avoid waiting (stall), you can call
	// first glBufferDataARB() with NULL pointer before glMapBufferARB().
	// If you do that, the previous data in PBO will be discarded and
	// glMapBufferARB() returns a new allocated pointer immediately
	// even if GPU is still working with the previous data.
	glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, dataSize, 0, GL_STREAM_DRAW_ARB);
	GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
	if(ptr)
	{
		// update data directly on the mapped buffer
		memcpy(ptr,pixels.getPixels(),dataSize);
		glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer
	}
    
    // it is good idea to release PBOs with ID 0 after use.
    // Once bound with 0, all pixel operations behave normal ways.
    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
}
예제 #4
0
//////////////////////////////////////////////////////////////////////
//  readback
//
//////////////////////////////////////////////////////////////////////
bool CheckBackBuffer::readback( GLuint width, GLuint height )
{
    bool ret = false;

    if (m_bUsePBO) 
    {
        // binds the PBO for readback
        bindReadback();

        // Initiate the readback BLT from BackBuffer->PBO->membuf
	    glReadPixels(0, 0, width, height, getPixelFormat(),      GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
        ret = checkStatus(__FILE__, __LINE__, true);
        if (!ret) printf("CheckBackBuffer::glReadPixels() checkStatus = %d\n", ret);

	    // map - unmap simulates readback without the copy
	    void *ioMem = glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
        memcpy(m_pImageData,    ioMem, width*height*m_Bpp);

		glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);

        // release the PBO
        unbindReadback();
    } else {
        // reading direct from the backbuffer
        glReadBuffer(GL_FRONT);
        glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
    }

    return ret; 
}
예제 #5
0
void * CIndexBuffer::Lock( uint nOffset, size_t nSize, bool bReadBack  )
{
	DEBUG_ASSERT( 0 == nOffset ); // offset not supported

	//--------------------------------------------------------------------------
	// Tip: Выходим, если буффер уже залочен
	//--------------------------------------------------------------------------
	if ( m_bLocked )
	{
		DEBUG_ASSERT( !"Try to lock locked buffer" );
		return NULL;
	}

	byte * pResult = NULL;

	if ( g_pRenderer->IsExtSupported( EXT_GL_VBO ) )
	{
		glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_nBufferID );
		GL_VALIDATE;

		pResult = (byte *)glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
			bReadBack ? GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB );
		GL_VALIDATE;

		glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
		GL_VALIDATE;
	}
	else
	{
		pResult = m_pMemBuffer;
	}

	m_bLocked = true;
	return pResult;
}
예제 #6
0
파일: renderer.cpp 프로젝트: adasm/vxc
void Renderer::flushText()
{
	if (!currentFont) return;
	if (!bindShader(textShader))
		return;

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, currentFont->tex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
	glEnableVertexAttribArrayARB(uniform_coord);
	glVertexAttribPointerARB(uniform_coord, 4, GL_FLOAT, GL_FALSE, sizeof(TextVertex), 0);
	glEnableVertexAttribArrayARB(uniform_atr);
	glVertexAttribPointerARB(uniform_atr, 4, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const void *)(offsetof(TextVertex, c)));
	float* ptr = (float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
	if (ptr)
	{
		memcpy(ptr, textVertexBuffer, sizeof(TextVertex)* currentTextVertexBufferPos);
		glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
		glDrawArrays(GL_TRIANGLES, 0, currentTextVertexBufferPos);
	}

	currentTextVertexBufferPos = 0;
}
예제 #7
0
파일: sdlgl.cpp 프로젝트: dirkcuys/texgen
GLubyte* SDLGLMain::renderGeneToSurface(const Tai::SimpleGene &gene)
{
    // render to texture
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);

    renderGene(gene);

    //glFlush();
    SDL_GL_SwapBuffers();


    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    glBindTexture(GL_TEXTURE_2D, m_fbTex);

    //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, m_pbo);
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
    GLubyte* texBuf = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
    GLubyte *image = new GLubyte[m_width*m_height*4];
    if (texBuf != 0)
    {
        // do something with the texture
        //return texBuf;
        memcpy(image, texBuf, m_width*m_height*4);
        glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
    }
    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);//*/
    return image;
}
static void
_cairo_gl_emit_glyph_rectangle (cairo_gl_context_t *ctx,
				cairo_gl_glyphs_setup_t *setup,
				int x1, int y1,
				int x2, int y2,
				cairo_gl_glyph_private_t *glyph)
{
    if (setup->vb != NULL &&
	setup->vb_offset + 4 * setup->vertex_size > setup->vbo_size) {
	_cairo_gl_flush_glyphs (ctx, setup);
    }

    if (setup->vb == NULL) {
	glBufferDataARB (GL_ARRAY_BUFFER_ARB,
			 setup->vbo_size * sizeof (GLfloat),
			 NULL, GL_STREAM_DRAW_ARB);
	setup->vb = glMapBufferARB (GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
	setup->vb_offset = 0;
    }

    _cairo_gl_glyphs_emit_vertex (setup, x1, y1, glyph->p1.x, glyph->p1.y);
    _cairo_gl_glyphs_emit_vertex (setup, x2, y1, glyph->p2.x, glyph->p1.y);
    _cairo_gl_glyphs_emit_vertex (setup, x2, y2, glyph->p2.x, glyph->p2.y);
    _cairo_gl_glyphs_emit_vertex (setup, x1, y2, glyph->p1.x, glyph->p2.y);
    setup->num_prims++;
}
void btParticlesDynamicsWorld::createVBO()
{
    // create buffer object
    glGenBuffers(1, &m_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
	// positions of spheres
    unsigned int memSize = sizeof(btVector3) *  m_numParticles;
    glBufferData(GL_ARRAY_BUFFER, memSize, 0, GL_DYNAMIC_DRAW);
	// colors
	GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, memSize, 0, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    m_colVbo = vbo;
    // fill color buffer
    glBindBufferARB(GL_ARRAY_BUFFER, m_colVbo);
    float *data = (float*)glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    float *ptr = data;
    for(int i = 0; i < m_numParticles; i++) 
	{
        float t = i / (float)m_numParticles;
		ptr[0] = 0.f;
		ptr[1] = 1.f;
		ptr[2] = 0.f;
        ptr+=3;
        *ptr++ = 1.0f;
    }
    glUnmapBufferARB(GL_ARRAY_BUFFER);
	glBindBufferARB(GL_ARRAY_BUFFER, 0);
}
예제 #10
0
//--------------------------------------------------------------
void RayTracingKernel::update() {
	// Transfer ownership of buffer from GL to CL
#ifdef GL_INTEROP
	// Acquire PBO for OpenCL writing
	clErr = clEnqueueAcquireGLObjects(commandQ, 1, &pbo_cl, 0, 0, 0);
	if (!checkOpenClError(clErr, "clEnqueueAcquireGLObjects")) return;		
#endif
	clErr = clEnqueueWriteBuffer(commandQ, d_invViewMatrix,CL_FALSE, 0,12*sizeof(float), invViewMatrix, 0, 0, 0);
//		if (!checkOpenClError(clErr, "clEnqueueWriteBuffer")) return;		
	
	enqueue();
	
#ifdef GL_INTEROP
	// Transfer ownership of buffer back from CL to GL
	clErr = clEnqueueReleaseGLObjects(commandQ, 1, &pbo_cl, 0, 0, 0);
	if (!checkOpenClError(clErr, "clEnqueueReleaseGLObjects")) return;		
#else
	// Explicit Copy
	// map the PBO to copy data from the CL buffer via host
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
	
	// map the buffer object into client's memory
	GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
											GL_WRITE_ONLY_ARB);
	clErr = clEnqueueReadBuffer(commandQ, pbo_cl, CL_TRUE, 0,
						sizeof(unsigned int) * width * height,
						ptr, 0, NULL, NULL);
//		if (!checkOpenClError(clErr, "clEnqueueReadBuffer")) return;		
	glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
#endif		
}
예제 #11
0
int
bot_gtk_gl_image_area_upload_image (BotGtkGlImageArea * self,
        const void *data, int row_stride)
{
    if (self->use_pbo && (row_stride * self->height) > self->max_data_size) {
        fprintf (stderr, "Error: gl_texture buffer (%d bytes) too small for "
                "texture (%d bytes)\n", self->max_data_size, 
                row_stride * self->height);
        return -1;
    }
    if (!data && !self->use_pbo) {
        fprintf (stderr, "Error: gl_texture data is NULL\n");
        return -1;
    }
    GLenum type = GL_UNSIGNED_BYTE;

    glBindTexture (self->target, self->texname);

    glTexParameterf (self->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf (self->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    if (row_stride % 2) {
        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    } else if (row_stride % 4) {
        glPixelStorei (GL_UNPACK_ALIGNMENT, 2);
    } else {
        glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
    }

    glPixelStorei (GL_UNPACK_ROW_LENGTH, 
            row_stride * 8 / _pixel_format_bpp (self->format));
    if (self->use_pbo) {
        glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB, self->pbo);

        /* By setting data to NULL, we skip the memcpy and just re-upload
         * from the buffer object.  This can be useful to re-upload with
         * different PixelTransfer settings. */
        if (data) {
            uint8_t *buffer_data = 
                (uint8_t*) glMapBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB,
                        GL_WRITE_ONLY);
            memcpy (buffer_data, data, row_stride * self->height);
            glUnmapBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB);
        }

        glTexImage2D (self->target, 0, self->int_format, 
                self->width, self->height, 0,
                self->format, type, 0);

        glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    } else {
        glTexImage2D (self->target, 0, self->int_format, 
                self->width, self->height, 0,
                self->format, type, data);
    }
    glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
    glBindTexture (self->target, 0);
    return 0;
}
void ParticleSystem::_initialize(int numParticles){
    assert(!m_bInitialized);
    m_numParticles = numParticles;

    //Allocate host storage
    m_hPos          = (float *)malloc(m_numParticles * 4 * sizeof(float));
    m_hVel          = (float *)malloc(m_numParticles * 4 * sizeof(float));
    m_hReorderedPos = (float *)malloc(m_numParticles * 4 * sizeof(float));
    m_hReorderedVel = (float *)malloc(m_numParticles * 4 * sizeof(float));
    m_hHash         = (uint  *)malloc(m_numParticles * sizeof(uint));
    m_hIndex        = (uint  *)malloc(m_numParticles * sizeof(uint));
    m_hCellStart    = (uint  *)malloc(m_numGridCells * sizeof(uint));
    m_hCellEnd      = (uint  *)malloc(m_numGridCells * sizeof(uint));

    memset(m_hPos, 0, m_numParticles * 4 * sizeof(float));
    memset(m_hVel, 0, m_numParticles * 4 * sizeof(float));
    memset(m_hCellStart, 0, m_numGridCells * sizeof(uint));
    memset(m_hCellEnd,   0, m_numGridCells * sizeof(uint));

    //Allocate GPU data
    shrLog("Allocating GPU Data buffers...\n\n");
    allocateArray(&m_dPos,          m_numParticles * 4 * sizeof(float));
    allocateArray(&m_dVel,          m_numParticles * 4 * sizeof(float));
    allocateArray(&m_dReorderedPos, m_numParticles * 4 * sizeof(float));
    allocateArray(&m_dReorderedVel, m_numParticles * 4 * sizeof(float));
    allocateArray(&m_dHash,         m_numParticles * sizeof(uint));
    allocateArray(&m_dIndex,        m_numParticles * sizeof(uint));
    allocateArray(&m_dCellStart,    m_numGridCells * sizeof(uint));
    allocateArray(&m_dCellEnd,      m_numGridCells * sizeof(uint));

    if (!m_bQATest)
    {
        //Allocate VBO storage
        m_posVbo   = createVBO(m_numParticles * 4 * sizeof(float));
        m_colorVBO = createVBO(m_numParticles * 4 * sizeof(float));

        //Fill color buffer
        glBindBufferARB(GL_ARRAY_BUFFER, m_colorVBO);
        float *data = (float *)glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
            float *ptr = data;
            for(uint i = 0; i < m_numParticles; i++){
                float t = (float)i / (float) m_numParticles;
                #if 0
                    *ptr++ = rand() / (float) RAND_MAX;
                    *ptr++ = rand() / (float) RAND_MAX;
                    *ptr++ = rand() / (float) RAND_MAX;
                #else
                    colorRamp(t, ptr);
                    ptr += 3;
                #endif
                *ptr++ = 1.0f;
            }
        glUnmapBufferARB(GL_ARRAY_BUFFER);
    }

    setParameters(&m_params);
    setParametersHost(&m_params);
    m_bInitialized = true;
}
U8* LLVertexBuffer::mapIndexBuffer(S32 access)
{
	LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
	if (mFinal)
	{
		llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
	}
	if (!useVBOs() && !mMappedData && !mMappedIndexData)
	{
		llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
	}

	if (!mIndexLocked && useVBOs())
	{
		{
			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);

			setBuffer(0, TYPE_INDEX);
			mIndexLocked = TRUE;
			stop_glerror();	

			if(sDisableVBOMapping)
			{
				allocateClientIndexBuffer() ;
			}
			else
			{
				mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
			}
			stop_glerror();
		}

		if (!mMappedIndexData)
		{
			log_glerror();

			if(!sDisableVBOMapping)
			{
				GLint buff;
				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
				if ((GLuint)buff != mGLIndices)
				{
					llerrs << "Invalid GL index buffer bound: " << buff << llendl;
				}

				llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
			}
			else
			{
				llerrs << "memory allocation for Index data failed. " << llendl ;
			}
		}

		sMappedCount++;
	}

	return mMappedIndexData ;
}
예제 #14
0
void Topo3PrimalRender<PFP>::pushColors()
{
	m_color_save = new float[6*m_nbDarts];
	m_vbo2->bind();
	void* colorBuffer = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);

	memcpy(m_color_save, colorBuffer, 6*m_nbDarts*sizeof(float));
	glUnmapBuffer(GL_ARRAY_BUFFER);
}
예제 #15
0
파일: pbo-teximage.c 프로젝트: RAOF/piglit
PIGLIT_GL_TEST_CONFIG_END

enum piglit_result
piglit_display(void)
{
	GLboolean pass = GL_TRUE;
	static float red[] = {1.0, 0.0, 0.0, 0.0};
	static float green[] = {0.0, 1.0, 0.0, 0.0};
	static float blue[]  = {0.0, 0.0, 1.0, 0.0};
	float *pixels;
	GLuint pbo, tex;

	glClearColor(0.5, 0.5, 0.5, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	glGenBuffersARB(1, &pbo);
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, pbo);
	glBufferDataARB(GL_PIXEL_UNPACK_BUFFER, 4 * 4 * sizeof(float),
			NULL, GL_STREAM_DRAW_ARB);
	pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY_ARB);

	memcpy(pixels + 0,  red, sizeof(red));
	memcpy(pixels + 4,  green, sizeof(green));
	memcpy(pixels + 8,  blue, sizeof(blue));
	memcpy(pixels + 12, red, sizeof(red));

	glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER);
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0,
		     GL_RGBA,
		     2, 2, 0,
		     GL_RGBA, GL_FLOAT, 0);
	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
	glDeleteBuffersARB(1, &pbo);

	glEnable(GL_TEXTURE_2D);
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(0.0, 0.0); glVertex2f(10, 10);
	glTexCoord2f(1.0, 0.0); glVertex2f(20, 10);
	glTexCoord2f(1.0, 1.0); glVertex2f(20, 20);
	glTexCoord2f(0.0, 1.0); glVertex2f(10, 20);
	glEnd();

	glDeleteTextures(1, &tex);

	pass &= piglit_probe_pixel_rgb(12, 12, red);
	pass &= piglit_probe_pixel_rgb(18, 12, green);
	pass &= piglit_probe_pixel_rgb(12, 18, blue);
	pass &= piglit_probe_pixel_rgb(18, 18, red);

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
예제 #16
0
	void* VertexBuffer::lock(uint offset,uint length,LockOptions options)
	{
		if(m_bLocked)return 0;

		GLenum access = 0;

		glBindBufferARB(GL_ARRAY_BUFFER,m_ui32BufferID);

		if(options == BL_DISCARD)
		{
			//TODO: really we should use this to indicate our discard of the buffer
			//However it makes no difference to fps on nVidia, and can crash some ATI
			//glBufferData_ptr(GL_ELEMENT_ARRAY_BUFFER, mSizeInBytes, NULL, 
			//    GLHardwareBufferManager::getGLUsage(mUsage));

			// TODO: we should be using the below implementation, but nVidia cards
			// choke on it and perform terribly - for investigation with nVidia
			//access = (mUsage == BU_DYNAMIC || mUsage == BU_STATIC) ? 
			//    GL_READ_WRITE : GL_WRITE_ONLY;
			access = GL_READ_WRITE;

		}
		else if(options == BL_READ_ONLY)
		{
			if(m_Usage == BU_WRITE_ONLY)
			{
				Warning("GLHardwareVertexBuffer: Locking a write-only vertex buffer for reading, performance TRACE0_WARNING.\n");
			}
			access = GL_READ_ONLY;
		}
		else if(options == BL_NORMAL || options == BL_NO_OVERWRITE)
		{
			// TODO: we should be using the below implementation, but nVidia cards
			// choke on it and perform terribly - for investigation with nVidia
			//access = (mUsage == BU_DYNAMIC || mUsage == BU_STATIC) ? 
			//    GL_READ_WRITE : GL_WRITE_ONLY;
			access = GL_READ_WRITE;
		}
		else
		{
			//default
			access = GL_READ_WRITE;
		}

		void* pBuffer = glMapBufferARB( GL_ARRAY_BUFFER,access);

		if(pBuffer == 0)
		{
			return 0;
		}

		m_bLocked = true;
		glBindBufferARB(GL_ARRAY_BUFFER,0);
		return static_cast<void*>(static_cast<unsigned char*>(pBuffer) + offset);
	}
예제 #17
0
void WaterRenderer::initContext(GLContextData& contextData) const
	{
	/* Create a data item and add it to the context: */
	DataItem* dataItem=new DataItem;
	contextData.addDataItem(this,dataItem);
	
	/* Upload the grid of template vertices into the vertex buffer: */
	glBindBufferARB(GL_ARRAY_BUFFER_ARB,dataItem->vertexBuffer);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB,waterGridSize[1]*waterGridSize[0]*sizeof(Vertex),0,GL_STATIC_DRAW_ARB);
	Vertex* vPtr=static_cast<Vertex*>(glMapBufferARB(GL_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB));
	for(unsigned int y=0;y<waterGridSize[1];++y)
		for(unsigned int x=0;x<waterGridSize[0];++x,++vPtr)
			{
			/* Set the template vertex' position to the pixel center's position: */
			vPtr->position[0]=GLfloat(x)+0.5f;
			vPtr->position[1]=GLfloat(y)+0.5f;
			}
	glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
	
	/* Upload the surface's triangle indices into the index buffer: */
	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,dataItem->indexBuffer);
	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,(waterGridSize[1]-1)*waterGridSize[0]*2*sizeof(GLuint),0,GL_STATIC_DRAW_ARB);
	GLuint* iPtr=static_cast<GLuint*>(glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB));
	for(unsigned int y=1;y<waterGridSize[1];++y)
		for(unsigned int x=0;x<waterGridSize[0];++x,iPtr+=2)
			{
			iPtr[0]=GLuint(y*waterGridSize[0]+x);
			iPtr[1]=GLuint((y-1)*waterGridSize[0]+x);
			}
	glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
	
	/* Create the water rendering shader: */
	dataItem->waterShader=linkVertexAndFragmentShader("WaterRenderingShader");
	GLint* ulPtr=dataItem->waterShaderUniforms;
	*(ulPtr++)=glGetUniformLocationARB(dataItem->waterShader,"quantitySampler");
	*(ulPtr++)=glGetUniformLocationARB(dataItem->waterShader,"bathymetrySampler");
	*(ulPtr++)=glGetUniformLocationARB(dataItem->waterShader,"modelviewGridMatrix");
	*(ulPtr++)=glGetUniformLocationARB(dataItem->waterShader,"tangentModelviewGridMatrix");
	*(ulPtr++)=glGetUniformLocationARB(dataItem->waterShader,"projectionModelviewGridMatrix");
	}
예제 #18
0
void GPU_update_grid_buffers(void *buffers_v, DMGridData **grids,
	int *grid_indices, int totgrid, int gridsize, int smooth)
{
	GPU_Buffers *buffers = buffers_v;
	DMGridData *vert_data;
	int i, j, k, totvert;

	totvert= gridsize*gridsize*totgrid;

	/* Build VBO */
	if(buffers->vert_buf) {
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
		glBufferDataARB(GL_ARRAY_BUFFER_ARB,
				 sizeof(DMGridData) * totvert,
				 NULL, GL_STATIC_DRAW_ARB);
		vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
		if(vert_data) {
			for(i = 0; i < totgrid; ++i) {
				DMGridData *grid= grids[grid_indices[i]];
				memcpy(vert_data, grid, sizeof(DMGridData)*gridsize*gridsize);

				if(!smooth) {
					/* for flat shading, recalc normals and set the last vertex of
					   each quad in the index buffer to have the flat normal as
					   that is what opengl will use */
					for(j = 0; j < gridsize-1; ++j) {
						for(k = 0; k < gridsize-1; ++k) {
							normal_quad_v3(vert_data[(j+1)*gridsize + (k+1)].no,
								vert_data[(j+1)*gridsize + k].co,
								vert_data[(j+1)*gridsize + k+1].co,
								vert_data[j*gridsize + k+1].co,
								vert_data[j*gridsize + k].co);
						}
					}
				}

				vert_data += gridsize*gridsize;
			}
			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
		}
		else {
			glDeleteBuffersARB(1, &buffers->vert_buf);
			buffers->vert_buf = 0;
		}
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
	}

	buffers->grids = grids;
	buffers->grid_indices = grid_indices;
	buffers->totgrid = totgrid;
	buffers->gridsize = gridsize;

	//printf("node updated %p\n", buffers_v);
}
 inline void* VL_glMapBuffer( GLenum target, GLenum access)
 {
   if (glMapBuffer)
     return glMapBuffer( target, access);
   else
   if (glMapBufferARB)
     return glMapBufferARB( target, access);
   else
     VL_UNSUPPORTED_FUNC();
   return 0;
 }
예제 #20
0
void Topo3PrimalRender<PFP>::popColors()
{
	m_vbo2->bind();
	void* colorBuffer = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);

	memcpy(colorBuffer, m_color_save, 6*m_nbDarts*sizeof(float));
	glUnmapBuffer(GL_ARRAY_BUFFER);

	delete[] m_color_save;
	m_color_save=0;
}
예제 #21
0
PIGLIT_GL_TEST_CONFIG_END

void
piglit_init(int argc, char**argv)
{
	GLfloat data = 1.0;
	GLfloat *v;
	GLuint buf;

	piglit_require_extension("GL_ARB_vertex_buffer_object");

	glGenBuffersARB(1, &buf);

	/* First, do a normal buffer create/data/delete */
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, 4, &data, GL_STATIC_DRAW_ARB);
	glDeleteBuffersARB(1, &buf);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* Then, another normal path: create, map, write, unmap, delete */
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, 4, NULL, GL_STATIC_DRAW_ARB);
	v = (GLfloat *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
	*v = data;
	glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
	glDeleteBuffersARB(1, &buf);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* Then, do the failing path: create, map, delete */
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, 4, NULL, GL_STATIC_DRAW_ARB);
	v = (GLfloat *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
	*v = data;
	glDeleteBuffersARB(1, &buf);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	piglit_report_result(PIGLIT_PASS);
}
void btParticlesDynamicsWorld::runComputeCellIdKernel()
{
    cl_int ciErrNum;
#if 0
	if(m_useCpuControls[SIMSTAGE_COMPUTE_CELL_ID]->m_active)
	{	// CPU version
		unsigned int memSize = sizeof(btVector3) * m_numParticles;
		ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL);
		oclCHECKERROR(ciErrNum, CL_SUCCESS);
		for(int index = 0; index < m_numParticles; index++)
		{
			btVector3 pos = m_hPos[index];
			btInt4 gridPos = cpu_getGridPos(pos, &m_simParams);
			unsigned int hash = cpu_getPosHash(gridPos, &m_simParams);
			m_hPosHash[index].x = hash;
			m_hPosHash[index].y = index;
		}
		memSize = sizeof(btInt2) * m_numParticles;
		ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL);
		oclCHECKERROR(ciErrNum, CL_SUCCESS);
	}
	else
#endif
	{
		BT_PROFILE("ComputeCellId");
		runKernelWithWorkgroupSize(PARTICLES_KERNEL_COMPUTE_CELL_ID, m_numParticles);
		ciErrNum = clFinish(m_cqCommandQue);
		oclCHECKERROR(ciErrNum, CL_SUCCESS);
	}
/*
	// check
	int memSize = sizeof(btInt2) * m_hashSize;
    ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL);
    oclCHECKERROR(ciErrNum, CL_SUCCESS);

	memSize = sizeof(float) * 4 * m_numParticles;
    ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL);
    oclCHECKERROR(ciErrNum, CL_SUCCESS);
*/

	{
		BT_PROFILE("Copy VBO");
		// Explicit Copy (until OpenGL interop will work)
		// map the PBO to copy data from the CL buffer via host
		glBindBufferARB(GL_ARRAY_BUFFER, m_vbo);    
		// map the buffer object into client's memory
		void* ptr = glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY_ARB);
		ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, sizeof(float) * 4 * m_numParticles, ptr, 0, NULL, NULL);
		oclCHECKERROR(ciErrNum, CL_SUCCESS);
		glUnmapBufferARB(GL_ARRAY_BUFFER); 
		glBindBufferARB(GL_ARRAY_BUFFER,0);
	}
}
예제 #23
0
static void
vbo_write_floats_mapped(const float *varray, size_t count)
{
	float *ptr = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);

	if (ptr == NULL)
		piglit_report_result(PIGLIT_FAIL);

	memcpy(ptr, varray, count * sizeof(GLfloat));

	if (!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB))
		piglit_report_result(PIGLIT_FAIL);
}
예제 #24
0
void Topo3PrimalRender<PFP>::setAllDartsColor(float r, float g, float b)
{
	m_vbo2->bind();
	GLvoid* ColorDartsBuffer = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);
	float* colorDartBuf = reinterpret_cast<float*>(ColorDartsBuffer);
	for (unsigned int i=0; i < 2*m_nbDarts; ++i)
	{
		*colorDartBuf++ = r;
		*colorDartBuf++ = g;
		*colorDartBuf++ = b;
	}
	glUnmapBufferARB(GL_ARRAY_BUFFER);
}
예제 #25
0
	void* OpenGLTexture::lock(TextureUsage _access)
	{
		MYGUI_PLATFORM_ASSERT(mTextureID, "Texture is not created");

		if (_access == TextureUsage::Read)
		{
			glBindTexture(GL_TEXTURE_2D, mTextureID);

			mBuffer = new unsigned char[mDataSize];
			glGetTexImage(GL_TEXTURE_2D, 0, mPixelFormat, GL_UNSIGNED_BYTE, mBuffer);

			mLock = false;

			return mBuffer;
		}

		// bind the texture
		glBindTexture(GL_TEXTURE_2D, mTextureID);
		if (!OpenGLRenderManager::getInstance().isPixelBufferObjectSupported())
		{
			//Fallback if PBO's are not supported
			mBuffer = new unsigned char[mDataSize];
		}
		else
		{
			// bind the PBO
			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, mPboID);
			
			// Note that glMapBufferARB() causes sync issue.
			// If GPU is working with this buffer, glMapBufferARB() will wait(stall)
			// until GPU to finish its job. To avoid waiting (idle), you can call
			// first glBufferDataARB() with NULL pointer before glMapBufferARB().
			// If you do that, the previous data in PBO will be discarded and
			// glMapBufferARB() returns a new allocated pointer immediately
			// even if GPU is still working with the previous data.
			glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, mDataSize, 0, mUsage);

			// map the buffer object into client's memory
			mBuffer = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, mAccess);
			if (!mBuffer)
			{
				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
				glBindTexture(GL_TEXTURE_2D, 0);
				MYGUI_PLATFORM_EXCEPT("Error texture lock");
			}
		}

		mLock = true;

		return mBuffer;
	}
예제 #26
0
void upload_image_data_to_opengl(unsigned char* raw_image_data,
                                 CameraPixelCoding coding,
				 int device_number) {
  unsigned char * gl_image_data;
  static unsigned char* show_pixels=NULL;
  GLuint textureId;
  GLubyte* ptr;

  textureId = textureId_all[device_number];

  if (use_pbo) {
#ifdef USE_GLEW
    glBindTexture(GL_TEXTURE_2D, textureId);
    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);

    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex_width, tex_height, gl_data_format, GL_UNSIGNED_BYTE, 0);
    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
    glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, PBO_stride*tex_height, 0, GL_STREAM_DRAW_ARB);
    ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
    if(ptr) {
      convert_pixels(raw_image_data, coding, PBO_stride, ptr, 1);
      glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer
    }
    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
#endif  /* ifdef USE_GLEW */
  } else {

    if (show_pixels==NULL) {
      /* allocate memory */
      show_pixels = (unsigned char *)malloc( PBO_stride*height );
      if (show_pixels==NULL) {
        fprintf(stderr,"couldn't allocate memory in %s, line %d\n",__FILE__,__LINE__);
        exit(1);
      }
    }

    gl_image_data = convert_pixels(raw_image_data, coding, PBO_stride, show_pixels, 0);

    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexSubImage2D(GL_TEXTURE_2D, /* target */
                    0, /* mipmap level */
                    0, /* x offset */
                    0, /* y offset */
                    width,
                    height,
                    gl_data_format, /* data format */
                    GL_UNSIGNED_BYTE, /* data type */
                    gl_image_data);

  }
}
예제 #27
0
// render image using OpenCL
//*****************************************************************************
void render()
{
    ciErrNum = CL_SUCCESS;

    // Transfer ownership of buffer from GL to CL

	if( g_glInterop ) 
	{
		// Acquire PBO for OpenCL writing
		glFlush();
		ciErrNum |= clEnqueueAcquireGLObjects(cqCommandQueue, 1, &pbo_cl, 0, 0, 0);
		//printf("Enqueue acquired GL objects error is %i \n",ciErrNum);
	}

	ciErrNum |= clEnqueueWriteBuffer(cqCommandQueue,d_invViewMatrix,CL_FALSE, 0,12*sizeof(float), invViewMatrix, 0, 0, 0);	
	//printf("Write buffer error is %i \n",ciErrNum);

    // execute OpenCL kernel, writing results to PBO
    size_t localSize[] = {LOCAL_SIZE_X,LOCAL_SIZE_Y};

    ciErrNum |= clSetKernelArg(ckKernel, 3, sizeof(float), &density);
    ciErrNum |= clSetKernelArg(ckKernel, 4, sizeof(float), &brightness);
    ciErrNum |= clSetKernelArg(ckKernel, 5, sizeof(float), &transferOffset);
    ciErrNum |= clSetKernelArg(ckKernel, 6, sizeof(float), &transferScale);
    ciErrNum |= clEnqueueNDRangeKernel(cqCommandQueue, ckKernel, 2, NULL, gridSize, localSize, 0, 0, 0);
	//printf("Enqueue ND range kernel error is %i \n",ciErrNum);
    ////oclCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup);
		clFinish( cqCommandQueue );

	if( g_glInterop ) 
	{
		// Transfer ownership of buffer back from CL to GL    
		ciErrNum |= clEnqueueReleaseGLObjects(cqCommandQueue, 1, &pbo_cl, 0, 0, 0);
		//printf("Release GL object error is %i \n",ciErrNum);
		////oclCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup);
		clFinish( cqCommandQueue );
	} 
	else 
	{
		// Explicit Copy 
		// map the PBO to copy data from the CL buffer via host
		glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);    

		// map the buffer object into client's memory
		GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
			GL_WRITE_ONLY_ARB);
		clEnqueueReadBuffer(cqCommandQueue, pbo_cl, CL_TRUE, 0, sizeof(unsigned int) * height * width, ptr, 0, NULL, NULL);        
		////oclCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup);
		glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); 
	}
}
예제 #28
0
    const void* mapRead() const
        {
            if( !_testInitialized( ))
                return 0;

            if( _type != GL_READ_ONLY_ARB )
            {
                _setError( ERROR_PBO_WRITE_ONLY );
                return 0;
            }

            bind();
            return glMapBufferARB( GL_PIXEL_PACK_BUFFER_ARB, _type );
        }
예제 #29
0
void *CVertexBuffer::_map(eOperation op){
    GLenum oper;
    switch (op) {
        case WRITE_ONLY:
            oper = GL_WRITE_ONLY_ARB;
            break;
        case READ_ONLY:
            oper = GL_READ_ONLY_ARB;
            break;
        case READ_WRITE:
            oper = GL_READ_WRITE_ARB;
            break;
    }
    return glMapBufferARB(GL_ARRAY_BUFFER_ARB, oper);
}
예제 #30
0
static int pixelbuffer_map_into_gpu(GLuint bindcode)
{
	void *pixels;

	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
	pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);

	/* do stuff in pixels */

	if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
		fprintf(stderr, "Could not unmap opengl PBO\n");
		return 0;
	}
	
	return 1;
}