• Advertisement
Sign in to follow this  

vector stuff

This topic is 4040 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to use a STL vector to fill a buffer with. I change from the normal array to vector but i still dont know how to set up the size of the buffer corectly.


struct Vertex
{
    float x, y, z;
    DWORD color;
};




        vector<Vertex> pointList(6);


	pointList[0].color = (D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ));
	pointList[0].x = 0.0f; pointList[0].y = 0.0f; pointList[0].z = 0.0;

	pointList[0].color = (D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ));
	pointList[0].x = 0.5f; pointList[0].y = 0.0f; pointList[0].z = 0.0;

	pointList[0].color = (D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ));
	pointList[0].x = -0.5f; pointList[0].y = 0.0f; pointList[0].z = 0.0;

	pointList[0].color = (D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ));
	pointList[0].x = 0.0f; pointList[0].y = -0.5f; pointList[0].z = 0.0;

	pointList[0].color = (D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ));
	pointList[0].x = 0.0f; pointList[0].y = 0.5f; pointList[0].z = 0.0;




//Now the buffer:
//Here I dont know how to size the buffer corectly acording to the vector size.

LPDIRECT3DVERTEXBUFFER9 g_pPointList_VB     = NULL;

Vertex *pVertices = NULL;

MyBuffer.Device->CreateVertexBuffer( 6*sizeof(pointList), 0, D3DFVF_MY_VERTEX,
									                                      D3DPOOL_DEFAULT, &g_pPointList_VB, NULL );


    pVertices = NULL;
    g_pPointList_VB->Lock( 0, sizeof(pointList), (void**)&pVertices, 0 );
    memcpy( pVertices, &pointList, sizeof(pointList.size()) );
    g_pPointList_VB->Unlock();

Mybuffer is just a LPDIRECT3DVERTEXBUFFER9 buffer;



Thnks

Share this post


Link to post
Share on other sites
Advertisement
Untested:
struct Vertex
{
float x, y, z;
DWORD color;
};

vector<Vertex> pointList(6);

pointList[0].color = (D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ));
pointList[0].x = 0.0f; pointList[0].y = 0.0f; pointList[0].z = 0.0;

pointList[1].color = (D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ));
pointList[1].x = 0.5f; pointList[1].y = 0.0f; pointList[1].z = 0.0;

pointList[2].color = (D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ));
pointList[2].x = -0.5f; pointList[2].y = 0.0f; pointList[2].z = 0.0;

pointList[3].color = (D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ));
pointList[3].x = 0.0f; pointList[3].y = -0.5f; pointList[3].z = 0.0;

pointList[4].color = (D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ));
pointList[4].x = 0.0f; pointList[4].y = 0.5f; pointList[4].z = 0.0;

// pointList[5]?

//Now the buffer:
//Here I dont know how to size the buffer corectly acording to the vector size.

LPDIRECT3DVERTEXBUFFER9 g_pPointList_VB = NULL;

Vertex *pVertices = NULL;

MyBuffer.Device->CreateVertexBuffer( pointList.size() * sizeof(pointList::value_type), 0, D3DFVF_MY_VERTEX, D3DPOOL_DEFAULT, &g_pPointList_VB, NULL );

pVertices = NULL;
g_pPointList_VB->Lock( 0, sizeof(pointList::value_type), (void**)&pVertices, 0 );
// c++ provides better (i.e. typesafe) functions for copying
std::copy(pointList.begin(), pointList.end(), pVertices);

g_pPointList_VB->Unlock();
You should probably also consider giving your Vertex struct a constructor and using the push_back member function of vector. Oh, and please read this.

Σnigma

Share this post


Link to post
Share on other sites
for a declaration of:
vector<Vertex> pointList

pointList::value_type would return Vertex

it makes life easier, since there is less code to change if you ever change the type in the vector
declaration, you dont have to go changing it everywhere in the code.

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran
for a declaration of:
vector<Vertex> pointList

pointList::value_type would return Vertex

it makes life easier, since there is less code to change if you ever change the type in the vector
declaration, you dont have to go changing it everywhere in the code.



''unknown-type'': illegal sizeof operand. I cant use pointList::value_type

'value_type' : undeclared identifier

ITS anything im missing ? :(

Share this post


Link to post
Share on other sites
Sorry, my mistake. I somehow got confused and thought pointList was a typedef as well as a variable. If you had, for example:
typedef std::vector< Vertex > PointList;
PointList pointList;
Then you could use PointList::value_type to get the type of the objects contained within the vector. This means that if you change the contained type in the typedef the changes propogate through to the rest of your code automatically, which is a good thing™.

It would probably be a good idea for you to introduce such a typedef, but in it's absence you can use it's equivalent std::vector< Vertex >::value_type, or simply Vertex where I'd erroneously put pointList::value_type.

Σnigma

Share this post


Link to post
Share on other sites


MyBuffer.Device->CreateVertexBuffer( pointList.size() * sizeof(vector<Vertex >::value_type), 0, D3DFVF_MY_VERTEX,D3DPOOL_DEFAULT, &g_pPointList_VB,NULL);


pVertices = NULL;


g_pPointList_VB->Lock( 0, sizeof(vector<Vertex>::value_type), (void**)&pVertices, 0 );

memcpy( pVertices, &pointList, sizeof(vector<Vertex>::value_type));

g_pPointList_VB->Unlock();


I still see only one point !! :(


Share this post


Link to post
Share on other sites
try multiplying all the sizeof(...) by vector.size() for whatever you call your vector

- Do this in the Lock and in the memcpy

[EDIT]
sizeof(vector<Vertex>::value_type) is worthless (you'd better use sizeof(Vertex)) or alternatively typedef vector<Vertex> to something you're comfortable with and use vertexVector::value_type for example.

Share this post


Link to post
Share on other sites
Quote:
Original post by arithma
try multiplying all the sizeof(...) by vector.size() for whatever you call your vector

- Do this in the Lock and in the memcpy


I did now i dont see anything (not even that litle point it was before)

And btw , thats a strange behavior with VS2005 C++ Pro. If i compile the project I see a dot, then i make some modifications and i dont see anything, when i undo, instead of dot again I dont see anything or i see 3 points instead of one (even with the same code). Is this random bulding ? Sometimes the IDE forgets to build and just runs the last exe ? How can I stop that ?


MyBuffer.Device->CreateVertexBuffer(pointList.size() * sizeof(Vertex), 0, D3DFVF_MY_VERTEX,D3DPOOL_DEFAULT, &g_pPointList_VB,NULL);
pVertices = NULL;


g_pPointList_VB->Lock( 0,pointList.size() * sizeof(Vertex), (void**)&pVertices, 0 );

memcpy( pVertices, &pointList,pointList.size() * sizeof(Vertex) );

g_pPointList_VB->Unlock();



[Edited by - Azzazelus on January 26, 2007 3:47:55 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Azzazelus
Should I go back to the simple array ?
Nah, there's almost always a way to make a vector work in a given situation, and it's almost always better to use a vector rather than a raw (dynamic) array where possible.

Taking a quick look at your code, I notice this:
memcpy( pVertices, &pointList,pointList.size() * sizeof(Vertex) );
&pointList returns the address of the vector object itself, not the address of the data that the vector holds. In other words, you're copying more or less random data (such as the values of vector member variables used to track size and other attributes) into your vertex buffer. Try this instead:
memcpy( pVertices, &pointList.front(),pointList.size() * sizeof(Vertex) );
There may be other problems as well, but I just thought I'd point this out since I happened to notice it.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Quote:
Original post by Azzazelus
Should I go back to the simple array ?
Nah, there's almost always a way to make a vector work in a given situation, and it's almost always better to use a vector rather than a raw (dynamic) array where possible.

Taking a quick look at your code, I notice this:
memcpy( pVertices, &pointList,pointList.size() * sizeof(Vertex) );
&pointList returns the address of the vector object itself, not the address of the data that the vector holds. In other words, you're copying more or less random data (such as the values of vector member variables used to track size and other attributes) into your vertex buffer. Try this instead:
memcpy( pVertices, &pointList.front(),pointList.size() * sizeof(Vertex) );
There may be other problems as well, but I just thought I'd point this out since I happened to notice it.


Yees, THANK YOU, finally. That was the problem. I was about to quit because of my stupidity.

Share this post


Link to post
Share on other sites
Quote:
Original post by Azzazelus
Quote:
Original post by jyk
Quote:
Original post by Azzazelus
Should I go back to the simple array ?
Nah, there's almost always a way to make a vector work in a given situation, and it's almost always better to use a vector rather than a raw (dynamic) array where possible.

Taking a quick look at your code, I notice this:
memcpy( pVertices, &pointList,pointList.size() * sizeof(Vertex) );
&pointList returns the address of the vector object itself, not the address of the data that the vector holds. In other words, you're copying more or less random data (such as the values of vector member variables used to track size and other attributes) into your vertex buffer. Try this instead:
memcpy( pVertices, &pointList.front(),pointList.size() * sizeof(Vertex) );
There may be other problems as well, but I just thought I'd point this out since I happened to notice it.


Yees, THANK YOU, finally. That was the problem. I was about to quit because of my stupidity.


Ahem.

Quote:
from Enigma's code
// c++ provides better (i.e. typesafe) functions for copying
std::copy(pointList.begin(), pointList.end(), pVertices);


Nice and simple, and you never have to worry about sizeof() anything. Plus you could change your container to a std::list or std::deque later (although you probably won't want to in this particular case) and it would work just the same.

Had you managed to use std::copy incorrectly (specifying pointList instead of pointList.begin()), the compiler would have caught it. Of course, there are ways to write it wrongly that will compile, but they don't look as natural as the correct syntax; whereas memcpy() requires you to work with weird &'s to get pointers.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by Azzazelus
Quote:
Original post by jyk
Quote:
Original post by Azzazelus
Should I go back to the simple array ?
Nah, there's almost always a way to make a vector work in a given situation, and it's almost always better to use a vector rather than a raw (dynamic) array where possible.

Taking a quick look at your code, I notice this:
memcpy( pVertices, &pointList,pointList.size() * sizeof(Vertex) );
&pointList returns the address of the vector object itself, not the address of the data that the vector holds. In other words, you're copying more or less random data (such as the values of vector member variables used to track size and other attributes) into your vertex buffer. Try this instead:
memcpy( pVertices, &pointList.front(),pointList.size() * sizeof(Vertex) );
There may be other problems as well, but I just thought I'd point this out since I happened to notice it.


Yees, THANK YOU, finally. That was the problem. I was about to quit because of my stupidity.


Ahem.

Quote:
from Enigma's code
// c++ provides better (i.e. typesafe) functions for copying
std::copy(pointList.begin(), pointList.end(), pVertices);


Nice and simple, and you never have to worry about sizeof() anything. Plus you could change your container to a std::list or std::deque later (although you probably won't want to in this particular case) and it would work just the same.

Had you managed to use std::copy incorrectly (specifying pointList instead of pointList.begin()), the compiler would have caught it. Of course, there are ways to write it wrongly that will compile, but they don't look as natural as the correct syntax; whereas memcpy() requires you to work with weird &'s to get pointers.
The use of std::copy() had already been suggested when I made my post, so I assumed the OP just wanted to know why his current code wasn't working.

Also, I think it can sometimes be useful to answer a question or address a problem in 'stages'. The &pointList error was present from the original post. Enigma correctly replaced the call to memcpy() with std::copy() in his example; however, had that been the end of it, the OP would have been left with a fundamental misunderstanding that was never addressed.

I'm not one of those people who thinks you need to write your own linked list class before allowing yourself to use std::list, but IMHO one should probably understand the difference between &v and &v.front() before making extensive use of the algorithms from the standard library. The distinction is just too important to be glossed over.

That said, I probably should have pointed out the &listPoint error, and then reiterated that std::copy() should be used instead, despite the fact that it had already been covered. (You'd think I would have learned by now to cover all my bases when posting in For Beginners :)

Share this post


Link to post
Share on other sites
You have some interesting points about teaching, there. [smile] I'll be sure to think about that in the future.

On another note... you, jouley, jpetrie, others I'm forgetting for sure... what's with all the knowledgable j-people? O_O

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement