Jump to content

  • Log In with Google      Sign In   
  • Create Account

Create VB. stringValue Lock memcpy


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 AquaMacker   Members   -  Reputation: 255

Like
0Likes
Like

Posted 27 July 2013 - 09:10 AM

 
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 ?
 


Sponsor:

#2 shazen   Members   -  Reputation: 284

Like
1Likes
Like

Posted 27 July 2013 - 09:50 AM

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.



#3 unbird   Crossbones+   -  Reputation: 6010

Like
2Likes
Like

Posted 27 July 2013 - 10:33 AM

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.



#4 Norman Barrows   Crossbones+   -  Reputation: 2308

Like
2Likes
Like

Posted 27 July 2013 - 10:36 AM

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;
}
 
 
 
 

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

 

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

 

 


#5 Norman Barrows   Crossbones+   -  Reputation: 2308

Like
1Likes
Like

Posted 27 July 2013 - 10:42 AM

note that lock returns a null pointer to the VB's or IB's data, which you then use as the destination for the memcpy.


Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

 

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

 

 


#6 AquaMacker   Members   -  Reputation: 255

Like
0Likes
Like

Posted 27 July 2013 - 10:52 AM

parsing and lock, copy <- I already know.

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

No way ?


 



#7 unbird   Crossbones+   -  Reputation: 6010

Like
1Likes
Like

Posted 27 July 2013 - 10:57 AM

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, 27 July 2013 - 10:58 AM.


#8 Norman Barrows   Crossbones+   -  Reputation: 2308

Like
1Likes
Like

Posted 28 July 2013 - 03:55 PM


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, 28 July 2013 - 04:00 PM.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

 

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

 

 





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS