Reading texture from PVR back into SH-4 RAM
- MisterDave
- DCEmu Freak
- Posts: 58
- https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Reading texture from PVR back into SH-4 RAM
Just a quick question about textures in the PVR RAM. Do you know if it is possible to be able to read these back into SH-4 RAM and possibly untwiddle into a raw form for modification?
My thought behind this is to be able to perform a blurring effect to achieve a light bloom. I have had a look at the often cited (http://yam.20to4.net/dreamcast/index_old.html) and the author achieves a box filter effect amongst other post-processing effects which would help achieve this.
Without this to keep things in the PVR RAM (as an alternative) I have thought about rendering part of a scene to a small part of a texture and then just drawing this to a polygon scaled back up. However, the PVR only seems to be able to write to rounded screen size (1024 x 512) textures, which makes grabbing a precise section back rather tricky.
Any advice on this would be appreciated
Thanks,
Dave
My thought behind this is to be able to perform a blurring effect to achieve a light bloom. I have had a look at the often cited (http://yam.20to4.net/dreamcast/index_old.html) and the author achieves a box filter effect amongst other post-processing effects which would help achieve this.
Without this to keep things in the PVR RAM (as an alternative) I have thought about rendering part of a scene to a small part of a texture and then just drawing this to a polygon scaled back up. However, the PVR only seems to be able to write to rounded screen size (1024 x 512) textures, which makes grabbing a precise section back rather tricky.
Any advice on this would be appreciated
Thanks,
Dave
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
Well, in KOS, pvr_ptr_t "objects" are simply pointers. So, if you have a pvr_ptr_t, you can read/write to/from it just like any other pointer (just potentially slower).
If you're using render-to-texture, it can be set up to do non-screen-sized output, but I just haven't ever gotten the chance to fix the code for that possibility. Also, the rendered "texture" should be non-twiddled and easily workable, simply as RGB565 pixels (unless you've changed the output format, of course).
If you're using render-to-texture, it can be set up to do non-screen-sized output, but I just haven't ever gotten the chance to fix the code for that possibility. Also, the rendered "texture" should be non-twiddled and easily workable, simply as RGB565 pixels (unless you've changed the output format, of course).
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Thanks BlueCrab. I wasn't sure if the object at the end of the pvr_ptr_t was readable and manipulatable, so thanks for clarifying that for me.
I noticed on the Parallax tutorial 35 that there was an example of ortho rendering, which helps to deal with scaling down and texture then picking it out and scaling back up to create a blur so that issue has gone.
One last question that I have with KOS is regarding the blending source and destination flags. From what I understand the PVR2 only supports alpha blending, however, the flags imply that KOS somehow enables additive blending. I have had a play with different combinations, but they seem to lead to the same effect. Do you know if additive blending is possible with the hardware with a workaround?
I noticed on the Parallax tutorial 35 that there was an example of ortho rendering, which helps to deal with scaling down and texture then picking it out and scaling back up to create a blur so that issue has gone.
One last question that I have with KOS is regarding the blending source and destination flags. From what I understand the PVR2 only supports alpha blending, however, the flags imply that KOS somehow enables additive blending. I have had a play with different combinations, but they seem to lead to the same effect. Do you know if additive blending is possible with the hardware with a workaround?
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
For Opaque polygons, the only valid combination is PVR_BLEND_ONE for the source and PVR_BLEND_ZERO for the destination.
For Punch-thru polygons, the only valid combination is PVR_BLEND_SRCALPHA for the source and PVR_BLEND_INVSRCALPHA for the destination.
For translucent polygons, you should be able to use whatever blending modes you want for the source and destination, and they all should work as they would be expected to work.
The only blending modes available involve alpha blending.
For Punch-thru polygons, the only valid combination is PVR_BLEND_SRCALPHA for the source and PVR_BLEND_INVSRCALPHA for the destination.
For translucent polygons, you should be able to use whatever blending modes you want for the source and destination, and they all should work as they would be expected to work.
The only blending modes available involve alpha blending.
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Thanks for the help. I seem to have more or less the effect that I was looking for by using alpha blending, however, when rendering to textures before blending I seem to have hit on either a bug in the hardware or something that I have misunderstood.
From what I can tell pvr_scene_begin_txr(...) can only be called once before a pvr_scene_begin() as a blank frame is passed to the screen itself when pvr_scene_begin_txr(...) is called again causing a flicker. Is this a known limitation with the hardware or should it be possible to call pvr_scene_begin_txr repeatedly to render to multiple textures then blend them together within the final pvr_scene_begin(). In this case I have ensured that pvr_wait_ready() is called before each frame is drawn.
From what I can tell pvr_scene_begin_txr(...) can only be called once before a pvr_scene_begin() as a blank frame is passed to the screen itself when pvr_scene_begin_txr(...) is called again causing a flicker. Is this a known limitation with the hardware or should it be possible to call pvr_scene_begin_txr repeatedly to render to multiple textures then blend them together within the final pvr_scene_begin(). In this case I have ensured that pvr_wait_ready() is called before each frame is drawn.
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
You shouldn't call pvr_scene_begin() when you do pvr_scene_begin_txr(). Only call one or the other. I'm not sure if you're calling both on the same scene, but what you wrote seems sort of like you are.
There is an example in the KOS tree of doing render-to-texture. Should be in examples/dreamcast/pvr/texture_render. Dunno if you've seen that or not.
There is an example in the KOS tree of doing render-to-texture. Should be in examples/dreamcast/pvr/texture_render. Dunno if you've seen that or not.
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Apologies if that didn't come across too clear. I have looked through both the pvr render-to-texture and lesson35 examples which have given me enough information to put together an example to render a scene to a texture then to draw a cube with this texture on the sides. This seems to work fine.
The cut down code for what is causing the 'flashing black' is below. If I remove the second 'pvr_scene_begin_txr' then everything works fine, however, rendering more than one scene to a texture is causing the screen to blank.
pvr_wait_ready();
pvr_scene_begin_txr(TextureA.ptr, &tx_x, &tx_y);
... draw lists for first scene
pvr_scene_finish();
pvr_wait_ready();
pvr_scene_begin_txr(TextureB.ptr, &tx_x, &tx_y);
... draw lists for second scene
pvr_scene_finish();
pvr_wait_ready();
pvr_scene_begin();
... draw two cubes textured with TextureA and TextureB
pvr_scene_finish();
Thanks,
Dave
The cut down code for what is causing the 'flashing black' is below. If I remove the second 'pvr_scene_begin_txr' then everything works fine, however, rendering more than one scene to a texture is causing the screen to blank.
pvr_wait_ready();
pvr_scene_begin_txr(TextureA.ptr, &tx_x, &tx_y);
... draw lists for first scene
pvr_scene_finish();
pvr_wait_ready();
pvr_scene_begin_txr(TextureB.ptr, &tx_x, &tx_y);
... draw lists for second scene
pvr_scene_finish();
pvr_wait_ready();
pvr_scene_begin();
... draw two cubes textured with TextureA and TextureB
pvr_scene_finish();
Thanks,
Dave
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
Ah... I've never actually tried rendering two frames in a row with render-to-texture... I'd guess the code is probably doing something slightly wrong, but I couldn't tell you what at the moment.
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Thanks for the advice anyways. I need to do a bit more testing to determine why this is happening. If it's something in KOS rather than my own code I'll see if I can fix it and make a patch.
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
When I said "in the code", I was referring to KOS itself. When I committed the patch years ago to re-enable the render-to-texture support that had been missing since the PVR API was re-done in like 1.1.7, I actually didn't quite have a grasp on everything that it was doing. I probably overlooked something back then.MisterDave wrote:Thanks for the advice anyways. I need to do a bit more testing to determine why this is happening. If it's something in KOS rather than my own code I'll see if I can fix it and make a patch.
EDIT: I think I may see the problem in the code, but I obviously want to test to see if this corrects it or not. Unfortunately, I have to walk out the door, so I can't quite test it at the moment.
EDIT x2: Well, I'm now 100% sure this is the code that is causing the problem. I have to rearrange a few things, because the way the code is set up now you cannot possibly do two render-to-texture passes without doing an intervening render-to-screen pass.
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
So, I committed a fix for this problem to the repository tonight (commit da33c8).
There were a bunch of problems with the code, so I'll kinda briefly cover what was wrong... Basically, the main problem was that there was only one set of render-to-texture state, whereas every other bit of rendering state is duplicated. The reason the rendering state is duplicated is because you will always have one scene rendering while you're sending the data for the next. So, when you're submitting polygons, they obviously won't be drawn immediately -- basically, your standard double-buffer setup.
Since only one set of state variables for render-to-texture was stored, one of them represented whether texture rendering was enabled or not. This had three possible values -- 0: normal screen render, 1: you've called pvr_scene_begin_txr(), 2: you called pvr_scene_begin_txr() one frame ago, so the current render is going to a texture. You should already see the problem as to why this would (obviously) not work if you call pvr_scene_begin_txr() on two frames in a row... Basically, when you'd do that, you'd upset the state internally of the code and the framebuffer would get swapped (since it got swapped to the display in all states of that variable except it being 2).
So, now there's two sets of state for all the render-to-texture variables to take care of the issues involved with that... I didn't see any issues with doing two passes of render-to-texture in a row (I modified the example I mentioned before to do that). That said, I'm still not completely satisfied with how I'm doing things, even though it appears to work. Oh well...
There were a bunch of problems with the code, so I'll kinda briefly cover what was wrong... Basically, the main problem was that there was only one set of render-to-texture state, whereas every other bit of rendering state is duplicated. The reason the rendering state is duplicated is because you will always have one scene rendering while you're sending the data for the next. So, when you're submitting polygons, they obviously won't be drawn immediately -- basically, your standard double-buffer setup.
Since only one set of state variables for render-to-texture was stored, one of them represented whether texture rendering was enabled or not. This had three possible values -- 0: normal screen render, 1: you've called pvr_scene_begin_txr(), 2: you called pvr_scene_begin_txr() one frame ago, so the current render is going to a texture. You should already see the problem as to why this would (obviously) not work if you call pvr_scene_begin_txr() on two frames in a row... Basically, when you'd do that, you'd upset the state internally of the code and the framebuffer would get swapped (since it got swapped to the display in all states of that variable except it being 2).
So, now there's two sets of state for all the render-to-texture variables to take care of the issues involved with that... I didn't see any issues with doing two passes of render-to-texture in a row (I modified the example I mentioned before to do that). That said, I'm still not completely satisfied with how I'm doing things, even though it appears to work. Oh well...
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Thanks for looking into this so quickly BlueCrab and for creating a patch. Fingers crossed I should be able to get my bloom filter complete now. If this works as expected then I would be happy to share my code in the case that anyone else wants to reuse it as an example.
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
If you'd like, I could possibly add it to the repository as an example program.MisterDave wrote:Thanks for looking into this so quickly BlueCrab and for creating a patch. Fingers crossed I should be able to get my bloom filter complete now. If this works as expected then I would be happy to share my code in the case that anyone else wants to reuse it as an example.
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Cool, I'd be happy to do that. The effect works fairly well, I'm just wrestling with a bug that seems to make anything that moves behind the camera repeat in an endless corridor in front of the camera and trying to determine what is causing it.
It seems to be in the Parallax version of nehe lesson 10 (lesson 9 in the parallaxnehe naming convention) has that bug too. It runs fine on lxdream, but on the real hardware the problem happens. I'm just trying at the moment to determine if it is something wrong in that code (such as clipping being set wrong) or in KOS itself.
It seems to be in the Parallax version of nehe lesson 10 (lesson 9 in the parallaxnehe naming convention) has that bug too. It runs fine on lxdream, but on the real hardware the problem happens. I'm just trying at the moment to determine if it is something wrong in that code (such as clipping being set wrong) or in KOS itself.
- BlueCrab
- The Crabby Overlord
- Posts: 5658
- Joined: Mon May 27, 2002 11:31 am
- Location: Sailing the Skies of Arcadia
- Has thanked: 9 times
- Been thanked: 69 times
- Contact:
Re: Reading texture from PVR back into SH-4 RAM
That seems like a clipping bug or perhaps something odd with some matrix transforms.MisterDave wrote:It seems to be in the Parallax version of nehe lesson 10 (lesson 9 in the parallaxnehe naming convention) has that bug too. It runs fine on lxdream, but on the real hardware the problem happens. I'm just trying at the moment to determine if it is something wrong in that code (such as clipping being set wrong) or in KOS itself.
Keep in mind that the PVR itself doesn't do any camera-related transforms or whatnot, so you do have to do a bit of manual work to deal with Z plane clipping and such.
- PH3NOM
- DC Developer
- Posts: 576
- Joined: Fri Jun 18, 2010 9:29 pm
- Has thanked: 0
- Been thanked: 5 times
Re: Reading texture from PVR back into SH-4 RAM
Yes BlueCrab beat me to it somehow ( my last post didnt submit? )MisterDave wrote:I'm just wrestling with a bug that seems to make anything that moves behind the camera repeat in an endless corridor in front of the camera and trying to determine what is causing it.
It seems to be in the Parallax version of nehe lesson 10 (lesson 9 in the parallaxnehe naming convention) has that bug too. It runs fine on lxdream, but on the real hardware the problem happens. I'm just trying at the moment to determine if it is something wrong in that code (such as clipping being set wrong) or in KOS itself.
You will need to clip the vertices to the Near-Z Plane for use with the PVR, the results of not doing so, as you have experienced, can be quite bizarre indeed.
KGL includes a mechanism for Clipping on the Near-Z Plane, that might be sufficient for your project.
However, I noticed many deficiencies with the algorithm, so I decided to write my own implementation for my build of OpenGL.
My algorithm ( currently only written for clipping Triangle Strips, but will be easy to add support for triangles ) will break a Triangle Strip down into individual triangles, clipping them against the Near-Z plane, and output the results as an array of triangles.
It is not yet completed, as there are some cases where a strip will be clipped when it shouldn't, but I am not sure if the problem is in my clip code, or in the stage that clipping occurs in my pipeline( post transformation )
Any rate, here is my code, if you know of a better method I would like to hear about it.
Code: Select all
/*
** Gl-Clip.c (C) Josh PH3NOM Pearson 2013
** *Work In Progress
*/
#include <dc/pvr.h>
#define NONE 0x0000 /* Clip Codes */
#define FIRST 0x0001
#define SECOND 0x0010
#define THIRD 0x0100
#define ALL 0x0111
#define FIRST_TWO_OUT 0x0011
#define FIRST_AND_LAST_OUT 0x0101
#define LAST_TWO_OUT 0x0110
#define ALPHA 0xFF000000 /* Color Components using PVR's Packed 32bit int */
#define RED 0x00FF0000
#define GREEN 0x0000FF00
#define BLUE 0x000000FF
#define CLIP_ZNEAR 0.00001
#define CLIPZ 0xF
inline void VertexCopy( pvr_vertex_t *src, pvr_vertex_t *dst )
{
*dst = *src;
}
inline void VertexClipZNear( pvr_vertex_t *v1, pvr_vertex_t *v2 )
{
float MAG = (CLIP_ZNEAR - v1->z)/(v2->z-v1->z); /* Displacement Mag */
/* Linear interpolate the U/V data */
v1->u = ((v2->u-v1->u)*MAG)+v1->u;
v1->v = ((v2->v-v1->v)*MAG)+v1->v;
/* Linear interpolate the Vertex data */
v1->x = ((v2->x-v1->x)*MAG) + v1->x;
v1->y = ((v2->y-v1->y)*MAG) + v1->y;
v1->z = ((v2->z-v1->z)*MAG) + v1->z;
/* Extract Color Components, Apply Linear Interpolation, then Pack it up */
BYTE a1 = (v1->argb & ALPHA)>>24;
BYTE r1 = (v1->argb & RED)>>16;
BYTE g1 = (v1->argb & GREEN)>>8;
BYTE b1 = (v1->argb & BLUE)>>0;
BYTE a2 = (v2->argb & ALPHA)>>24;
BYTE r2 = (v2->argb & RED)>>16;
BYTE g2 = (v2->argb & GREEN)>>8;
BYTE b2 = (v2->argb & BLUE)>>0;
BYTE a = ((a2-a1)*MAG)+ a1;
BYTE r = ((r2-r1)*MAG)+ r1;
BYTE g = ((g2-g1)*MAG)+ g1;
BYTE b = ((b2-b1)*MAG)+ b1;
v1->argb = ( (a<<24) | (r<<16) | (g<<8) | (b<<0) );
}
/* Wowsers, what a run this has been. Initially forgot to modify vertex flags */
inline int ClipZNearTriStrip( pvr_vertex_t *in, pvr_vertex_t *out, unsigned int n )
{
unsigned short int clip = 0, vertices_inside = 0;
unsigned int v = 0, i;
for( i=0; i<(n-2); i++ )
{
/* Compute clip codes for each vertex of triangle */
( in[i+0].z < CLIP_ZNEAR ) ? clip |= FIRST : ++vertices_inside;
( in[i+1].z < CLIP_ZNEAR ) ? clip |= SECOND : ++vertices_inside;
( in[i+2].z < CLIP_ZNEAR ) ? clip |= THIRD : ++vertices_inside;
switch(vertices_inside)
{
case 0: /* All Vertices are outside of clip plane */
break;
case 3: /* All Vertices are inside of clip plane */
VertexCopy( &in[i+0], &out[v+0] );
VertexCopy( &in[i+1], &out[v+1] );
VertexCopy( &in[i+2], &out[v+2] );
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
out[v+2].flags = PVR_CMD_VERTEX_EOL;
v+=3;
break;
case 1: /* 1 Vertex is inside of clip window, 2 are out */
VertexCopy( &in[i+0], &out[v+0] );
VertexCopy( &in[i+1], &out[v+1] );
VertexCopy( &in[i+2], &out[v+2] );
switch(clip)
{
case FIRST_TWO_OUT:
VertexClipZNear( &out[v], &out[v+2] );
VertexClipZNear( &out[v+1], &out[v+2] );
break;
case FIRST_AND_LAST_OUT:
VertexClipZNear( &out[v], &out[v+1] );
VertexClipZNear( &out[v+2], &out[v+1] );
break;
case LAST_TWO_OUT:
VertexClipZNear( &out[v+1], &out[v] );
VertexClipZNear( &out[v+2], &out[v] );
break;
}
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
out[v+2].flags = PVR_CMD_VERTEX_EOL;
v+=3;
break;
case 2: /* 2 Vertices are inside of clip window, 1 is out */
switch(clip)
{
case FIRST:
VertexCopy( &in[i+0], &out[v+0] );
VertexCopy( &in[i+1], &out[v+1] );
VertexClipZNear( &out[v+0], &out[v+1] );
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
v+=2;
VertexCopy( &in[i+0], &out[v+0] );
VertexCopy( &in[i+2], &out[v+1] );
VertexClipZNear( &out[v+0], &out[v+1] );
out[v+0].flags = PVR_CMD_VERTEX_EOL;
++v;
VertexCopy( &out[v-2], &out[v+0] );
VertexCopy( &out[v-1], &out[v+1] );
VertexCopy( &in[i+2] , &out[v+2] );
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
out[v+2].flags = PVR_CMD_VERTEX_EOL;
v+=3;
break;
case SECOND:
VertexCopy( &in[i+0], &out[v+0] );
VertexCopy( &in[i+1], &out[v+1] );
VertexClipZNear( &out[v+1], &out[v+0] );
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
v+=2;
VertexCopy( &in[i+2], &out[v+0] );
out[v+0].flags = PVR_CMD_VERTEX_EOL;
++v;
VertexCopy( &out[v-2], &out[v+0] );
VertexCopy( &out[v-1], &out[v+1] );
VertexCopy( &in[i+1] , &out[v+2] );
VertexClipZNear( &out[v+2], &out[v+1] );
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
out[v+2].flags = PVR_CMD_VERTEX_EOL;
v+=3;
break;
case THIRD:
VertexCopy( &in[i+0], &out[v+0] );
VertexCopy( &in[i+1], &out[v+1] );
VertexCopy( &in[i+2], &out[v+1] );
VertexClipZNear( &out[v+2], &out[v+1] );
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
out[v+2].flags = PVR_CMD_VERTEX_EOL;
v+=3;
VertexCopy( &out[v-3], &out[v+0] );
VertexCopy( &out[v-1], &out[v+1] );
out[v+0].flags = out[v+1].flags = PVR_CMD_VERTEX;
v+=2;
VertexCopy( &in[i+2], &out[v] );
VertexClipZNear( &out[v+0], &out[v-2] );
out[v+0].flags = PVR_CMD_VERTEX_EOL;
++v;
break;
}
break;
}
vertices_inside = clip = 0;
}
//printf("clip in/out: %i / %i\n", n, v);
return v;
}
- PH3NOM
- DC Developer
- Posts: 576
- Joined: Fri Jun 18, 2010 9:29 pm
- Has thanked: 0
- Been thanked: 5 times
Re: Reading texture from PVR back into SH-4 RAM
One last thought on that subject, sometimes it is not appropriate to clip every triangle of a mesh, for example high-poly models that exist within a small volume.
In that case, it is best to define a "bounding box" that defines the volume of that mesh, and cull against the bounding box, rather than clipping every triangle of the mesh.
I use the dot product of the camera->camera-destination vector and the bounding box position to determine if the mesh is behind the camera:
In that case, it is best to define a "bounding box" that defines the volume of that mesh, and cull against the bounding box, rather than clipping every triangle of the mesh.
I use the dot product of the camera->camera-destination vector and the bounding box position to determine if the mesh is behind the camera:
Code: Select all
/* DOT for a 3 float vector = FIPR with W components set to 1 */
#define dot(x1, y1, z1, x2, y2, z2) ({ \
register float __x __asm__("fr0") = (x1); \
register float __y __asm__("fr1") = (y1); \
register float __z __asm__("fr2") = (z1); \
register float __w __asm__("fr3"); \
register float __a __asm__("fr4") = (x2); \
register float __b __asm__("fr5") = (y2); \
register float __c __asm__("fr6") = (z2); \
register float __d __asm__("fr7"); \
__asm__ __volatile__( \
"fldi1 fr3\n" \
"fldi1 fr7\n" \
"fipr fv4,fv0" \
: "+f" (__w) \
: "f" (__x), "f" (__y), "f" (__z), "f" (__w), \
"f" (__a), "f" (__b), "f" (__c), "f" (__d) \
); \
__w; })
// Camera to Camera Destination ( camera from / to ) vector
vector3f cp = {campos[0]-camdst[0], campos[1]-camdst[1], campos[2]-camdst[2] };
// Dot product of Camera From-To Vector to Vertex Position
float dc = dot( cp[0], cp[1], cp[2],
campos[0]-vpos1[0], campos[1]-vpos1[1],campos[2]-vpos1[2]);
if(dc<0)
//Vertex "vpos1" is behind camera z plane
else
// Vertex "vpos1" is in front of camera z plane
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Thanks guys. Ah .. I should have checked the Parallax documentation more closely as I had assumed that it handled the Z clipping just like KGL. Thanks for the code sample - I had taken this for granted in KGL.
-
- DC Developer
- Posts: 105
- Joined: Sun Oct 04, 2009 11:13 am
- Has thanked: 2 times
- Been thanked: 90 times
Re: Reading texture from PVR back into SH-4 RAM
I have an old video of bloom on the Dreamcast (which I've never bothered to link to before) with my own modified version of the PVR driver (which is too messy to release at the moment, although I plan to at some point).
One thing that needs to be changed in the vanilla PVR driver for good render-to-texture support is changing how the driver starts renders. In the normal driver (I haven't looked at BlueCrab's changes), it only starts a render on a vblank, so each render-to-texture will wait until vblank and costs a multiple of one frame of time.
One trick to applying fullscreen bilinear render-to-texture results to the main framebuffer on the PVR is having the PVR twiddle the texture. Untwiddled textures, like a render-to-texture result, have half speed bilinear filtering, so there's a big difference in fillrate consumed if you first twiddle the texture. It's possible to have the PVR twiddle the texture by taking advantage of the fact that the process to untwiddle a texture (which the PVR does when drawing from a twiddled texture) can generate the twiddled version of the texture if you repeat it 3 times. With this trick, I was able to get my bloom demo to reach 60 FPS.
One thing that needs to be changed in the vanilla PVR driver for good render-to-texture support is changing how the driver starts renders. In the normal driver (I haven't looked at BlueCrab's changes), it only starts a render on a vblank, so each render-to-texture will wait until vblank and costs a multiple of one frame of time.
One trick to applying fullscreen bilinear render-to-texture results to the main framebuffer on the PVR is having the PVR twiddle the texture. Untwiddled textures, like a render-to-texture result, have half speed bilinear filtering, so there's a big difference in fillrate consumed if you first twiddle the texture. It's possible to have the PVR twiddle the texture by taking advantage of the fact that the process to untwiddle a texture (which the PVR does when drawing from a twiddled texture) can generate the twiddled version of the texture if you repeat it 3 times. With this trick, I was able to get my bloom demo to reach 60 FPS.
- MisterDave
- DCEmu Freak
- Posts: 58
- Joined: Mon Apr 08, 2013 1:16 pm
- Has thanked: 0
- Been thanked: 0
Re: Reading texture from PVR back into SH-4 RAM
Just a quick screenshot of what I have working so far. I'm looking at putting together a small demo of a player walking in and out of dark environments into a brightly lit area fairly soon and make the code public.
TapamN, thanks for the advice on the optimisations. So far the effect runs fairly quick with simple geometry, however, once I start ramping up the number of polys in the scene every millisecond is going to count so optimisation is something to bring in soon
TapamN, thanks for the advice on the optimisations. So far the effect runs fairly quick with simple geometry, however, once I start ramping up the number of polys in the scene every millisecond is going to count so optimisation is something to bring in soon