/* MapPreviewCanvas::createImage
 * Draws the map in an image
 * TODO: Factorize code with normal draw() and showMap() functions.
 * TODO: Find a way to generate an arbitrary-sized image through
 * tiled rendering.
 *******************************************************************/
void MapPreviewCanvas::createImage(ArchiveEntry& ae, int width, int height)
{
	// Find extents of map
	mep_vertex_t m_min(999999.0, 999999.0);
	mep_vertex_t m_max(-999999.0, -999999.0);
	for (unsigned a = 0; a < verts.size(); a++)
	{
		if (verts[a].x < m_min.x)
			m_min.x = verts[a].x;
		if (verts[a].x > m_max.x)
			m_max.x = verts[a].x;
		if (verts[a].y < m_min.y)
			m_min.y = verts[a].y;
		if (verts[a].y > m_max.y)
			m_max.y = verts[a].y;
	}
	double mapwidth = m_max.x - m_min.x;
	double mapheight = m_max.y - m_min.y;

	if (width == 0) width = -5;
	if (height == 0) height = -5;
	if (width < 0)
		width = mapwidth / abs(width);
	if (height < 0)
		height = mapheight / abs(height);

	// Setup colours
	wxColour wxc;
	wxc.Set(map_image_col_background);	rgba_t col_save_background(wxc.Red(), wxc.Green(), wxc.Blue(), 255);
	wxc.Set(map_image_col_line_1s);		rgba_t col_save_line_1s(wxc.Red(), wxc.Green(), wxc.Blue(), 255);
	wxc.Set(map_image_col_line_2s);		rgba_t col_save_line_2s(wxc.Red(), wxc.Green(), wxc.Blue(), 255);
	wxc.Set(map_image_col_line_special); rgba_t col_save_line_special(wxc.Red(), wxc.Green(), wxc.Blue(), 255);
	wxc.Set(map_image_col_line_macro);	rgba_t col_save_line_macro(wxc.Red(), wxc.Green(), wxc.Blue(), 255);
	col_save_background.a = map_image_alpha_background;

	// Setup OpenGL rigmarole
	GLuint texID, fboID;
	if (GLEW_ARB_framebuffer_object)
	{
		glGenTextures(1, &texID);
		glBindTexture(GL_TEXTURE_2D, texID);
		// We don't use mipmaps, but OpenGL will refuse to attach
		// the texture to the framebuffer if they are not present
		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
		glGenFramebuffersEXT(1, &fboID);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texID, 0);
		GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	}

	glViewport(0, 0, width, height);

	// Setup the screen projection
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, width, 0, height, -1, 1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	// Clear
	glClearColor(((double)col_save_background.r)/255.f, ((double)col_save_background.g)/255.f,
	             ((double)col_save_background.b)/255.f, ((double)col_save_background.a)/255.f);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	// Translate to inside of pixel (otherwise inaccuracies can occur on certain gl implementations)
	if (OpenGL::accuracyTweak())
		glTranslatef(0.375f, 0.375f, 0);

	// Zoom/offset to show full map
	// Offset to center of map
	offset_x = m_min.x + (mapwidth * 0.5);
	offset_y = m_min.y + (mapheight * 0.5);

	// Zoom to fit whole map
	double x_scale = ((double)width) / mapwidth;
	double y_scale = ((double)height) / mapheight;
	zoom = MIN(x_scale, y_scale);
	zoom *= 0.95;

	// Translate to middle of canvas
	glTranslated(width>>1, height>>1, 0);

	// Zoom
	glScaled(zoom, zoom, 1);

	// Translate to offset
	glTranslated(-offset_x, -offset_y, 0);

	// Setup drawing
	glDisable(GL_TEXTURE_2D);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glLineWidth(map_image_thickness);
	glEnable(GL_LINE_SMOOTH);

	// Draw lines
	for (unsigned a = 0; a < lines.size(); a++)
	{
		mep_line_t line = lines[a];

		// Check ends
		if (line.v1 >= verts.size() || line.v2 >= verts.size())
			continue;

		// Get vertices
		mep_vertex_t v1 = verts[lines[a].v1];
		mep_vertex_t v2 = verts[lines[a].v2];

		// Set colour
		if (line.special)
			OpenGL::setColour(col_save_line_special);
		else if (line.macro)
			OpenGL::setColour(col_save_line_macro);
		else if (line.twosided)
			OpenGL::setColour(col_save_line_2s);
		else
			OpenGL::setColour(col_save_line_1s);

		// Draw line
		glBegin(GL_LINES);
		glVertex2d(v1.x, v1.y);
		glVertex2d(v2.x, v2.y);
		glEnd();
	}

	glLineWidth(1.0f);
	glDisable(GL_LINE_SMOOTH);

	uint8_t* ImageBuffer = new uint8_t[width * height * 4];
	glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, ImageBuffer);

	if (GLEW_ARB_framebuffer_object)
	{
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glDeleteTextures( 1, &texID );
		glDeleteFramebuffersEXT( 1, &fboID );
	}
	SImage img;
	img.setImageData(ImageBuffer, width, height, RGBA);
	img.mirror(true);
	MemChunk mc;
	SIFormat::getFormat("png")->saveImage(img, mc);
	ae.importMemChunk(mc);
}
Example #2
0
/**
 * Take a screenshot of the frame buffer
 * @param[in] x
 * @param[in] y
 * @param[in] width
 * @param[in] height
 * @param[in] filename Force to use a filename. Else NULL to autogen a filename
 * @param[in] ext Force to use an image format (tga/png/jpg). Else NULL to use value of r_screenshot_format
 */
void R_ScreenShot (int x, int y, int width, int height, const char *filename, const char *ext)
{
	char	checkName[MAX_OSPATH];
	int		type, shotNum, quality = 100;
	byte	*buffer;
	qFILE	f;
	int rowPack;

	glGetIntegerv(GL_PACK_ALIGNMENT, &rowPack);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	/* Find out what format to save in */
	if (ext == NULL)
		ext = r_screenshot_format->string;

	if (!Q_strcasecmp(ext, "png"))
		type = SSHOTTYPE_PNG;
	else if (!Q_strcasecmp(ext, "jpg"))
		type = SSHOTTYPE_JPG;
	else
		type = SSHOTTYPE_TGA_COMP;

	/* Set necessary values */
	switch (type) {
	case SSHOTTYPE_TGA_COMP:
		Com_Printf("Taking TGA screenshot...\n");
		ext = "tga";
		break;

	case SSHOTTYPE_PNG:
		Com_Printf("Taking PNG screenshot...\n");
		ext = "png";
		break;

	case SSHOTTYPE_JPG:
		if (Cmd_Argc() == 3)
			quality = atoi(Cmd_Argv(2));
		else
			quality = r_screenshot_jpeg_quality->integer;
		if (quality > 100 || quality <= 0)
			quality = 100;

		Com_Printf("Taking JPG screenshot (at %i%% quality)...\n", quality);
		ext = "jpg";
		break;
	}

	/* Find a file name to save it to */
	if (filename) {
		Com_sprintf(checkName, sizeof(checkName), "scrnshot/%s.%s", filename, ext);
	} else {
		for (shotNum = 0; shotNum < 1000; shotNum++) {
			Com_sprintf(checkName, sizeof(checkName), "scrnshot/ufo%i%i.%s", shotNum / 10, shotNum % 10, ext);
			if (FS_CheckFile("%s", checkName) == -1)
				break;
		}
		if (shotNum == 1000) {
			Com_Printf("R_ScreenShot_f: screenshot limit (of 1000) exceeded!\n");
			return;
		}
	}

	/* Open it */
	FS_OpenFile(checkName, &f, FILE_WRITE);
	if (!f.f) {
		Com_Printf("R_ScreenShot_f: Couldn't create file: %s\n", checkName);
		return;
	}

	/* Allocate room for a copy of the framebuffer */
	buffer = (byte *)Mem_PoolAlloc(width * height * 3, vid_imagePool, 0);
	if (!buffer) {
		Com_Printf("R_ScreenShot_f: Could not allocate %i bytes for screenshot!\n", width * height * 3);
		FS_CloseFile(&f);
		return;
	}

	/* Read the framebuffer into our storage */
	glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
	R_CheckError();

	/* Write */
	switch (type) {
	case SSHOTTYPE_TGA_COMP:
		R_WriteCompressedTGA(&f, buffer, width, height);
		break;

	case SSHOTTYPE_PNG:
		R_WritePNG(&f, buffer, width, height);
		break;

	case SSHOTTYPE_JPG:
		R_WriteJPG(&f, buffer, width, height, quality);
		break;
	}

	/* Finish */
	FS_CloseFile(&f);
	Mem_Free(buffer);

	Com_Printf("Wrote %s to %s\n", checkName, FS_Gamedir());
	glPixelStorei(GL_PACK_ALIGNMENT, rowPack);
}
Example #3
0
void SceneObjectBlockGame::postRender() {
	// Get data from effect buffer
	glReadBuffer(GL_FRONT);

	glReadPixels(0, 0, getRenderScene()->_gBuffer.getWidth(), getRenderScene()->_gBuffer.getHeight(), GL_RGB, GL_UNSIGNED_BYTE, _capBytes->data());
}
bool ofxFastFboReader::readToFloatPixels(ofFbo &fbo, ofFloatPixelsRef pix, ofImageType type)
{
	genPBOs();
	
	int channels;
	int glType;
	
	if (type == OF_IMAGE_COLOR)
	{
		channels = 3;
		glType = GL_RGB;
	}
	else if (type == OF_IMAGE_COLOR_ALPHA)
	{
		channels = 4;
		glType = GL_RGBA;
	}
	else if (type == OF_IMAGE_GRAYSCALE)
	{
		channels = 1;
		glType = GL_LUMINANCE;
	}
	else
	{
		return false;
	}
	
	const int width = fbo.getWidth();
	const int height = fbo.getHeight();
	
	if (async)
	{
		index = (index + 1) % num_buffers;
		nextIndex = (index + 1) % num_buffers;
	}
	else
	{
		index = nextIndex = 0;
	}
	
	size_t nb = width * height * channels * sizeof(float); // LS: don't just deal with 8-bit color channels..
	
	if (nb != num_bytes)
	{
		num_bytes = nb;
		setupPBOs(num_bytes);
	}
	
	glReadBuffer(GL_FRONT);
	
	fbo.bind();
	
	glBindBuffer(GL_PIXEL_PACK_BUFFER, pboIds[index]);
	glReadPixels(0, 0, width, height, glType, GL_FLOAT, NULL);
	
	glBindBuffer(GL_PIXEL_PACK_BUFFER, pboIds[nextIndex]);
	float* mem = (float*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
	
	if (mem)
	{
		pix.setFromPixels(mem, width, height, channels);
		//pix.setFromAlignedPixels(mem, width, height, channels, width*channels); // stride = nr of elements (float, char, etc) in a row, including padding for alignment. we assume no padding..
		glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
	}
	
	glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
	
	fbo.unbind();
	
	return mem != NULL;
}
Example #5
0
///////////////////////////////////////////////////////////////////////////////
// Render a frame. The owning framework is responsible for buffer swaps,
// flushes, etc.
void RenderScene(void)
{
	static CStopWatch animationTimer;
	static float totalTime = 6; // To go back and forth
	static float halfTotalTime = totalTime/2;
	float seconds = animationTimer.GetElapsedSeconds() * speedFactor;
	float xPos = 0;

	// Calculate the next postion of the moving object
	// First perform a mod-like operation on the time as a float
	while(seconds > totalTime)
		seconds -= totalTime;

	// Move object position, if it's gone half way across
	// start bringing it back
	if(seconds < halfTotalTime)
		xPos = seconds -halfTotalTime*0.5f;
	else
		xPos = totalTime - seconds -halfTotalTime*0.5f;

	// First draw world to screen
	modelViewMatrix.PushMatrix();	
		M3DMatrix44f mCamera;
		cameraFrame.GetCameraMatrix(mCamera);
		modelViewMatrix.MultMatrix(mCamera);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textures[0]); // Marble
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE, transformPipeline.GetModelViewProjectionMatrix(), vWhite, 0);

		floorBatch.Draw();
		DrawWorld(0.0f, xPos);
	modelViewMatrix.PopMatrix();
	
	if(bUsePBOPath)
	{
		// First bind the PBO as the pack buffer, then read the pixels directly to the PBO
		glBindBuffer(GL_PIXEL_PACK_BUFFER, pixBuffObjs[0]);
		glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, NULL);
		glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

		// Next bind the PBO as the unpack buffer, then push the pixels straight into the texture
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixBuffObjs[0]);
        
        // Setup texture unit for new blur, this gets imcremented every frame 
		glActiveTexture(GL_TEXTURE0+GetBlurTarget0() ); 
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
	}
	else
	{
		// Grab the screen pixels and copy into local memory
		glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
		
		// Push pixels from client memory into texture
        // Setup texture unit for new blur, this gets imcremented every frame
		glActiveTexture(GL_TEXTURE0+GetBlurTarget0() );
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
	}

	// Draw full screen quad with blur shader and all blur textures
	projectionMatrix.PushMatrix(); 
		projectionMatrix.LoadIdentity();
		projectionMatrix.LoadMatrix(orthoMatrix);
		modelViewMatrix.PushMatrix();	
			modelViewMatrix.LoadIdentity();
			glDisable(GL_DEPTH_TEST); 
			SetupBlurProg();
			screenQuad.Draw();
			glEnable(GL_DEPTH_TEST); 
		modelViewMatrix.PopMatrix(); 
	projectionMatrix.PopMatrix();

	// Move to the next blur texture for the next frame
	AdvanceBlurTaget();
    
    // Do the buffer Swap
    glutSwapBuffers();
        
    // Do it again
    glutPostRedisplay();

    UpdateFrameCount();
}
Example #6
0
void Camera::zBufferLookAt( int pixel_x, int pixel_y ) {
    
    int W = _viewport_x2 - _viewport_x1 + 1;
    int H = _viewport_y2 - _viewport_y1 + 1;
    
    GLfloat * zbuffer = new GLfloat[ W * H ];
    
    // FIXME: we want to fetch the z-buffer of the most
    // recently rendered image.  Unfortunately, this code
    // probably grabs the back z-buffer, rather than the
    // front z-buffer, which (if I'm not mistaken) is what we want.
    // FIXME: instead of grabbing the whole buffer, we should just
    // grab a small region around the pixel of interest.
    // Grabbing the whole buffer is very slow on
    // some Iris machines (e.g. Indigo2).
    glReadPixels(
                 _viewport_x1,
                 _window_height_in_pixels - 1 - _viewport_y2,
                 W, H,
                 GL_DEPTH_COMPONENT, GL_FLOAT, zbuffer
                 );
    
    // // Print contents of z-buffer (for debugging only).
    // for ( int b = H-1; b >= 0; --b ) {
    //    for ( int a = 0; a < W; ++a ) {
    //       printf("%c",zbuffer[ b*W + a ]==1?'.':'X');
    //    }
    //    puts("");
    // }
    
    // Keep in mind that zbuffer[0] corresponds to the lower-left
    // pixel of the viewport, *not* the upper-left pixel.
    
    // Transform the pixel passed in so that it is
    // in the z-buffer's coordinate system.
    pixel_x -= _viewport_x1;
    pixel_y = H - 1 - (pixel_y - _viewport_y1);
    
    // Assume, as is typically the case, that the z-buffer was
    // cleared with a value of 1.0f (the maximum z value).
    // Also assume that any pixels containing a value of 1.0f
    // have this value because no rendered geometry covered them.
    // Now, search outward from the pixel passed in, in larger
    // and larger rectangles, for a pixel with a z value
    // less than 1.0f.
    
    ASSERT( 0 <= pixel_x && pixel_x < W && 0 <= pixel_y && pixel_y < H );
    
    // the search rectangle
    int x1 = pixel_x, y1 = pixel_y;
    int x2 = x1, y2 = y1;
    
    int x,y,x0=W/2,y0=H/2;
    int min, max;
    float z = 1;
    while ( z == 1 ) {
        // top edge of rectangle
        if ( y1 >= 0 ) {
            y = y1;
            min = x1 < 0 ? 0 : x1;
            max = x2 >= W ? W-1 : x2;
            for ( x = min; x <= max; ++x )
                if ( zbuffer[ y*W + x ] < z ) {
                    z = zbuffer[ y*W + x ];
                    x0 = x;
                    y0 = y;
                }
        }
        // bottom edge of rectangle
        if ( y2 < H ) {
            y = y2;
            min = x1 < 0 ? 0 : x1;
            max = x2 >= W ? W-1 : x2;
            for ( x = min; x <= max; ++x )
                if ( zbuffer[ y*W + x ] < z ) {
                    z = zbuffer[ y*W + x ];
                    x0 = x;
                    y0 = y;
                }
        }
        // left edge of rectangle
        if ( x1 >= 0 ) {
            x = x1;
            min = y1 < 0 ? 0 : y1;
            max = y2 >= H ? H-1 : y2;
            for ( y = min; y <= max; ++y )
                if ( zbuffer[ y*W + x ] < z ) {
                    z = zbuffer[ y*W + x ];
                    x0 = x;
                    y0 = y;
                }
        }
        // right edge of rectangle
        if ( x2 < W ) {
            x = x2;
            min = y1 < 0 ? 0 : y1;
            max = y2 >= H ? H-1 : y2;
            for ( y = min; y <= max; ++y )
                if ( zbuffer[ y*W + x ] < z ) {
                    z = zbuffer[ y*W + x ];
                    x0 = x;
                    y0 = y;
                }
        }
        
        // grow the rectangle
        --x1;  --y1;
        ++x2;  ++y2;
        
        // is there nothing left to search ?
        if ( y1 < 0 && y2 >= H && x1 < 0 && x2 >= W )
            break;
    }
    
    if ( z < 1 ) {
        // compute point in clipping space
#ifdef OPENGL_CENTRE_BASED
        Point3 pc( 2*x0/(float)(W-1)-1, 2*y0/(float)(H-1)-1, 2*z-1 );
#else
        // The +0.5f here is to convert from centre-based coordinates
        // to edge-based coordinates.
        Point3 pc( 2*(x0+0.5f)/(float)W-1, 2*(y0+0.5f)/(float)H-1, 2*z-1 );
#endif
        
        // compute inverse view transform
        Matrix M;
        M.setToLookAt( _position, _target, _up, true );
        
        // compute inverse perspective transform
        Matrix M2;
        M2.setToFrustum(
                        - 0.5 * _viewport_width,  0.5 * _viewport_width,    // left, right
                        - 0.5 * _viewport_height, 0.5 * _viewport_height,   // bottom, top
                        _near_plane, _far_plane,
                        true
                        );
        
        // compute inverse of light transform
        M = M * M2;
        
        // compute point in world space
        Point3 t0 = M * pc;
        Point3 t( t0.x()/t0.w(), t0.y()/t0.w(), t0.z()/t0.w() );
        
        lookAt( t );
    }
    
    delete [] zbuffer;
    zbuffer = 0;
}
Example #7
0
File: demo.c Project: cjxgm/clabs
void render(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45,1,0.01,100);
	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();

	glRotatef(pitch,1,0,0); // Set our position and orientition.
	glRotatef(dir,0,1,0);
	glTranslatef(-x,0,-y);

	glLightfv(GL_LIGHT1,GL_POSITION,sun); // Set up the light position. (This multiplys the position by the model matrix so you need to call it every frame after the view is setup.)

	glColor3f(0,1,0); // Make the geometry green.

#include "scene.h" // I found an easy way to use the output from ASE2GL: Put it in a header and include it.

	GLdouble modelMatrix[16]; // The model matrix.
	GLdouble projMatrix[16];  // The projection matrix.
	GLdouble sx,sy,sz;        // Where on the screen the light is.
	int x,y;                  // Used for going through the depth buffer.
	float brightness=0;       // How bright the light is.
	float depth;              // The depth in the framebuffer.
	GLint viewport[4];        // The viewport.

	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); // Load the matricies and viewport.
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
	glGetIntegerv(GL_VIEWPORT, viewport);

	gluProject(sun[0],sun[1],sun[2],modelMatrix,projMatrix,viewport,&sx,&sy,&sz); // Find out where the light is on the screen.


	for(x=-4;x<=4;x++) // Go through some of the points near the light.
		for(y=-4;y<=4;y++)
		{
			if(viewport[2]/300.0*x+sx < viewport[2] && viewport[2]/300.0*x+sx >= 0 &&
					viewport[3]/300.0*y+sy < viewport[3] && viewport[3]/300.0*y+sy >= 0 ) // If the point is on the screen
			{
				glReadPixels((int)(viewport[2]/300.0*x+sx),(int)(viewport[3]/300.0*y+sy),1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&depth); // Read the depth from the depth buffer.
				if(depth >= sz) brightness += 1.0/81.0; // If the light is infront of what ever was in that spot, increase the brightness.
			}
		}


	if(sx < viewport[2] && sx >= 0 &&
			sy < viewport[3] && sy >= 0 ) // If the light is on the screen
	{
		glReadPixels((int)(sx),(int)(sy),1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&depth);
		if(depth < sz) // but it is behind something.
			brightness = 0; // The light can't be seen.
	}
	else // If the light isn't on the screen
		brightness = 0; // The light can't be seen.


	sx = sx/(float)viewport[2]*2.0-1.0; // Now that we know the brightness, convert
	sy = sy/(float)viewport[2]*2.0-1.0; // The position to a nember between (-1,-1) and (1,1)

	brightness = (1.2-sqrt(sx*sx+sy*sy))*brightness*0.75; // And adjust the brightness so it is brighter at the centre of the screen.

	glPushMatrix();
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity(); // Forget about the view and projection. We will be drawing in 2D for the flares.
	glDisable(GL_DEPTH_TEST); // Disable depth testing, face culling, and lighting.
	glDisable(GL_CULL_FACE);  // You don't need those in 2D.
	glDisable(GL_LIGHTING);

	glBegin(GL_TRIANGLE_FAN); // Make a steak across the screen where the light is.
	glColor4f(0.9,1.0,0.9,brightness*0.5);
	glVertex2f(sx,sy);
	glColor4f(1.0,1.0,1.0,0);
	glVertex2f(sx+2.5*brightness,sy);
	glVertex2f(sx,sy+0.1*brightness);
	glVertex2f(sx-2.5*brightness,sy);
	glVertex2f(sx,sy-0.1*brightness);
	glVertex2f(sx+2.5*brightness,sy);
	glEnd();

	glColor4f(1,1,1,brightness); // Brighten the screen.
	glBegin(GL_QUADS);                
	glTexCoord2f(0,0);
	glVertex2f(sx-2,sy-2);
	glTexCoord2f(1,0);
	glVertex2f(sx+2,sy-2);
	glTexCoord2f(1,1);
	glVertex2f(sx+2,sy+2);
	glTexCoord2f(0,1);
	glVertex2f(sx-2,sy+2);
	glEnd();

	float loop;
	bool big = true;

	glBegin(GL_TRIANGLE_FAN);
	glColor4f(1.0,1.0,1.0,brightness*0.5);
	glVertex2f(sx,sy);
	glColor4f(1.0,1.0,0.5,0);
	for(loop=0.0;loop<6.283185307;loop+=6.283185307/64.0) // Make a 32 point star (64/2=32). Feel free to change that if you want.
	{
		glVertex2f(sx+sin(loop)*(big?2.0*brightness:1.0*brightness),sy+cos(loop)*(big?2.0*brightness:1.0*brightness));
		big = !big; // Make the next part of the star the opposite of this part.
	}                    
	glEnd();

	MAKE_FLARE( 0.7,0.2,1.0,1.0,1.0); // Make the flares. Add or Remove some if you like. The MAKE_FLARE macro will only work right here.
	MAKE_FLARE( 0.6,0.3,1.0,0.6,0.6); // It looks better with a chaotic size. I don't know why, though.
	MAKE_FLARE( 0.4,0.4,1.0,1.0,1.0); // Have mine coloured to make a rainbow.
	MAKE_FLARE( 0.3,0.6,0.8,0.8,0.6);
	MAKE_FLARE( 0.2,0.5,1.0,1.0,1.0);
	MAKE_FLARE(-0.1,0.4,0.6,1.0,0.6);
	MAKE_FLARE(-0.2,0.3,1.0,1.0,1.0);
	MAKE_FLARE(-0.4,0.2,0.6,0.8,0.8);
	MAKE_FLARE(-0.6,0.4,1.0,1.0,1.0);
	MAKE_FLARE(-0.7,0.5,0.6,0.6,1.0);
	MAKE_FLARE(-0.8,0.6,1.0,1.0,1.0);
	MAKE_FLARE(-0.9,0.5,0.8,0.6,0.8);
	MAKE_FLARE(-1.2,0.3,1.0,1.0,1.0);
	glEnable(GL_LIGHTING); // Turn the stuff on that I turned off.
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);
	glPopMatrix(); 
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix(); // Get the old matricies back.
	SWAP;
}    
Example #8
0
/*------------------------------------------------------------*/
void
gifi_finish_output (void)
{
    int row, col, value, r, g, b, error, right, leftbelow, below;
    unsigned char *buffer, *buf;
    int *rcurr, *gcurr, *bcurr, *rnext, *gnext, *bnext, *swap;

    image_render();

    buffer = malloc (output_width * 3 * sizeof (unsigned char));
    rcurr = malloc ((output_width + 1) * sizeof (int));
    gcurr = malloc ((output_width + 1) * sizeof (int));
    bcurr = malloc ((output_width + 1) * sizeof (int));
    rnext = calloc (output_width + 1, sizeof (int));
    gnext = calloc (output_width + 1, sizeof (int));
    bnext = calloc (output_width + 1, sizeof (int));

    for (row = 0; row < output_height; row++) {

        swap = rnext;
        rnext = rcurr;
        rcurr = swap;
        swap = gnext;
        gnext = gcurr;
        gcurr = swap;
        swap = bnext;
        bnext = bcurr;
        bcurr = swap;
        for (col = 0; col < output_width; col++) {
            rnext[col] = 0;
            gnext[col] = 0;
            bnext[col] = 0;
        }

        glReadPixels (0, output_height - row - 1, output_width, 1,
                      GL_RGB, GL_UNSIGNED_BYTE, buffer);
        buf = buffer;
        for (col = 0; col < output_width; col++) {
            rcurr[col] += *buf++;
            gcurr[col] += *buf++;
            bcurr[col] += *buf++;
        }

        for (col = 0; col < output_width; col++) { /* error diffusion */

            value = rcurr[col];
            for (r = 0; 51 * (r + 1) - 26 < value; r++);
            error = value - r * 51;
            right = (7 * error) / 16;
            leftbelow = (3 * error) / 16;
            below = (5 * error) / 16;
            rcurr[col+1] += right;
            if (col > 0) rnext[col-1] += leftbelow;
            rnext[col] += below;
            rnext[col+1] = error - right - leftbelow - below;

            value = gcurr[col];
            for (g = 0; 51 * (g + 1) - 26 < value; g++);
            error = value - g * 51;
            right = (7 * error) / 16;
            leftbelow = (3 * error) / 16;
            below = (5 * error) / 16;
            gcurr[col+1] += right;
            if (col > 0) gnext[col-1] += leftbelow;
            gnext[col] += below;
            gnext[col+1] = error - right - leftbelow - below;

            value = bcurr[col];
            for (b = 0; 51 * (b + 1) - 26 < value; b++);
            error = value - b * 51;
            right = (7 * error) / 16;
            leftbelow = (3 * error) / 16;
            below = (5 * error) / 16;
            bcurr[col+1] += right;
            if (col > 0) bnext[col-1] += leftbelow;
            bnext[col] += below;
            bnext[col+1] = error - right - leftbelow - below;

            gdImageSetPixel (image, col, row, ((r * 6) + g) * 6 + b);
        }
    }

    free (rnext);
    free (gnext);
    free (bnext);
    free (rcurr);
    free (gcurr);
    free (bcurr);
    free (buffer);

    gdImageGif (image, outfile);
    gdImageDestroy (image);

    image_close();
}
Example #9
0
Image Texture::copyToImage() const
{
    // Easy case: empty texture
    if (!m_texture)
        return Image();

    TransientContextLock lock;

    // Make sure that the current texture binding will be preserved
    priv::TextureSaver save;

    // Create an array of pixels
    std::vector<Uint8> pixels(m_size.x * m_size.y * 4);

#ifdef SFML_OPENGL_ES

    // OpenGL ES doesn't have the glGetTexImage function, the only way to read
    // from a texture is to bind it to a FBO and use glReadPixels
    GLuint frameBuffer = 0;
    glCheck(GLEXT_glGenFramebuffers(1, &frameBuffer));
    if (frameBuffer)
    {
        GLint previousFrameBuffer;
        glCheck(glGetIntegerv(GLEXT_GL_FRAMEBUFFER_BINDING, &previousFrameBuffer));

        glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, frameBuffer));
        glCheck(GLEXT_glFramebufferTexture2D(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0));
        glCheck(glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]));
        glCheck(GLEXT_glDeleteFramebuffers(1, &frameBuffer));

        glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, previousFrameBuffer));
    }

#else

    if ((m_size == m_actualSize) && !m_pixelsFlipped)
    {
        // Texture is not padded nor flipped, we can use a direct copy
        glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
        glCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]));
    }
    else
    {
        // Texture is either padded or flipped, we have to use a slower algorithm

        // All the pixels will first be copied to a temporary array
        std::vector<Uint8> allPixels(m_actualSize.x * m_actualSize.y * 4);
        glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
        glCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &allPixels[0]));

        // Then we copy the useful pixels from the temporary array to the final one
        const Uint8* src = &allPixels[0];
        Uint8* dst = &pixels[0];
        int srcPitch = m_actualSize.x * 4;
        int dstPitch = m_size.x * 4;

        // Handle the case where source pixels are flipped vertically
        if (m_pixelsFlipped)
        {
            src += srcPitch * (m_size.y - 1);
            srcPitch = -srcPitch;
        }

        for (unsigned int i = 0; i < m_size.y; ++i)
        {
            std::memcpy(dst, src, dstPitch);
            src += srcPitch;
            dst += dstPitch;
        }
    }

#endif // SFML_OPENGL_ES

    // Create the image
    Image image;
    image.create(m_size.x, m_size.y, &pixels[0]);

    return image;
}
Example #10
0
// capture image from viewport
void ImageViewport::calcViewport (unsigned int texId, double ts, unsigned int format)
{
	// if scale was changed
	if (m_scaleChange)
		// reset image
		init(m_capSize[0], m_capSize[1]);
	// if texture wasn't initialized
	if (!m_texInit && texId != 0) {
		// initialize it
		loadTexture(texId, m_image, m_size, false, m_internalFormat);
		m_texInit = true;
	}
	// if texture can be directly created
	if (texId != 0 && m_pyfilter == NULL && m_size[0] == m_capSize[0] &&
	    m_size[1] == m_capSize[1] && !m_flip && !m_zbuff && !m_depth)
	{
		// just copy current viewport to texture
		glBindTexture(GL_TEXTURE_2D, texId);
		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1]);
		glBindTexture(GL_TEXTURE_2D, 0);
		// image is not available
		m_avail = false;
	}
	// otherwise copy viewport to buffer, if image is not available
	else if (!m_avail) {
		if (m_zbuff) {
			// Use read pixels with the depth buffer
			// *** misusing m_viewportImage here, but since it has the correct size
			//     (4 bytes per pixel = size of float) and we just need it to apply
			//     the filter, it's ok
			glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
			        GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage);
			// filter loaded data
			FilterZZZA filt;
			filterImage(filt, (float *)m_viewportImage, m_capSize);
		}
		else {

			if (m_depth) {
				// Use read pixels with the depth buffer
				// See warning above about m_viewportImage.
				glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
				        GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage);
				// filter loaded data
				FilterDEPTH filt;
				filterImage(filt, (float *)m_viewportImage, m_capSize);
			}
			else {

				// get frame buffer data
				if (m_alpha) {
					// as we are reading the pixel in the native format, we can read directly in the image buffer
					// if we are sure that no processing is needed on the image
					if (m_size[0] == m_capSize[0] &&
					    m_size[1] == m_capSize[1] &&
					    !m_flip &&
					    !m_pyfilter)
					{
						glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], format,
						             GL_UNSIGNED_BYTE, m_image);
						m_avail = true;
					}
					else if (!m_pyfilter) {
						glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], format,
						             GL_UNSIGNED_BYTE, m_viewportImage);
						FilterRGBA32 filt;
						filterImage(filt, m_viewportImage, m_capSize);
					}
					else {
						glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA,
						             GL_UNSIGNED_BYTE, m_viewportImage);
						FilterRGBA32 filt;
						filterImage(filt, m_viewportImage, m_capSize);
						if (format == GL_BGRA) {
							// in place byte swapping
							swapImageBR();
						}
					}
				}
				else {
					glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGB,
					        GL_UNSIGNED_BYTE, m_viewportImage);
					// filter loaded data
					FilterRGB24 filt;
					filterImage(filt, m_viewportImage, m_capSize);
					if (format == GL_BGRA) {
						// in place byte swapping
						swapImageBR();
					}
				}
			}
		}
	}
}
Example #11
0
void RotoRegion::calculateMask()
{

    int numPoints = 0, d;
    PathV::const_iterator c;
    for (c = _rotoPaths.begin(); c != _rotoPaths.end(); ++c)
    {
        d = (*c)->_bez->getDiscreteCount();
        assert(d > 0);
        numPoints += d;
    }

    GLdouble *v = new GLdouble[numPoints * 3];
    Vec2f loc;
    Vec2f endPt;
    int gi, l;
    float d0, d1;
    std::vector<short>::const_iterator c2 = _sides.begin();
    for (l = 0, gi = 0, c = _rotoPaths.begin(); c != _rotoPaths.end();
            ++c, ++c2, ++l)
    {

        d0 = (*c)->_bez->distanceToEnd2(endPt, 0);
        d1 = (*c)->_bez->distanceToEnd2(endPt, 1);

        if ((l != 0 && d0 < d1) || (l == 0 && *c2 == RR_RIGHT))
        {
            for (int i = 0; i < (*c)->_bez->getDiscreteCount(); ++i, gi += 3)
            {
                loc = (*c)->_bez->getDiscreteLoc(i);
                v[gi] = loc.x();
                v[gi + 1] = loc.y();
                v[gi + 2] = 0;
                printf("Right: %f %f\n", loc.x(), loc.y());
                if ((*c)->_bez->getDiscreteCount() - 1 == i)
                    endPt = loc;
            }
        }
        else
        {
            for (int i = (*c)->_bez->getDiscreteCount() - 1; i >= 0; --i, gi +=
                    3)
            {
                loc = (*c)->_bez->getDiscreteLoc(i);
                v[gi] = loc.x();
                v[gi + 1] = loc.y();
                v[gi + 2] = 0;
                printf("Left: %f %f\n", loc.x(), loc.y());
                if (i == 0)
                    endPt = loc;
            }
        }

    }

    // render tesselated version, make it render into stencil buffer but fail depth test
    // then, read stencil buffer into mask
    assert(glGetError() == GL_NO_ERROR);
    glEnable (GL_STENCIL_TEST);
    glEnable (GL_DEPTH_TEST);
    glClear(GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glStencilFunc(GL_ALWAYS, 1, 0x1);
    glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
    glDepthFunc (GL_NEVER);
    assert(glGetError() == GL_NO_ERROR);

    glNewList(_listNum, GL_COMPILE_AND_EXECUTE);

    GLUtesselator* tobj = gluNewTess();
    gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid (*)()) &glVertex3dv);gluTessCallback
    (tobj, GLU_TESS_BEGIN, (GLvoid (*)()) &glBegin);gluTessCallback
    (tobj, GLU_TESS_END, (GLvoid (*)()) &glEnd);gluTessCallback
    (tobj, GLU_TESS_ERROR, (GLvoid (*)()) &rrfuck);gluTessCallback
    (tobj, GLU_TESS_COMBINE, (GLvoid (*)()) &rrfuckCombine);

gluTessBeginPolygon	(tobj, NULL);
    gluTessBeginContour(tobj);

    int i;
    for (i = 0; i < numPoints; i++)
        gluTessVertex(tobj, v + i * 3, v + i * 3);

    gluTessEndContour(tobj);
    gluTessEndPolygon(tobj);
    gluDeleteTess(tobj);

    glEndList();
    assert(glGetError() == GL_NO_ERROR);
    delete[] v;

    glReadPixels(0, 0, _w, _h, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, _mask);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // flip the stencil upside down
    int j = 0, bj = _h - 1;
    while (j < bj)
    {
        for (i = 0; i < _w; ++i)
            std::swap(_mask[j * _w + i], _mask[bj * _w + i]);
        ++j;
        --bj;
    }

    /*
     QImage im (_w, _h, 32);
     int index=0;
     for (j=0; j<_h; ++j)
     for (i=0; i<_w; ++i, ++index)
     im.setPixel(i, j,qRgb(_mask[index]*255,0,0));
     im.save("out.png", "PNG");
     */
}
Example #12
0
// if psFilename == NULL, takes a memory screenshot in DIB format (for copying to clipboard)
//
bool ScreenShot(LPCSTR psFilename,			// else NULL = take memory snapshot (for clipboard)
				LPCSTR psCopyrightMessage,	// /* = NULL */
				int iWidth,					// /* = <screenwidth>  */
				int iHeight					// /* = <screenheight> */
				)
{
	bool bReturn = false;

	int iOldPack;	
	glGetIntegerv(GL_PACK_ALIGNMENT,&iOldPack);
	glPixelStorei(GL_PACK_ALIGNMENT,1);
	
	void *pvGLPixels = malloc (iWidth * iHeight * 3);	// 3 = R,G,B

	if (pvGLPixels)
	{
		if (psCopyrightMessage)
		{
			bool bOldInhibit = gbTextInhibit;
			gbTextInhibit = false;
			Text_DisplayFlat(psCopyrightMessage, 0, (iHeight-TEXT_DEPTH)-1,255,255,255);	// y-1 = aesthetic only
			gbTextInhibit = bOldInhibit;
		}

		glReadPixels(	0,					// x
						0,					// y (from bottom left)
						iWidth,				// width
						iHeight,			// height
						GL_RGB,				// format
						GL_UNSIGNED_BYTE,	// type
						pvGLPixels			// buffer ptr 			
						);

		// save area is valid size...
		//
		if (BMP_Open(psFilename, iWidth, iHeight))
		{
			for (int y=0; y<iHeight; y++)				
			{
				LPGLRGBBYTES 
				lpGLRGBBytes = (LPGLRGBBYTES) pvGLPixels;
				lpGLRGBBytes+= y * iWidth;

				for (int x=0; x<iWidth; x++, lpGLRGBBytes++)
				{
					BMP_WritePixel(lpGLRGBBytes->r,lpGLRGBBytes->g,lpGLRGBBytes->b);
				}

				BMP_WriteLinePadding(iWidth);	// arg is # pixels per row	
			}

			BMP_Close(psFilename,false);	// false = bFlipFinal			

			bReturn = true;
		}

		free(pvGLPixels);
		pvGLPixels = NULL;	// yeah...yeah
	}	

	glPixelStorei(GL_PACK_ALIGNMENT,iOldPack);

	return bReturn;
}
Example #13
0
void GLWidget::paintGL()
{
	if (data.currentFile != data.nextFile) {
		if (data.nextFile == -1)
			loadShaders(data.filePath);
		else
			loadShaders(fileList[data.nextFile]);
		data.currentFile = data.nextFile;
		data.zoom = 0;
		data.moveX = 0;
		data.moveY = 0;
		data.pause = false;
		updateTitle();
	}
	double posX = (data.moveX + 1.) * float(DIM / 2);
	double posY = (data.moveY - 1.) * float(DIM / 2) * -1.;
	glUniform1ui(data.loc.dim, DIM);
	glUniform1f(data.loc.zoom, data.zoom);
	glUniform2d(data.loc.position, posX, posY);
	glVertexAttribPointer(data.loc.vertex, 2, GL_FLOAT, GL_FALSE, 0, data.vertex.constData());

	if (data.loc.animation != -1 && !data.pause) {
		glUniform1f((float)data.loc.animation,
			    (double)QTime::currentTime().msecsSinceStartOfDay() / 1000.);
		update();
	}

	render();
	if (!data.saving)
		return;
	data.saving = false;

	QImage *img = saveDialog->img;
	QImage imgRen(data.save.blockSize, QImage::Format_RGB888);
	if (img == 0) {
		saveDialog->failed(tr("img allocation failed"));
		return;
	}
	if (img->isNull()) {
		saveDialog->failed(tr("img is null"));
		return;
	}
	if (imgRen.isNull()) {
		saveDialog->failed(tr("imgRen is null"));
		return;
	}

	QOpenGLFramebufferObject fbo(data.save.blockSize);
	fbo.bind();
	glViewport(0, 0, data.save.blockSize.width(), data.save.blockSize.height());
	QPoint pos;
	int w = data.save.blockSize.width() * data.save.blockCount.width();
	int h = data.save.blockSize.height() * data.save.blockCount.height();
	float asp = (float)h / (float)w;
render:
	// Select region
	data.projection.setToIdentity();
	float left = float(2 * pos.x() - data.save.blockCount.width()) / data.save.blockCount.width();
	float top = float(2 * pos.y() - data.save.blockCount.height()) / data.save.blockCount.height();
	data.projection.ortho(left, left + 2. / data.save.blockCount.width(),
			      asp * top, asp * (top + 2. / data.save.blockCount.height()), -1., 1.);
	render();

	QPoint imgPos(pos.x() * data.save.blockSize.width(), pos.y() * data.save.blockSize.height());
	glReadPixels(0, 0, imgRen.width(), imgRen.height(), GL_RGB, GL_UNSIGNED_BYTE, imgRen.bits());
	unsigned char *imgPtr = img->scanLine(img->height() - imgPos.y() - 1) + imgPos.x() * 3;
	for (int i = 0; i < imgRen.height(); i++) {
		memcpy(imgPtr, imgRen.constScanLine(i), imgRen.bytesPerLine());
		imgPtr -= img->bytesPerLine();
	}

	if (pos.x() != data.save.blockCount.width() - 1)
		pos.setX(pos.x() + 1);
	else if (pos.y() != data.save.blockCount.height() - 1) {
		pos.setX(0);
		pos.setY(pos.y() + 1);
	} else {
		fbo.release();
		resizeGL(width(), height());
		saveDialog->done();
		return;
	}
	goto render;
}
Example #14
0
static bool
test_z_gradient(void)
{
	const GLfloat epsilon = 2.0 / piglit_width;
	GLfloat *buf, *row;
	bool pass = true;
	int pos, i;

	/* draw full-window quad with z increasing left to right */
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	draw_z_gradient(-1.0, 1.0);
	glDisable(GL_DEPTH_TEST);

	buf = (GLfloat *) malloc(piglit_width * piglit_height * sizeof(GLfloat));

	/* read whole buffer */
	glReadPixels(0, 0, piglit_width, piglit_height,
		     GL_DEPTH_COMPONENT, GL_FLOAT, buf);

	/* examine a horizontal row at mid-Y */
	row = buf + piglit_width * piglit_height / 2;

	pos = 0;
	if (fabs(row[pos] - 0.0) > epsilon) {
		printf("Left-most Z value should be close to 0.0, found %f\n",
		       row[pos]);
		pass = false;
	}

	pos = piglit_width / 2;
	if (fabs(row[pos] - 0.5) > epsilon) {
		printf("Middle Z value should be close to 0.5, found %f\n",
		       row[pos]);
		pass = false;
	}

	pos = piglit_width - 1;
	if (fabs(row[pos] - 1.0) > epsilon) {
		printf("Left-most Z value should be close to 1.0, found %f\n",
		       row[pos]);
		pass = false;
	}

	/* check for monotonicity */
	for (i = 1; i < piglit_width; i++) {
		if (row[i - 1] > row[i]) {
			printf("Z values aren't increasing from left to right. row[%d]=%f > row[%d]=%f\n",
			       i-1, row[i-1], i, row[i]);
			pass = false;
			break;
		}
	}

	if (!piglit_automatic) {
		display_depth(buf);
		piglit_present_results();
	}

	free(buf);

	return pass;
}
Example #15
0
static GLboolean
test_mipmap_copypixels(GLenum srcIntFormat, GLenum dstIntFormat,
                       GLboolean doPixelTransfer, GLboolean useReadDrawPix)
{
   GLuint srcTex, dstTex;
   GLuint fboSrc, fboDst;
   GLuint level, size;
   GLboolean pass = GL_TRUE;
   GLenum status;

   if (doPixelTransfer) {
      glPixelTransferf(GL_ALPHA_SCALE, 0.0000001);
      glPixelTransferf(GL_ALPHA_BIAS, 1.0);
   }

   srcTex = create_texture(GL_TRUE, srcIntFormat);
   dstTex = create_texture(GL_FALSE, dstIntFormat);

   glGenFramebuffers(1, &fboSrc);
   glGenFramebuffers(1, &fboDst);

   size = 1 << (NumLevels - 1);

   for (level = 0; level < NumLevels; level++) {
      /* setup src */
      glBindFramebuffer(GL_READ_FRAMEBUFFER, fboSrc);
      glFramebufferTexture2D(GL_READ_FRAMEBUFFER,
                             GL_COLOR_ATTACHMENT0,
                             GL_TEXTURE_2D,
                             srcTex,
                             level);

      status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
      if (status != GL_FRAMEBUFFER_COMPLETE) {
         fprintf(stderr, "Source FBO incomplete for level %u (0x%x)\n",
                 level, status);
         pass = GL_FALSE;
         break;
      }

      /* setup dest */
      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboDst);
      glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
                             GL_COLOR_ATTACHMENT0,
                             GL_TEXTURE_2D,
                             dstTex,
                             level);

      status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
      if (status != GL_FRAMEBUFFER_COMPLETE) {
         fprintf(stderr, "Dest FBO incomplete for level %u (0x%x)\n",
                 level, status);
         pass = GL_FALSE;
         break;
      }

      glReadBuffer(GL_COLOR_ATTACHMENT0);
      glDrawBuffer(GL_COLOR_ATTACHMENT0);

      /* copy from src mipmap level to dest */
      if (useReadDrawPix) {
         GLubyte *tmp = (GLubyte *) malloc(size * size * 4 * sizeof(GLubyte));
         glReadPixels(0, 0, size, size, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
         if (0)
            printf("copy color %u %u %u %u\n", tmp[0], tmp[1], tmp[2], tmp[3]);
         glDrawPixels(size, size, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
         free(tmp);
      }
      else {
         glCopyPixels(0, 0, size, size, GL_COLOR);
      }

      size /= 2;
   }

   /* restore */
   glPixelTransferf(GL_ALPHA_SCALE, 1.0);
   glPixelTransferf(GL_ALPHA_BIAS, 0.0);

   glDeleteFramebuffers(1, &fboSrc);
   glDeleteFramebuffers(1, &fboDst);

   glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);

   if (!pass)
      return GL_FALSE;

   /* Draw with dest texture and test the color */
   glBindTexture(GL_TEXTURE_2D, dstTex);
   glEnable(GL_TEXTURE_2D);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

   size = 1 << (NumLevels - 1);

   for (level = 0; level < NumLevels; level++) {
      GLboolean p;

      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, level);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, level);

      glClear(GL_COLOR_BUFFER_BIT);

      piglit_draw_rect_tex(0, 0, piglit_width, piglit_height,
                           0.0, 0.0, 1.0, 1.0);

      p = piglit_probe_pixel_rgba(piglit_width/2, piglit_height/2, colors[level]);
      if (!p) {
         printf("  Mipmap level %d\n", level);
	 printf("  Source tex format: %s\n",
		piglit_get_gl_enum_name(srcIntFormat));
	 printf("  Destination tex format: %s\n",
		piglit_get_gl_enum_name(dstIntFormat));
         if (useReadDrawPix)
            printf("  Using glRead/DrawPixels()\n");
         else
            printf("  Using glCopyPixels()\n");
         if (srcIntFormat == dstIntFormat)
            printf("  Matching src/dest texture formats\n");
         else
            printf("  Different src/dest texture formats\n");
         if (doPixelTransfer)
            printf("  With pixel transfer enabled\n");
         pass = GL_FALSE;
      }

      size /= 2;

      piglit_present_results();
   }

   glDisable(GL_TEXTURE_2D);

   glDeleteTextures(1, &srcTex);
   glDeleteTextures(1, &dstTex);

   return pass;
}
Example #16
0
/*
==================
RB_TakeVideoFrameCmd
==================
*/
const void     *RB_TakeVideoFrameCmd( const void *data )
{
	const videoFrameCommand_t *cmd;
	GLint                     packAlign;
	int                       lineLen, captureLineLen;
	byte                      *pixels;
	int                       i;
	int                       outputSize;
	int                       j;
	int                       aviLineLen;

	cmd = ( const videoFrameCommand_t * ) data;

	// RB: it is possible to we still have a videoFrameCommand_t but we already stopped
	// video recording
	if ( ri.CL_VideoRecording() )
	{
		// take care of alignment issues for reading RGB images..

		glGetIntegerv( GL_PACK_ALIGNMENT, &packAlign );

		lineLen = cmd->width * 3;
		captureLineLen = PAD( lineLen, packAlign );

		pixels = ( byte * ) PADP( cmd->captureBuffer, packAlign );
		glReadPixels( 0, 0, cmd->width, cmd->height, GL_RGB, GL_UNSIGNED_BYTE, pixels );

		if ( tr.overbrightBits > 0 && glConfig.deviceSupportsGamma )
		{
			// this also runs over the padding...
			R_GammaCorrect( pixels, captureLineLen * cmd->height );
		}

		if ( cmd->motionJpeg )
		{
			// Drop alignment and line padding bytes
			for ( i = 0; i < cmd->height; ++i )
			{
				memmove( cmd->captureBuffer + i * lineLen, pixels + i * captureLineLen, lineLen );
			}

			outputSize = SaveJPGToBuffer( cmd->encodeBuffer, 3 * cmd->width * cmd->height, 90, cmd->width, cmd->height, cmd->captureBuffer );
			ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, outputSize );
		}
		else
		{
			aviLineLen = PAD( lineLen, AVI_LINE_PADDING );

			for ( i = 0; i < cmd->height; ++i )
			{
				for ( j = 0; j < lineLen; j += 3 )
				{
					cmd->encodeBuffer[ i * aviLineLen + j + 0 ] = pixels[ i * captureLineLen + j + 2 ];
					cmd->encodeBuffer[ i * aviLineLen + j + 1 ] = pixels[ i * captureLineLen + j + 1 ];
					cmd->encodeBuffer[ i * aviLineLen + j + 2 ] = pixels[ i * captureLineLen + j + 0 ];
				}

				while ( j < aviLineLen )
				{
					cmd->encodeBuffer[ i * aviLineLen + j++ ] = 0;
				}
			}

			ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, aviLineLen * cmd->height );
		}
	}

	return ( const void * )( cmd + 1 );
}
Example #17
0
void Render_OpenGL31::getScreenPixelsRGBA(int x, int y, int w, int h, unsigned char *pixels)
{
    glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
}
Example #18
0
static int render_and_check(int w, int h, int d, GLenum format, float q, unsigned char* data, const char* test)
{
    int x, y, z;
    int layer;
    unsigned char* readback;
    unsigned char* texp;
    unsigned char* readp;
    int ncomp = 0;

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_3D);

    x = y = 0;
    for(layer = 0; layer < d; ++layer) {
        float r = (layer+0.5)/d;
        glBegin(GL_QUADS);
            glTexCoord4f(0, 0, r*q, q);
            glVertex2f(x, y);
            glTexCoord4f(q, 0, r*q, q);
            glVertex2f(x+w, y);
            glTexCoord4f(q, q, r*q, q);
            glVertex2f(x+w, y+h);
            glTexCoord4f(0, q, r*q, q);
            glVertex2f(x, y+h);
        glEnd();
        x += w;
        if (x+w >= piglit_width) {
            y += h;
            x = 0;
        }
    }

    readback = (unsigned char*)malloc(w*h*d*4);
    x = y = 0;
    for(layer = 0; layer < d; ++layer) {
        glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, readback+layer*w*h*4);
        x += w;
        if (x+w >= piglit_width) {
            y += h;
            x = 0;
        }
    }

    texp = data;
    readp = readback;
    ncomp = nrcomponents(format);
    for(z = 0; z < d; ++z) {
        for(y = 0; y < h; ++y) {
            for(x = 0; x < w; ++x, readp += 4, texp += ncomp) {
                unsigned char expected[4];
                int i;
                expected_rgba(format, texp, expected);
                for(i = 0; i < 4; ++i) {
                    if (expected[i] != readp[i]) {
                        fprintf(stderr, "%s: Mismatch at %ix%ix%i\n", test, x, y, z);
                        fprintf(stderr, " Expected: %i,%i,%i,%i\n",
                            expected[0], expected[1], expected[2], expected[3]);
                        fprintf(stderr, " Readback: %i,%i,%i,%i\n",
                            readp[0], readp[1], readp[2], readp[3]);
                        free(readback);
                        return 0;
                    }
                }
            }
        }
    }
    free(readback);

    glutSwapBuffers();
    return 1;
}
Example #19
0
/** \return GL_TRUE for pass, GL_FALSE for fail */
static bool
test_format(const struct format_info *info)
{
	const int max = get_max_val(info);
	const int comps = num_components(info->BaseFormat);
	const int texels = TexWidth * TexHeight;
	const GLenum type = get_datatype(info);
	const int w = piglit_width / 10;
	const int h = piglit_height / 10;
	const float error = 2.0 / 255.0; /* XXX fix */
	GLfloat expected[4];
	void *buf;
	int value[4];
	GLfloat result[4], bias[4];
	GLint f;

	/* pick random texture color */
	value[0] = rand() % max;
	value[1] = rand() % max;
	value[2] = rand() % max;
	value[3] = rand() % max;

	/* alloc, fill texture image */
	buf = malloc(comps * texels * info->BitsPerChannel / 8);
	fill_array(comps, texels, buf, info->BitsPerChannel, value);

	glTexImage2D(GL_TEXTURE_2D, 0, info->IntFormat, TexWidth, TexHeight, 0,
					 info->BaseFormat, type, buf);

	/* make sure the teximage call worked */
	if (!piglit_check_gl_error(GL_NO_ERROR))
		return false;

	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &f);

	/* setup expected polygon color */
	expected[0] = 0.25;
	expected[1] = 0.50;
	expected[2] = 0.75;
	expected[3] = 1.00;

	/* need to swizzle things depending on texture format */
	switch (info->BaseFormat) {
	case GL_RGBA_INTEGER_EXT:
		/* nothing */
		break;
	case GL_RGB_INTEGER_EXT:
		value[3] = 0.0;
		break;
	case GL_ALPHA_INTEGER_EXT:
		expected[0] = expected[1] = expected[2] = 0.0;
		expected[3] = 0.25;
		value[3] = value[0];
		value[0] = value[1] = value[2] = 0.0;
		break;
	case GL_LUMINANCE_INTEGER_EXT:
		expected[0] = expected[1] = expected[2] = 0.25;
		expected[3] = 1.0;
		value[1] = value[2] = value[0];
		value[3] = 1.0;
		break;
	case GL_LUMINANCE_ALPHA_INTEGER_EXT:
		expected[0] = expected[1] = expected[2] = 0.25;
		value[3] = value[1];
		value[1] = value[2] = value[0];
		break;
	case GL_RED_INTEGER_EXT:
		expected[0] = expected[1] = expected[2] = expected[3] = 0.25;
		value[1] = value[2] = value[3] = value[0];
		break;
	default:
		;
	}

	/* compute, set test bias */
	bias[0] = expected[0] - value[0];
	bias[1] = expected[1] - value[1];
	bias[2] = expected[2] - value[2];
	bias[3] = expected[3] - value[3];
	glUniform4fv(BiasUniform, 1, bias);

	/* draw */
	glClearColor(0, 1, 1, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_POLYGON);
	glTexCoord2f(0, 0);	glVertex2f(0, 0);
	glTexCoord2f(1, 0);	glVertex2f(w, 0);
	glTexCoord2f(1, 1);	glVertex2f(w, h);
	glTexCoord2f(0, 1);	glVertex2f(0, h);
	glEnd();

	/* test */
	glReadPixels(w/2, h/2, 1, 1, GL_RGBA, GL_FLOAT, result);

	if (fabsf(result[0] - expected[0]) > error ||
		 fabsf(result[1] - expected[1]) > error ||
		 fabsf(result[2] - expected[2]) > error ||
		 fabsf(result[3] - expected[3]) > error) {
		fprintf(stderr, "%s: failure with format %s:\n", TestName, info->Name);
		fprintf(stderr, "  texture color = %d, %d, %d, %d\n",
				  value[0], value[1], value[2], value[3]);
		fprintf(stderr, "  expected color = %g, %g, %g, %g\n",
				  expected[0], expected[1], expected[2], expected[3]);
		fprintf(stderr, "  result color = %g, %g, %g, %g\n",
				  result[0], result[1], result[2], result[3]);
		return false;
	}

	piglit_present_results();

	free(buf);

	return GL_TRUE;
}
Example #20
0
File: cogl.c Project: collects/cogl
void
_cogl_read_pixels_with_rowstride (int x,
                                  int y,
                                  int width,
                                  int height,
                                  CoglReadPixelsFlags source,
                                  CoglPixelFormat format,
                                  guint8 *pixels,
                                  int rowstride)
{
    CoglFramebuffer *framebuffer = _cogl_get_read_framebuffer ();
    int              framebuffer_height;
    int              bpp;
    CoglBitmap      *bmp;
    GLenum           gl_intformat;
    GLenum           gl_format;
    GLenum           gl_type;
    CoglPixelFormat  bmp_format;
    gboolean         pack_invert_set;

    _COGL_GET_CONTEXT (ctx, NO_RETVAL);

    _COGL_RETURN_IF_FAIL (source == COGL_READ_PIXELS_COLOR_BUFFER);

    if (width == 1 && height == 1 && !framebuffer->clear_clip_dirty)
    {
        /* If everything drawn so far for this frame is still in the
         * Journal then if all of the rectangles only have a flat
         * opaque color we have a fast-path for reading a single pixel
         * that avoids the relatively high cost of flushing primitives
         * to be drawn on the GPU (considering how simple the geometry
         * is in this case) and then blocking on the long GPU pipelines
         * for the result.
         */
        if (_cogl_framebuffer_try_fast_read_pixel (framebuffer,
                x, y, source, format,
                pixels))
            return;
    }

    /* make sure any batched primitives get emitted to the GL driver
     * before issuing our read pixels...
     *
     * XXX: Note we currently use cogl_flush to ensure *all* journals
     * are flushed here and not _cogl_journal_flush because we don't
     * track the dependencies between framebuffers so we don't know if
     * the current framebuffer depends on the contents of other
     * framebuffers which could also have associated journal entries.
     */
    cogl_flush ();

    _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
                                   framebuffer,
                                   COGL_FRAMEBUFFER_STATE_BIND);

    framebuffer_height = cogl_framebuffer_get_height (framebuffer);

    /* The y co-ordinate should be given in OpenGL's coordinate system
     * so 0 is the bottom row
     *
     * NB: all offscreen rendering is done upside down so no conversion
     * is necissary in this case.
     */
    if (!cogl_is_offscreen (framebuffer))
        y = framebuffer_height - y - height;

    /* Initialise the CoglBitmap */
    bpp = _cogl_get_format_bpp (format);
    bmp_format = format;

    if ((format & COGL_A_BIT))
    {
        /* We match the premultiplied state of the target buffer to the
         * premultiplied state of the framebuffer so that it will get
         * converted to the right format below */

        if ((framebuffer->format & COGL_PREMULT_BIT))
            bmp_format |= COGL_PREMULT_BIT;
        else
            bmp_format &= ~COGL_PREMULT_BIT;
    }

    bmp = _cogl_bitmap_new_from_data (pixels,
                                      bmp_format, width, height, rowstride,
                                      NULL, NULL);

    ctx->texture_driver->pixel_format_to_gl (format,
            &gl_intformat,
            &gl_format,
            &gl_type);

    /* NB: All offscreen rendering is done upside down so there is no need
     * to flip in this case... */
    if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
            !cogl_is_offscreen (framebuffer))
    {
        GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, TRUE));
        pack_invert_set = TRUE;
    }
    else
        pack_invert_set = FALSE;

    /* Under GLES only GL_RGBA with GL_UNSIGNED_BYTE as well as an
       implementation specific format under
       GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES and
       GL_IMPLEMENTATION_COLOR_READ_TYPE_OES is supported. We could try
       to be more clever and check if the requested type matches that
       but we would need some reliable functions to convert from GL
       types to Cogl types. For now, lets just always read in
       GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary. We also need
       to use this intermediate buffer if the rowstride has padding
       because GLES does not support setting GL_ROW_LENGTH */
    if (ctx->driver != COGL_DRIVER_GL &&
            (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE ||
             rowstride != 4 * width))
    {
        CoglBitmap *tmp_bmp, *dst_bmp;
        guint8 *tmp_data = g_malloc (width * height * 4);

        tmp_bmp = _cogl_bitmap_new_from_data (tmp_data,
                                              COGL_PIXEL_FORMAT_RGBA_8888 |
                                              (bmp_format & COGL_PREMULT_BIT),
                                              width, height, 4 * width,
                                              (CoglBitmapDestroyNotify) g_free,
                                              NULL);

        ctx->texture_driver->prep_gl_for_pixels_download (4 * width, 4);

        GE( ctx, glReadPixels (x, y, width, height,
                               GL_RGBA, GL_UNSIGNED_BYTE,
                               tmp_data) );

        /* CoglBitmap doesn't currently have a way to convert without
           allocating its own buffer so we have to copy the data
           again */
        if ((dst_bmp = _cogl_bitmap_convert_format_and_premult (tmp_bmp,
                       format)))
        {
            _cogl_bitmap_copy_subregion (dst_bmp,
                                         bmp,
                                         0, 0,
                                         0, 0,
                                         width, height);
            cogl_object_unref (dst_bmp);
        }
        else
        {
            /* FIXME: there's no way to report an error here so we'll
               just have to leave the data initialised */
        }

        cogl_object_unref (tmp_bmp);
    }
    else
    {
        ctx->texture_driver->prep_gl_for_pixels_download (rowstride, bpp);

        GE( ctx, glReadPixels (x, y, width, height, gl_format, gl_type, pixels) );

        /* Convert to the premult format specified by the caller
           in-place. This will do nothing if the premult status is already
           correct. */
        _cogl_bitmap_convert_premult_status (bmp, format);
    }

    /* Currently this function owns the pack_invert state and we don't want this
     * to interfere with other Cogl components so all other code can assume that
     * we leave the pack_invert state off. */
    if (pack_invert_set)
        GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, FALSE));

    /* NB: All offscreen rendering is done upside down so there is no need
     * to flip in this case... */
    if (!cogl_is_offscreen (framebuffer) && !pack_invert_set)
    {
        guint8 *temprow = g_alloca (rowstride * sizeof (guint8));

        /* vertically flip the buffer in-place */
        for (y = 0; y < height / 2; y++)
        {
            if (y != height - y - 1) /* skip center row */
            {
                memcpy (temprow,
                        pixels + y * rowstride, rowstride);
                memcpy (pixels + y * rowstride,
                        pixels + (height - y - 1) * rowstride, rowstride);
                memcpy (pixels + (height - y - 1) * rowstride,
                        temprow,
                        rowstride);
            }
        }
    }

    cogl_object_unref (bmp);
}
bool ofxFastFboReader::readToPixels(ofFbo &fbo, ofPixelsRef pix, ofImageType type)
{
	genPBOs();
	
	int channels;
	int glType;
	
	if (type == OF_IMAGE_COLOR)
	{
		channels = 3;
		glType = GL_RGB;
	}
	else if (type == OF_IMAGE_COLOR_ALPHA)
	{
		channels = 4;
		glType = GL_RGBA;
	}
	else if (type == OF_IMAGE_GRAYSCALE)
	{
		channels = 1;
		glType = GL_LUMINANCE;
	}
	else
	{
		return false;
	}
	
	const int width = fbo.getWidth();
	const int height = fbo.getHeight();
	
	if (async)
	{
		index = (index + 1) % num_buffers;
		nextIndex = (index + 1) % num_buffers;
	}
	else
	{
		index = nextIndex = 0;
	}
	
	size_t nb = width * height * channels;
	
	if (nb != num_bytes)
	{
		num_bytes = nb;
		setupPBOs(num_bytes);
	}
	
	glReadBuffer(GL_FRONT);
	
	fbo.bind();
	
	glBindBuffer(GL_PIXEL_PACK_BUFFER, pboIds[index]);
	glReadPixels(0, 0, width, height, glType, GL_UNSIGNED_BYTE, NULL);
	
	glBindBuffer(GL_PIXEL_PACK_BUFFER, pboIds[nextIndex]);
	unsigned char* mem = (unsigned char*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
	
	if (mem)
	{
		pix.setFromPixels(mem, width, height, channels);
		glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
	}
	
	glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
	
	fbo.unbind();
	
	return mem != NULL;
}
Example #22
0
void DrawSVG::draw_zoom() {

  // size (in pixels) of region of interest
  const size_t regionSize = 32;

  // relative size of zoom window
  size_t zoomFactor = 16;

  // compute zoom factor---the zoom window should never cover
  // more than 40% of the framebuffer, horizontally or vertically
  size_t bufferSize = min( width, height );
  if( regionSize*zoomFactor > bufferSize * 0.4) {
    zoomFactor = (bufferSize * 0.4 )/regionSize;
  }
  size_t zoomSize = regionSize * zoomFactor;

  // adjust the cursor coordinates so that the region of
  // interest never goes outside the bounds of the framebuffer
  size_t cX = max( regionSize/2, min( width-regionSize/2-1, (size_t) cursor_x ));
  size_t cY = max( regionSize/2, min( height-regionSize/2-1, height - (size_t) cursor_y ));

  // grab pixels from the region of interest
  vector<unsigned char> windowPixels( 3*regionSize*regionSize );
  glReadPixels( cX - regionSize/2,
                cY - regionSize/2 + 1, // meh
                regionSize,
                regionSize,
                GL_RGB,
                GL_UNSIGNED_BYTE,
                &windowPixels[0] );

  // upsample by the zoom factor, highlighting pixel boundaries
  vector<unsigned char> zoomPixels( 3*zoomSize*zoomSize );
  unsigned char* wp = &windowPixels[0];
  // outer loop over pixels in region of interest
  for( int y = 0; y < regionSize; y++ ) {
   int y0 = y*zoomFactor;
   for( int x = 0; x < regionSize; x++ ) {
      int x0 = x*zoomFactor;
      unsigned char* zp = &zoomPixels[ ( x0 + y0*zoomSize )*3 ];
      // inner loop over upsampled block
      for( int j = 0; j < zoomFactor; j++ ) {
        for( int i = 0; i < zoomFactor; i++ ) {
          for( int k = 0; k < 3; k++ ) {
            // highlight pixel boundaries
            if( i == 0 || j == 0 ) {
              const float s = .3;
              zp[k] = (int)( (1.-2.*s)*wp[k] + s*255. );
            } else {
              zp[k] = wp[k];
            }
          }
          zp += 3;
        }
        zp += 3*( zoomSize - zoomFactor );
      }
      wp += 3;
    }
  }

  // copy pixels to the screen using OpenGL
  glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glOrtho( 0, width, 0, height, 0.01, 1000. );
  glMatrixMode( GL_MODELVIEW  ); glPushMatrix(); glLoadIdentity(); glTranslated( 0., 0., -1. );

  glRasterPos2i( width-zoomSize, height-zoomSize );
  glDrawPixels( zoomSize, zoomSize, GL_RGB, GL_UNSIGNED_BYTE, &zoomPixels[0] );
  glMatrixMode( GL_PROJECTION ); glPopMatrix();
  glMatrixMode( GL_MODELVIEW ); glPopMatrix();

}
Example #23
0
void Game::start()
{
	int width = 800;
	int height = 600;

	// context creation
	this->context = new Context();
	this->context->initialize(4, 3);
	this->context->createWindow(width, height, 1, "ZPG", false, false, true);
	this->context->setKeyCallback([](GLFWwindow* window, int key, int scan, int action, int modifier) { InputController::getInstance().onKeyCallback(window, key, scan, action, modifier); });
	this->context->setMousePositionCallback([](GLFWwindow* window, double x, double y) { InputController::getInstance().onMouseMoveCallback(window, x, y); });
	this->context->setMouseScrollCallback([](GLFWwindow* window, double xOffset, double yOffset) { InputController::getInstance().onMouseScrollCallback(window, xOffset, yOffset); });
	this->context->setMouseButtonCallback([](GLFWwindow* window, int button, int action, int modifier) { InputController::getInstance().onMouseButtonCallback(window, button, action, modifier); });
	this->context->setWindowSizeCallback([](GLFWwindow* window, int width, int height) { Game::getInstance().onWindowSizeCallback(window, width, height); });
	this->context->setShowMouseCursor(false);
	this->context->setDepthTest(true);
	this->context->setDepthFunc(GL_LEQUAL);
	this->context->setStencilTest(true);
	this->context->setStencilMask(0xFF);
	this->context->setStencilFunc(GL_ALWAYS, 1, 0xFF);
	this->context->setStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
	this->context->setCulling(true);
	this->context->setBlending(true);
	this->context->setBlendingFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	this->screenQuad = new ScreenQuad();

	// manager preload
	AudioManager::getInstance().initialize();
	TextureManager::getInstance().preloadTextures();
	ModelManager::getInstance().preloadModels();
	FontManager::getInstance().initialize(width, height);

	ShaderLoader::getInstance().addCodeMapping("#LIGHT_DEFINITIONS", FileHelper::loadFile("Shaders/Headers/light_definitions.frag"));
	ShaderLoader::getInstance().addCodeMapping("#PHONG_CALCULATIONS", FileHelper::loadFile("Shaders/Headers/phong_calculations.frag"));

	ProgramManager::getInstance().preloadPrograms();
	Program program = ProgramManager::getInstance().get(ProgramManager::PROGRAM_MODEL);
	ProgramManager::getInstance().use(ProgramManager::PROGRAM_MODEL);

	FramebufferManager::getInstance().preloadFramebuffers();

	// initial object spawn 
	Camera* cameraScript = new Camera(new CameraController(10.0f), glm::vec3(0.0f, 0.0f, -1.0f), 45.0f, 4.0f / 3.0f, 0.1f, 1000.0f);
	this->camera = new GameObject(cameraScript, nullptr, new BasicPhysicsComponent(false, new SphereBoundingBox(1.0f)));
	this->camera->getTransform().setPosition(glm::vec3(0.0f, 0.0f, 8.0f));
	this->camera->getTags().set(Tag::Camera);
	this->scene.add(this->camera);

	ProgramManager::getInstance().observeCamera(cameraScript);

	// objects
	float distance = 3.0f;
	GameObject* cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Blue));
	this->scene.add(cube);
	cube->getTransform().setPosition(glm::vec3(distance, 0.0f, 0.0f));

	cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Red));
	this->scene.add(cube);
	cube->getTransform().setPosition(glm::vec3(-distance, 0.0f, 0.0f));

	cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Green));
	this->scene.add(cube);
	cube->getTransform().setPosition(glm::vec3(0.0f, distance, 0.0f));

	cube = new GameObject(nullptr, new ModelRenderComponent(ModelManager::getInstance().get(ModelManager::MODEL_CUBE), Color::Yellow));
	this->scene.add(cube);
	cube->getTransform().setPosition(glm::vec3(0.0f, -distance, 0.0f));

	// lights
	DirectionalLight *dirLight = new DirectionalLight(glm::vec3(10.0f, 10.0f, 10.0f), Phong(Color::White * 0.001f, Color::White, Color::White * 0.1f));
	GameObject* light = new GameObject(new LightComponent(dirLight, "directionalLight"));
	light->getTags().set(Tag::Light);
	this->scene.add(light);

	GeometryObject planeGeometry(VERTICES_PLANE, 2 * sizeof(glm::vec3), 6);
	planeGeometry.setAttributePositionNormal();

	GeometryObject cubeGeometry(VERTICES_CUBE, sizeof(glm::vec3), 36);
	cubeGeometry.setAttributePosition();

	PointLight* pointLight = new PointLight(Attenuation::ATT_DISTANCE_LONG, Phong(Color::White * 0.1f, Color::White, Color::White));
	light = new GameObject(
		new LightComponent(pointLight, "pointLights", 0),
		new SimpleConstantRenderer(cubeGeometry, ProgramManager::PROGRAM_GEOMETRY_CONSTANT, Color::White)
	);
	light->getTransform().setPosition(glm::vec3(0.0f, 0.0f, 0.0f));
	light->getTags().set(Tag::Light);
	this->scene.add(light);

	program.setUniform1i("pointLightCount", 1);

	SpotLight* spotLight = new SpotLight(glm::vec3(0.0f, 0.0f, -1.0f), 12.5f, 17.5f, Attenuation::ATT_DISTANCE_LONG, dirLight->phong);
	GameObject* spotLightObj = new GameObject(new LightComponent(spotLight, "spotLight"));
	spotLightObj->getTags().set(Tag::Light);
	this->scene.add(spotLightObj);

	GameObject* floor = new GameObject(nullptr, new SimpleConstantRenderer(planeGeometry, ProgramManager::PROGRAM_MODEL, Color::Purple));
	floor->getTransform().setScale(glm::vec3(10.0f));
	floor->getTransform().setPosition(glm::vec3(0.0f, -5.0f, 0.0f));
	this->scene.add(floor);

	// skybox
	const std::string skyboxPath = "Resources/Textures/skybox/";
	std::vector<Image> skyboxFaces;
	skyboxFaces.push_back(Image(skyboxPath + "right.jpg"));
	skyboxFaces.push_back(Image(skyboxPath + "left.jpg"));
	skyboxFaces.push_back(Image(skyboxPath + "top.jpg"));
	skyboxFaces.push_back(Image(skyboxPath + "bottom.jpg"));
	skyboxFaces.push_back(Image(skyboxPath + "back.jpg"));
	skyboxFaces.push_back(Image(skyboxPath + "front.jpg"));

	Cubemap skyboxCubemap;
	skyboxCubemap.allocate();
	skyboxCubemap.set2DImages(skyboxFaces);

	GameObject* skybox = new GameObject(nullptr, new SkyboxRenderer(skyboxCubemap));
	this->scene.add(skybox);

	GameObject* crossHair = new GameObject(nullptr, new SpriteRenderer(TextureManager::TEXTURE_CROSSHAIR));
	crossHair->getTransform().setScale(glm::vec3(50.0f, 50.0f, 1.0f));
	this->scene.add(crossHair);

	Timer timer(0.01f);
	Timer switchTimer(0.05f);

	context->loop([&](Context& context)	// physics
	{
		//this->physicsHandler.simulate(this->scene.getObjectManager().getObjects(), this->scene.getObjectManager().getObjectCount(), Context::getFixedDeltaTime());
	},	
	[&](Context& context)	// render
	{
		float delta = context.getDeltaTime();
		timer.update(delta);
		switchTimer.update(delta);

		FramebufferManager::getInstance().get(FramebufferManager::FRAMEBUFFER_POSTPROCESS).bind();

		RenderUtils::clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		RenderUtils::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

		context.setDepthTest(true);

		spotLight->direction = cameraScript->getFront();
		spotLightObj->getTransform().setPosition(camera->getTransform().getPosition());

		crossHair->getTransform().setPosition(glm::vec3(context.getWindowWidth() / 2.0f, context.getWindowHeight() / 2.0f, 0.0f));

		this->scene.update();
		this->scene.draw();

		GLchar byte;
		glReadPixels(context.getWindowWidth() / 2, context.getWindowHeight() / 2, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &byte);	// stencil value at the center

		this->screenQuad->drawScreen(context);

		if (timer.resetIfReady())
		{
			FontManager::getInstance().renderText("FPS: " + std::to_string(round(1.0f / delta)), 10.0f, height - 20.0f, 0.5f, glm::vec3(1.0f, 1.0f, 0.0f));
		}

		if (InputController::getInstance().isButtonPressed(GLFW_KEY_ESCAPE))
		{
			context.closeWindow();
		}
		else if (InputController::getInstance().isButtonPressed(GLFW_KEY_SPACE) && switchTimer.resetIfReady())
		{
			// switch render strategy
		}

		InputController::getInstance().afterUpdate();
		
		this->scene.updateFrameEnd();
	});

	// resource disposal
	this->screenQuad->dispose();
	delete this->screenQuad;

	this->scene.dispose();
	ProgramManager::getInstance().dispose();
	ModelManager::getInstance().dispose();
	TextureManager::getInstance().dispose();
	FramebufferManager::getInstance().dispose();
	AudioManager::getInstance().dispose();
	FontManager::getInstance().dispose();

	context->terminate();
}
Example #24
0
void StripDataFromBuffer(int ix, int iy, int iwidth, int iheight, TextureType tt, char * buffer) {
    glReadPixels(ix, iy, iwidth, iheight, imXTypes[tt], byTypes[tt], buffer);
}
Example #25
0
// Do numColors * numColors tests in one batch.
// Setup a texture in which the colors vary by column.
// Draw a quadstrip in which we draw horizontal bands of colors.
// Drawing the textured quadstrips will fill the window with
// numColors * numColors test squares.
// Verify that they're all correct.
// Return:  true = pass, false = fail
bool
TexEnvTest::MatrixTest(GLenum envMode, GLenum texFormat,
	const char *envName, const char *formatName,
	int numColors, const GLfloat colors[][4],
	const GLfloat envColor[4], Window &w) {

	if (envMode == GL_DECAL && (texFormat != GL_RGB &&
		texFormat != GL_RGBA)) {
		// undefined mode
		return true;
	}

	glClear(GL_COLOR_BUFFER_BIT);

	// The texture colors are the columns
	MakeTexImage(texFormat, numColors, colors);

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envMode);
	glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);

	// The fragment colors are the rows
	GLfloat W = numColors * 3;
	GLfloat S = (float) (numColors*3) / (float) 256;
	glBegin(GL_QUAD_STRIP);
	glTexCoord2f(0, 0);  glVertex2f(0, 0);
	glTexCoord2f(S, 0);  glVertex2f(W, 0);
	for (int i = 0; i < numColors; i++) {
		glColor4fv(colors[i]);
		GLfloat y = i * 3 + 3;
		GLfloat t = y / (numColors * 3);
		glTexCoord2f(0, t);  glVertex2f(0, y);
		glTexCoord2f(S, t);  glVertex2f(W, y);
	}
	glEnd();

	const GLsizei width = 256;
	const GLsizei height = 256;
	GLfloat *image = new GLfloat[width*height*4];
	glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, image);

	w.swap(); // lets us watch the progress

	// Check results
	for (int row = 0; row < numColors; row++) {
		for (int col = 0; col < numColors; col++) {

			// compute expected
			GLfloat expected[4];
			ComputeExpectedColor(envMode, texFormat,
				colors[col], colors[row],
				envColor, expected);

			// fetch actual pixel
			int x = col * 3 + 1;
			int y = row * 3 + 1;
			const GLfloat *actual = image + y*width*4 + x*4;

			// compare
			if (!TestColor(expected, actual)) {
				// Report the error
				env->log << name
					 << ":  FAIL:  GL_TEXTURE_ENV_MODE="
					 << envName
					 << "  Texture Format="
					 << formatName
					 << "  Fragment Color=("
					 << colors[row][0] << ", "
					 << colors[row][1] << ", "
					 << colors[row][2] << ", "
					 << colors[row][3] << ") "
					 << " Texture Color=("
					 << colors[col][0] << ", "
					 << colors[col][1] << ", "
					 << colors[col][2] << ", "
					 << colors[col][3] << ") "
					 << " Tex Env Color=("
					 << envColor[0] << ", "
					 << envColor[1] << ", "
					 << envColor[2] << ", "
					 << envColor[3] << ") "
#if BLEND_WITH_BACKGROUND
					 << " Blend over=("
					 << BgColor[0] << ", "
					 << BgColor[1] << ", "
					 << BgColor[2] << ", "
					 << BgColor[3] << ") "
#endif
					 << " Expected=("
					 << expected[0] << ", "
					 << expected[1] << ", "
					 << expected[2] << ", "
					 << expected[3] << ") "
					 << " Measured=("
					 << actual[0] << ", "
					 << actual[1] << ", "
					 << actual[2] << ", "
					 << actual[3] << ")\n";
				delete[] image;
				return false;
			}
		}
	}
	delete[] image;
	return true;
}
Example #26
0
/**
 * Captures the frame in RGBA format from the backbuffer.  This method works but is really slow because it locks the backbuffer
 * during the copy and prevents any furthur rendering until the copy is complete.  It also locks the backbuffer surface 
 * immediately after requesting the render target data which is bad because it doesn't give the GPU time to prepare the data
 * for locking asynchronously.
 */
bool CaptureFrame_Slow(int captureWidth, int captureHeight, unsigned char*& outRgbaFrame)
{
	// Create/recreate the target textures and surfaces if needed
	if (gResizeFBO == 0 || captureHeight != gBroadcastHeight || captureWidth != gBroadcastWidth)		
	{
		// recreate resize FBO
		CreateResizeFBO(captureWidth, captureHeight);

		// recreate capture PBO
		CreateCapturePBO(captureWidth, captureHeight);

		gBroadcastHeight = captureHeight;
		gBroadcastWidth = captureWidth;
	}

	// strect to resize FBO
	RenderToResizeFBO(captureWidth, captureHeight);

	// read resize FBO to capture PBO
	{
		glBindFramebuffer(GL_FRAMEBUFFER, gResizeFBO);

		glBindBuffer(GL_PIXEL_PACK_BUFFER, gCapturePBO);
	
		glReadPixels(0, 0, captureWidth, captureHeight, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}	

	// lock PBO for reading
	void* buffer = glMapBuffer(GL_PIXEL_PACK_BUFFER , GL_READ_ONLY);
	if ( buffer == nullptr )
	{
		ReportError("Error locking PBO");
		return false;
	}

	const int kPixelSize = 4;
	const int rgbaWidthBytes = captureWidth * kPixelSize;
	const int bgraFrameBytes = captureWidth * captureHeight * kPixelSize;

	// Grab the free buffer from the streaming pool
	outRgbaFrame = GetNextFreeBuffer();

	if ( outRgbaFrame != nullptr )
	{
		memcpy(outRgbaFrame, buffer, bgraFrameBytes);
	}
	
	GLboolean success;
	success = glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
	if ( !success )
	{
		ReportError("Error unlocking PBO");
		glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
		return false;
	}

	glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

	return true;
}
Example #27
0
/* get buffer as Image */
Image* RenderTexture::newImage(bool fliimage)
{
    CCASSERT(_pixelFormat == Texture2D::PixelFormat::RGBA8888, "only RGBA8888 can be saved as image");

    if (nullptr == _texture)
    {
        return nullptr;
    }

    const Size& s = _texture->getContentSizeInPixels();

    // to get the image size to save
    //        if the saving image domain exceeds the buffer texture domain,
    //        it should be cut
    int savedBufferWidth = (int)s.width;
    int savedBufferHeight = (int)s.height;

    GLubyte *buffer = nullptr;
    GLubyte *tempData = nullptr;
    Image *image = new (std::nothrow) Image();

    do
    {
        CC_BREAK_IF(! (buffer = new (std::nothrow) GLubyte[savedBufferWidth * savedBufferHeight * 4]));

        if(! (tempData = new (std::nothrow) GLubyte[savedBufferWidth * savedBufferHeight * 4]))
        {
            delete[] buffer;
            buffer = nullptr;
            break;
        }

        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO);
        glBindFramebuffer(GL_FRAMEBUFFER, _FBO);

        // TODO: move this to configration, so we don't check it every time
        /*  Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture. The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture. Create a temporary texture to overcome this. At the end of RenderTexture::begin(), switch the attached texture to the second one, call glClear, and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers.
         */
        if (Configuration::getInstance()->checkForGLExtension("GL_QCOM"))
        {
            // -- bind a temporary texture so we can clear the render buffer without losing our texture
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureCopy->getName(), 0);
            CHECK_GL_ERROR_DEBUG();
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0);
        }
        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glReadPixels(0,0,savedBufferWidth, savedBufferHeight,GL_RGBA,GL_UNSIGNED_BYTE, tempData);
        glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO);

        if ( fliimage ) // -- flip is only required when saving image to file
        {
            // to get the actual texture data
            // #640 the image read from rendertexture is dirty
            for (int i = 0; i < savedBufferHeight; ++i)
            {
                memcpy(&buffer[i * savedBufferWidth * 4],
                       &tempData[(savedBufferHeight - i - 1) * savedBufferWidth * 4],
                       savedBufferWidth * 4);
            }

            image->initWithRawData(buffer, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8);
        }
        else
        {
            image->initWithRawData(tempData, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8);
        }
        
    } while (0);

    CC_SAFE_DELETE_ARRAY(buffer);
    CC_SAFE_DELETE_ARRAY(tempData);

    return image;
}
Example #28
0
i_img *
imss_darwin(i_img_dim left, i_img_dim top, i_img_dim right, i_img_dim bottom) {
  CGDisplayCount count;
  CGDisplayErr err;
  CGRect rect;
  CGLPixelFormatObj pix;
  GLint npix;
  CGLContextObj ctx;
  i_img *im;
  CGDirectDisplayID disp;
  i_img_dim screen_width, screen_height;
  i_img_dim width, height;

  CGLPixelFormatAttribute pix_attrs[] =
    {
      kCGLPFADisplayMask, 0, /* filled in later */
      kCGLPFAColorSize, 24,
      kCGLPFAAlphaSize, 0,
      kCGLPFAFullScreen,
      0
    };

  i_clear_error();

  disp = CGMainDisplayID();
  if (!disp) {
    i_push_error(0, "No main display");
    return NULL;
  }
  
  /* for now, only interested in the first display */
  rect = CGDisplayBounds(disp);
  screen_width = rect.size.width;
  screen_height = rect.size.height;

  /* adjust negative/zero values to window size */
  if (left < 0)
    left += screen_width;
  if (top < 0)
    top += screen_height;
  if (right <= 0)
    right += screen_width;
  if (bottom <= 0)
    bottom += screen_height;
  
  /* clamp */
  if (left < 0)
    left = 0;
  if (right > screen_width)
    right = screen_width;
  if (top < 0)
    top = 0;
  if (bottom > screen_height)
    bottom = screen_height;

  /* validate */
  if (right <= left || bottom <= top) {
    i_push_error(0, "image would be empty");
    return NULL;
  }

  width = right - left;
  height = bottom - top;

  /* select a pixel format */
  pix_attrs[1] = CGDisplayIDToOpenGLDisplayMask(disp);
  err = CGLChoosePixelFormat(pix_attrs, &pix, &npix);
  if (err) {
    i_push_errorf(err, "CGLChoosePixelFormat: %d", (int)err);
    return NULL;
  }
  if (!npix) {
    i_push_error(0, "No pixel format found - hidden display?");
    return NULL;
  }

  /* make ourselves a context */
  err = CGLCreateContext(pix, NULL, &ctx);
  CGLDestroyPixelFormat(pix);
  if (err) {
    i_push_errorf(err, "CGLCreateContext: %d", (int)err);
    return NULL;
  }

  err = CGLSetCurrentContext(ctx);
  if (err) {
    i_push_errorf(err, "CGLSetCurrentContext: %d", (int)err);
    return NULL;
  }

  err = CGLSetFullScreen(ctx);
  if (err) {
    i_push_errorf(err, "CGLSetFullScreen: %d", (int)err);
    return NULL;
  }

  /* capture */
  im = i_img_8_new(width, height, 3);
  if (im) {
    size_t line_size = width * 4; 
    size_t buf_size = line_size * height;
    unsigned char *buf = malloc(buf_size);
    i_img_dim y = height - 1;
    i_color *bufp = (i_color *)buf; /* hackish */

    /* GL has the vertical axis going from bottom to top, so translate it */

    glReadBuffer(GL_FRONT);
    glReadPixels(left, screen_height - top - height, width, height,
		 GL_RGBA, GL_UNSIGNED_BYTE, buf);

    /* transfer */
    while (y >= 0) {
      i_plin(im, 0, width, y, bufp);
      bufp += width;
      --y;
    }
    
    free(buf);

    i_tags_setn(&im->tags, "ss_window_width", width);
    i_tags_setn(&im->tags, "ss_window_height", height);
    i_tags_set(&im->tags, "ss_type", "Darwin", 6);
    i_tags_setn(&im->tags, "ss_left", left);
    i_tags_setn(&im->tags, "ss_top", top);
  }

  /* clean up */
  CGLSetCurrentContext(NULL);
  CGLDestroyContext(ctx);

  return im;
}
Example #29
0
void takePicture() {
	glReadPixels(0, 0, viewport.w-1, viewport.h-1, GL_RGBA, GL_UNSIGNED_BYTE, arr);
	invertIMG(viewport.w-1, viewport.h-1);
}
Example #30
0
void
ReadPixSanityTest::checkRGBA(ReadPixSanityResult& r, Window& w) {
	DrawingSurfaceConfig& config = *r.config;
	RandomBitsDouble rRand(config.r, 1066);
	RandomBitsDouble gRand(config.g, 1492);
	RandomBitsDouble bRand(config.b, 1776);
	RandomBitsDouble aRand((config.a? config.a: 1), 1789);
	int thresh = 1;

	r.passRGBA = true;
	r.errRGBA = 0.0;
	for (int i = 0; i < 100 && r.passRGBA; ++i) {
		// Generate a random color and use it to clear the color buffer:
		float expected[4];
		expected[0] = rRand.next();
		expected[1] = gRand.next();
		expected[2] = bRand.next();
		expected[3] = aRand.next();
		glClearColor(expected[0],expected[1],expected[2],expected[3]);
		glClear(GL_COLOR_BUFFER_BIT);

		// If the color buffer doesn't have an alpha channel, then
		// the spec requires the readback value to be 1.0:
		if (!config.a)
			expected[3] = 1.0;

		// Read the buffer:
		GLfloat buf[READPIX_SANITY_WIN_SIZE][READPIX_SANITY_WIN_SIZE][4];
		glReadPixels(0, 0, READPIX_SANITY_WIN_SIZE,
			READPIX_SANITY_WIN_SIZE, GL_RGBA, GL_FLOAT, buf);

		// Now compute the error for each pixel, and record the
		// worst one we find:
		for (int y = 0; y < READPIX_SANITY_WIN_SIZE; ++y)
			for (int x = 0; x < READPIX_SANITY_WIN_SIZE; ++x) {
				GLfloat dr = abs(buf[y][x][0] - expected[0]);
				GLfloat dg = abs(buf[y][x][1] - expected[1]);
				GLfloat db = abs(buf[y][x][2] - expected[2]);
				GLfloat da = abs(buf[y][x][3] - expected[3]);
				double err =
				    max(ErrorBits(dr, config.r),
				    max(ErrorBits(dg, config.g),
				    max(ErrorBits(db, config.b),
					ErrorBits(da,
					   config.a? config.a: thresh+1))));
					   // The "thresh+1" fudge above is
					   // needed to force the error to
					   // be greater than the threshold
					   // in the case where there is no
					   // alpha channel.  Without it the
					   // error would be just equal to
					   // the threshold, and the test
					   // would spuriously pass.
				if (err > r.errRGBA) {
					r.xRGBA = x;
					r.yRGBA = y;
					r.errRGBA = err;
					for (int j = 0; j < 4; ++j) {
						r.expectedRGBA[j] = expected[j];
						r.actualRGBA[j] = buf[y][x][j];
					}
				}
			}

		if (r.errRGBA > thresh)
			r.passRGBA = false;
		w.swap();
	}
} // ReadPixSanityTest::checkRGBA