forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Copy screen to texture?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
theHobbit



Joined: 30 Sep 2006
Posts: 65

PostPosted: Fri May 09, 2008 7:42 am    Post subject: Copy screen to texture? Reply with quote

Hi there, does anyone knows how to copy the screen to a texture.
I'm trying with the pspsdk rendertarget sample and sceGuCopyImage, but with no result.


Here is the code

Code:

/*
 * PSP Software Development Kit - http://www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * rendertarget.c - Sample to demonstrate usage of ofscreen
 *                  texture as a render target
 *
 * Copyright (c) 2005 Jesper Svennevid
 * Copyright (c) 2005 Renaldas Zioma <rej@scene.lt>
 */

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#include <pspge.h>
#include <pspgu.h>
#include <pspgum.h>

PSP_MODULE_INFO("RenderTarget Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);

#define printf   pspDebugScreenPrintf

static unsigned int __attribute__((aligned(16))) list[262144];

typedef struct Vertex_ColorUV
{
   float u, v;
   unsigned int color;
   float x,y,z;
} Vertex_ColorUV;

typedef struct Vertex_Normal
{
   float nx,ny,nz;
   float x,y,z;
} Vertex_Normal;


typedef struct Texture
{
   int format;
   int mipmap;
   int width, height, stride;
   const void* data;
} Texture;

/* cube */

Vertex_ColorUV __attribute__((aligned(16))) cube_vertices[12*3] =
{
   {0, 0, 0xff7f0000,-1,-1, 1}, // 0
   {1, 0, 0xff7f0000,-1, 1, 1}, // 4
   {1, 1, 0xff7f0000, 1, 1, 1}, // 5

   {0, 0, 0xff7f0000,-1,-1, 1}, // 0
   {1, 1, 0xff7f0000, 1, 1, 1}, // 5
   {0, 1, 0xff7f0000, 1,-1, 1}, // 1

   {0, 0, 0xff7f0000,-1,-1,-1}, // 3
   {1, 0, 0xff7f0000, 1,-1,-1}, // 2
   {1, 1, 0xff7f0000, 1, 1,-1}, // 6

   {0, 0, 0xff7f0000,-1,-1,-1}, // 3
   {1, 1, 0xff7f0000, 1, 1,-1}, // 6
   {0, 1, 0xff7f0000,-1, 1,-1}, // 7

   {0, 0, 0xff007f00, 1,-1,-1}, // 0
   {1, 0, 0xff007f00, 1,-1, 1}, // 3
   {1, 1, 0xff007f00, 1, 1, 1}, // 7

   {0, 0, 0xff007f00, 1,-1,-1}, // 0
   {1, 1, 0xff007f00, 1, 1, 1}, // 7
   {0, 1, 0xff007f00, 1, 1,-1}, // 4

   {0, 0, 0xff007f00,-1,-1,-1}, // 0
   {1, 0, 0xff007f00,-1, 1,-1}, // 3
   {1, 1, 0xff007f00,-1, 1, 1}, // 7

   {0, 0, 0xff007f00,-1,-1,-1}, // 0
   {1, 1, 0xff007f00,-1, 1, 1}, // 7
   {0, 1, 0xff007f00,-1,-1, 1}, // 4

   {0, 0, 0xff00007f,-1, 1,-1}, // 0
   {1, 0, 0xff00007f, 1, 1,-1}, // 1
   {1, 1, 0xff00007f, 1, 1, 1}, // 2

   {0, 0, 0xff00007f,-1, 1,-1}, // 0
   {1, 1, 0xff00007f, 1, 1, 1}, // 2
   {0, 1, 0xff00007f,-1, 1, 1}, // 3

   {0, 0, 0xff00007f,-1,-1,-1}, // 4
   {1, 0, 0xff00007f,-1,-1, 1}, // 7
   {1, 1, 0xff00007f, 1,-1, 1}, // 6

   {0, 0, 0xff00007f,-1,-1,-1}, // 4
   {1, 1, 0xff00007f, 1,-1, 1}, // 6
   {0, 1, 0xff00007f, 1,-1,-1}, // 5
};

/* torus */

#define TORUS_SLICES 48 // numc
#define TORUS_ROWS 48 // numt
#define TORUS_RADIUS 1.0f
#define TORUS_THICKNESS 0.5f

Vertex_Normal __attribute__((aligned(16))) torus_vertices[TORUS_SLICES*TORUS_ROWS];
unsigned short __attribute__((aligned(16))) torus_indices[TORUS_SLICES*TORUS_ROWS*6];


int SetupCallbacks();

void genTorus( unsigned slices, unsigned rows, float radius, float thickness,
   Vertex_Normal* dstVertices, unsigned short* dstIndices );

#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define PIXEL_SIZE (4) /* change this if you change to another screenmode */
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE)
#define ZBUF_SIZE (BUF_WIDTH * SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */

void drawCube( Texture* texture, int val )
{
   // setup matrices for cube

   sceGumMatrixMode(GU_PROJECTION);
   sceGumLoadIdentity();
   sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f);

   sceGumMatrixMode(GU_VIEW);
   {
      ScePspFVector3 pos = {0.0f,0.0f,-2.5f};

      sceGumLoadIdentity();
      sceGumTranslate(&pos);
   }

   sceGumMatrixMode(GU_MODEL);
   {
      ScePspFVector3 rot = {val * 0.263f * (GU_PI/180.0f), val * 0.32f * (GU_PI/180.0f), val * 0.44f * (GU_PI/180.0f)};

      sceGumLoadIdentity();
      sceGumRotateXYZ(&rot);
   }

   // setup texture

   sceGuTexMode(texture->format,0,0,0);
   sceGuTexImage(texture->mipmap,texture->width,texture->height,texture->stride,texture->data);
   sceGuTexFunc(GU_TFX_ADD,GU_TCC_RGB);
   sceGuTexFilter(GU_LINEAR,GU_LINEAR);
   sceGuTexScale(1.0f,1.0f);
   sceGuTexOffset(0.0f,0.0f);
   sceGuAmbientColor(0xffffffff);

   sceGuEnable(GU_TEXTURE_2D);

   // draw cube

   sceGumDrawArray(GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,cube_vertices);

   sceGuDisable(GU_TEXTURE_2D);
}

void drawTorus( int val )
{
   // setup a light

   ScePspFVector3 dir = { 0, 0, 1 };
   sceGuLight(0,GU_DIRECTIONAL,GU_DIFFUSE,&dir);
   sceGuLightColor(0,GU_DIFFUSE,0x00ff4040 );
   sceGuLightAtt(0,1.0f,0.0f,0.0f);
   sceGuAmbient(0x00202020);

   // setup texture
   sceGuDisable(GU_TEXTURE_2D);
   sceGuEnable(GU_LIGHTING);
   sceGuEnable(GU_LIGHT0);

   // setup matrices for torus

   sceGumMatrixMode(GU_PROJECTION);
   sceGumLoadIdentity();
   sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f);

   sceGumMatrixMode(GU_VIEW);
   {
      ScePspFVector3 pos = {0.0f,0.0f,-2.5f};

      sceGumLoadIdentity();
      sceGumTranslate(&pos);
   }

   sceGumMatrixMode(GU_MODEL);
   {
      ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)};

      sceGumLoadIdentity();
      sceGumRotateXYZ(&rot);
   }

   // draw torus

   sceGuColor(0xffffff);
   sceGumDrawArray(GU_TRIANGLES,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_INDEX_16BIT|GU_TRANSFORM_3D,sizeof(torus_indices)/sizeof(unsigned short),torus_indices,torus_vertices);


   // restore state

   sceGuDisable(GU_LIGHTING);
   sceGuDisable(GU_LIGHT0);
   sceGuEnable(GU_TEXTURE_2D);
}



int main(int argc, char* argv[])
{
   SetupCallbacks();

   // generate geometry

   genTorus( TORUS_ROWS, TORUS_SLICES, TORUS_RADIUS, TORUS_THICKNESS, torus_vertices, torus_indices );      

   // flush cache so that no stray data remains

   sceKernelDcacheWritebackAll();

   // setup Edram buffers

   void* frameBuffer = (void*)0;
   const void* doubleBuffer = (void*)0x44000;
   const void* renderTarget = (void*)0x88000;
   const void* depthBuffer = (void*)0x110000;

   // setup GU

   sceGuInit();

   sceGuStart(GU_DIRECT,list);
   sceGuDrawBuffer(GU_PSM_4444,frameBuffer,BUF_WIDTH);
   sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)doubleBuffer,BUF_WIDTH);
   sceGuDepthBuffer((void*)depthBuffer,BUF_WIDTH);
   sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
   sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
   sceGuDepthRange(0xc350,0x2710);
   sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
   sceGuEnable(GU_SCISSOR_TEST);
   sceGuDepthFunc(GU_GEQUAL);
   sceGuEnable(GU_DEPTH_TEST);
   sceGuFrontFace(GU_CW);
   sceGuShadeModel(GU_SMOOTH);
   sceGuEnable(GU_CULL_FACE);
   sceGuEnable(GU_TEXTURE_2D);
   sceGuFinish();
   sceGuSync(0,0);

   sceDisplayWaitVblankStart();
   sceGuDisplay(GU_TRUE);

   // run sample
   int val = 0;
   Texture offscreenTexture = {
      GU_PSM_4444,
      0, 128, 128, 128,
      sceGeEdramGetAddr() + (int)renderTarget
   };

   for(;;)
   {
      sceGuStart(GU_DIRECT,list);

      {
         sceGuDrawBufferList(GU_PSM_4444,(void*)renderTarget,offscreenTexture.stride);

         // setup viewport

         sceGuOffset(2048 - (offscreenTexture.width/2),2048 - (offscreenTexture.height/2));
         sceGuViewport(2048,2048,offscreenTexture.width,offscreenTexture.height);

         // clear screen

         sceGuClearColor(0xffffffff);
         sceGuClearDepth(0);
         sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);

         // draw torus to offscreen texture

         drawTorus( val );
      }

      {
         // set frame buffer

         sceGuDrawBufferList(GU_PSM_4444,(void*)frameBuffer,BUF_WIDTH);

         // setup viewport

         sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
         sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
         
         // clear screen

         sceGuClearColor(0xff554433);
         sceGuClearDepth(0);
         sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);

         // draw cube using offscreen texture

         drawCube( &offscreenTexture, val );

      }
      
      sceGuCopyImage(GU_PSM_4444,0,0,480,272,512,(void*)(0x04000000+(u32)frameBuffer),0,0,128,offscreenTexture.data);

      sceGuFinish();
      sceGuSync(0,0);

      sceDisplayWaitVblankStart();
      frameBuffer = sceGuSwapBuffers();

      val++;
   }

   sceGuTerm();

   sceKernelExitGame();
   return 0;
}

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
   sceKernelExitGame();
   return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
   int cbid;

   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);

   sceKernelSleepThreadCB();

   return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
   if(thid >= 0)
   {
      sceKernelStartThread(thid, 0, 0);
   }

   return thid;
}

/* usefull geometry functions */
void genTorus( unsigned slices, unsigned rows, float radius, float thickness, Vertex_Normal* dstVertices, unsigned short* dstIndices )
{
   unsigned int i,j;

   // generate torus (TODO: tri-strips)
   for (j = 0; j < slices; ++j)
   {
      for (i = 0; i < rows; ++i)
      {
         struct Vertex_Normal* curr = &dstVertices[i+j*rows];
         float s = i + 0.5f;
         float t = j;
         float cs,ct,ss,st;

         cs = cosf(s * (2*GU_PI)/slices);
         ct = cosf(t * (2*GU_PI)/rows);
         ss = sinf(s * (2*GU_PI)/slices);
         st = sinf(t * (2*GU_PI)/rows);

         curr->nx = cs * ct;
         curr->ny = cs * st;
         curr->nz = ss;

         curr->x = (radius + thickness * cs) * ct;
         curr->y = (radius + thickness * cs) * st;
         curr->z = thickness * ss;
      }
   }

   for (j = 0; j < slices; ++j)
   {
      for (i = 0; i < rows; ++i)
      {
         unsigned short* curr = &dstIndices[(i+(j*rows))*6];
         unsigned int i1 = (i+1)%rows, j1 = (j+1)%slices;

         *curr++ = i + j * rows;
         *curr++ = i1 + j * rows;
         *curr++ = i + j1 * rows;

         *curr++ = i1 + j * rows;
         *curr++ = i1 + j1 * rows;
         *curr++ = i + j1 * rows;
      }
   }
}



But it does nothing. Does anyone knows how to copy the screen to the texture data?

Thanks in advance!!
Back to top
View user's profile Send private message
romero126



Joined: 24 Dec 2005
Posts: 200

PostPosted: Fri May 09, 2008 8:59 am    Post subject: Reply with quote

Code:
Image* ScreenCopyImage()
{
   Image* image = createImage(SCREEN_WIDTH, SCREEN_HEIGHT);
   if (!image) return NULL;

   Color *destinationData = image->data;
   Color *vram = getVramDisplayBuffer();

   int i, x, y;
   for (y = 0; y < SCREEN_HEIGHT; y++) {
   
      for (i = 0, x = 0; x < SCREEN_WIDTH; x++) {
         Color color = vram[x + y * PSP_LINE_SIZE];
         u8 r = R(color);
         u8 g = G(color);
         u8 b = B(color);
         u8 a = 255; //(color >> 24) & 0xff; This errors out if alpha is in place!

         destinationData[y * image->textureWidth + x] = a << 24 | b << 16 | g << 8 | r;
      }
      vram += PSP_LINE_SIZE - image->textureWidth;
   }

   return image;
}
Back to top
View user's profile Send private message
jean



Joined: 05 Jan 2008
Posts: 489

PostPosted: Fri May 09, 2008 5:25 pm    Post subject: Reply with quote

Ok, the question was "how to copy ..." so the provided code up here is right, but why to do so in software?? the example provided in sdk to render into a texture works fine, so use it.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group