Sign in to follow this  
AquaMacker

Create VB. stringValue Lock memcpy

Recommended Posts

AquaMacker    255
 
Hi~~~
 
Let's look source...
 
string strValue = "1.0123f,3.1389f,5.0125f,11.0123f,33.1389f,55.0125f,111.0123f,333.1389f,555.0125f";
 
strValue has 9 float value.(3 vertex)
 
I hope to draw 1 tri.
 
I will make 1 mesh with "memcpy" NO Loop.
 
struct st
{
     D3DXVECTOR3 v;
};
 
st* pVerts = nullptr;
pMesh->LockVertexBuffer( 0, (void**)&pVerts );
::CopyMemory( pVerts, &strValue, sizeof(st) * 3 );
pMesh->UnlockVertexBuffer();
 
Is Right ?
 

Share this post


Link to post
Share on other sites
shazen    291

For each value in your string, say "1.0123f", requires 7 bytes (one for each character including the decimal). A real float of the value 1.0123f is represented with 4 bytes.

 

so, no, unfortunately.

Share this post


Link to post
Share on other sites
unbird    8336

You can't just memcpy that string to get your values into your vertex buffer (that would even be wrong if you took e.g. strValue.c_str()). You need so called parsing to first split that string (according to the commas) and then convert the parts to floats. I don't use C++ very often but IIRC one can split and parse using strstream and the >> operator. *google* Yep, that's a start.

Share this post


Link to post
Share on other sites
Norman Barrows    7179

what you're doing is trying to copy the "text representation" of a floating point number to a vertex buffer, not the value its self.

 

you'd need to convert the strings to floats first.

 

what you want to do is create a RAM buffer the same size as your VB, initialize it with your floating point values, then lock and copy the whole shebang to your vb:

 

float buffer[9]

 

buffer[0]=1.0123f

buffer[1]=3.1389f

buffer[2]=5.0125f

buffer[3]=11.0123f

buffer[4]=33.1389f

buffer[5]=55.0125f

buffer[6]=111.0123f

buffer[7]=333.1389f

buffer[8]=555.0125f

 

then lock and copy.

 

here's a source code snippet from CAVEMAN with the desired operations. 

 

it looks a little uglier than it is, because it does error checking for each step. 

 

by now, its proven stable code, so in the final release version, i may turn off the error checks.

 

 
 
 
void copy_ground_mesh2(int b,int c)    // b is chunk #.   c is tex pass #  (0-3).
{
void *p;
HRESULT a;
int d;                  // mesh #
d=b*4+c+157;          // calculate index of the mesh (VB/IB) to copy to
a=mesh[d].mesh2.vb->Lock(0,0,&p,D3DLOCK_DISCARD);
if (a != D3D_OK) 
    {
    Zshowscene();
    msg("lock ground mesh vb error");
    Zbeginscene();
    return;
    }
memcpy(p,system_vb,sizeof(Zvertexrec)*system_vb_numverts);
a=mesh[d].mesh2.vb->Unlock();
if (a != D3D_OK) 
    {
    Zshowscene();
    msg("unlock ground mesh vb error");
    Zbeginscene();
    return;
    }
a=mesh[d].mesh2.ib->Lock(0,0,&p,D3DLOCK_DISCARD);
if (a != D3D_OK) 
    {
    Zshowscene();
    msg("lock ground mesh ib error");
    Zbeginscene();
    return;
    }
memcpy(p,system_ib,sizeof(unsigned short int)*system_vb_numtris*3);
a=mesh[d].mesh2.ib->Unlock();
if (a != D3D_OK) 
    {
    Zshowscene();
    msg("unlock ground mesh ib error");
    Zbeginscene();
    return;
    }
mesh[d].mesh2.numfaces=system_vb_numtris;
mesh[d].mesh2.numverts=system_vb_numverts;
}
 
 
 
 

Share this post


Link to post
Share on other sites
unbird    8336

Nope, that "shortcut" you wanna take is, well, wrong, so no way around it. Can't make useful suggestions performance-wise either (since I don't use C++). You might look into C alternatives like strtok and atof or the boost libraries like in that link I found for comparisons.

 

Edit: Why you need to parse vertex data anyway ? If you wanna fast loading meshes you rather go binary.

Edited by unbird

Share this post


Link to post
Share on other sites
Norman Barrows    7179

parsing and lock, copy <- I already know.

But this method take long~~~~~ time.

No way ?
 

 

buffer[0]=1.0123f

buffer[1]=3.1389f

buffer[2]=5.0125f

buffer[3]=11.0123f

buffer[4]=33.1389f

buffer[5]=55.0125f

buffer[6]=111.0123f

buffer[7]=333.1389f

buffer[8]=555.0125f

 

once you have your vertices initialized, nothing is faster than memcpy(). lock is required in all cases.

 

converting hard coded strings to floats to init your vertices will be slower than simply hard coding the floats directly.

 

so the above code is essentially as fast as it gets.

 

you can also init the verts when you declare them, but all that does is move the init code (and its overhead) from your code to the app's startup init code stub. probably no speed savings.

 

but init speed is not what you should be worrying about. anything that gets the float values into your array of floats (which is a RAM memory image of the VB on the GPU) in a reasonable amount of time is ok. 

 

the problem is not that memcpy is slow. the problem is that dynamic buffers DRAW slow. MUCH slower than static. because the CPU must be able to update them quickly, they are stored in memory that the CPU can access relatively quickly, but which unfortunately the GPU can't read nearly as fast as the memory used for a static mesh. as a result, the performance hit for memcpy is low, at the cost of a performance hit in DrawIndexedPrimitive due to the slower memory used to store the dynamic VB/IB.

 

i actually switched from drawing a number of dynamic ground quad meshes per frame to assembling them into a big static mesh which changes much less frequently and draws much faster.

Edited by Norman Barrows

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this