Find the color of a vertex?
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Find the color of a vertex?
Is it possible to retrieve the color of a specific vertex? The base color, determined by the material, without any light influence?
I got the x,y float2 texture coordinates, found by retrieving VES_TEXTURE_COORDINATES alright, but how do I perform the texture lookup?
I got the x,y float2 texture coordinates, found by retrieving VES_TEXTURE_COORDINATES alright, but how do I perform the texture lookup?
-
- Kobold
- Posts: 30
- Joined: Sun Nov 09, 2008 5:16 am
- Location: Shanghai, China
Re: Find the color of a vertex?
You already have the texture-coords right? Then just lock the texture and you can get the pixel data~
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
Could you point me in the right direction? How do I lock the texture and get the pixel data? Which class allows me to do so?
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
*bump*
Could anyone tell me exactly how to do a texture lookup in Ogre3D?
How do I lock the texture and get the pixel data?
Could anyone tell me exactly how to do a texture lookup in Ogre3D?
How do I lock the texture and get the pixel data?
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
Sorry to bump again, but I'm still a bit stuck on this.
- madmarx
- OGRE Expert User
- Posts: 1671
- Joined: Mon Jan 21, 2008 10:26 pm
- x 50
Re: Find the color of a vertex?
There is an example of locking a texture, accessing the pixel data of the texture in the ogre demo called "dyn_tex" (for "dynamic texture").
From my head : get the texture from the texture manager, then ask for a pixel buffer (I can't remember if I had to create a pixel buffer to receive the texture last time I used this feature), and then call lock() on the pixel buffer. The lock will give you a pointer to the data of the texture (be careful of the data format anyway, not everything is RGB24).
Hope this help!
Good luck!
EDIT:
in OgreTexture :
HardwarePixelBufferSharedPtr getBuffer (size_t face=0, size_t mipmap=0)=0
then T * get () const
then virtual void * lock (size_t offset, size_t length, LockOptions options)
then unlock.
For example (NEVER write it like that of course !).
TextureManager::getSingletonPtr()->getByName("myTex")->getBuffer().get()->lock(size of the texture, ...);
From my head : get the texture from the texture manager, then ask for a pixel buffer (I can't remember if I had to create a pixel buffer to receive the texture last time I used this feature), and then call lock() on the pixel buffer. The lock will give you a pointer to the data of the texture (be careful of the data format anyway, not everything is RGB24).
Hope this help!
Good luck!
EDIT:
in OgreTexture :
HardwarePixelBufferSharedPtr getBuffer (size_t face=0, size_t mipmap=0)=0
then T * get () const
then virtual void * lock (size_t offset, size_t length, LockOptions options)
then unlock.
For example (NEVER write it like that of course !).
TextureManager::getSingletonPtr()->getByName("myTex")->getBuffer().get()->lock(size of the texture, ...);
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
It's been a while since my post. I've been working on other stuff and I couldn't return to this before.
I found the dynamic texture example at Wiki - Creating_dynamic_textures. This seems to be what you meant.
Also, I can use vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES) to find the texture coordinates alright.
However, how do I get a TexturePtr to the texture to use? For my specific submesh..
I found the dynamic texture example at Wiki - Creating_dynamic_textures. This seems to be what you meant.
Also, I can use vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES) to find the texture coordinates alright.
However, how do I get a TexturePtr to the texture to use? For my specific submesh..
- Kencho
- OGRE Retired Moderator
- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
- Contact:
Re: Find the color of a vertex?
TextureManager::getByName() is one way. TextureUnitState::_getTexturePtr() is other.
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
Ok, this is how I'm planning to do it, do you guys spot any problems with it?
I assume that pDest contains all pixels.
However, how can I retrieve the color for the current vertex? Tex.x and tex.y contains floats from a wide range (including negative floats), so I assume I'm doing something wrong.
Code: Select all
SubMesh* submesh; // Initialized elsewhere
Ogre::VertexData* vertex_data = submesh->useSharedVertices ? data.mesh->sharedVertexData : submesh->vertexData;
if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
{
if(submesh->useSharedVertices) {
added_shared = true;
shared_offset = current_offset;
}
const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
const Ogre::VertexElement* norElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL);
const Ogre::VertexElement* texElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES, 0);
Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
float* pReal;
float* nReal;
float* tReal;
for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) {
posElem->baseVertexPointerToElement(vertex, &pReal);
norElem->baseVertexPointerToElement(vertex, &nReal);
texElem->baseVertexPointerToElement(vertex, &tReal);
// What I'm trying to do here is find the (base) color of the current vertex
Pass* pass = ((MaterialPtr) MaterialManager::getSingleton().getByName(submesh->getMaterialName()))->getTechnique(0)->getPass(0);
if (pass->getNumTextureUnitStates() > 0) {
TextureUnitState* texunit = pass->getTextureUnitStateIterator().getNext();
TexturePtr texture = texunit->_getTexturePtr();
// Get the pixel buffer
HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
// Lock the pixel buffer and get a pixel box
pixelBuffer->lock(HardwareBuffer::HBL_DISCARD);
const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
int width = pixelBox.getWidth();
int height = pixelBox.getHeight();
std::cout << "width=" << width << " height=" << height << "\n";
uint8* pDest = static_cast<uint8*>(pixelBox.data);
// pDest contains our RGBA data (considering color format)
pixelBuffer->unlock();
}
}
}
However, how can I retrieve the color for the current vertex? Tex.x and tex.y contains floats from a wide range (including negative floats), so I assume I'm doing something wrong.
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
*bump*
How do I use the texture_coordinates properly? What's the correct range (from 0.0f to 1.0f?)?
This holds the texture_coordinates, but in my current model this can range from -10.0f to 110.0f, I can't really use it properly.
How do I use the texture_coordinates properly? What's the correct range (from 0.0f to 1.0f?)?
Code: Select all
uint8* pDest = static_cast<uint8*>(pixelBox.data);
- Kencho
- OGRE Retired Moderator
- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
- Contact:
Re: Find the color of a vertex?
I'm afraid you're mixing concepts here...
First of all, pixel boxes are "raw" images. The "uint8" data type should hint that the possible values are integers in the range [0, 255]. Then, they only store colour information, not texture coordinates.
Now, assuming you meant that you want to obtain the texture colour at positions outside the [0, 1] range, it all depends on the texture addressing mode. If you use clamping, then values below 0 are the values at 0 and above 1 are the values at 1. Wrapping results in repeating the whole cycle of [0, 1] (as with the modulus of a division), and so on.
First of all, pixel boxes are "raw" images. The "uint8" data type should hint that the possible values are integers in the range [0, 255]. Then, they only store colour information, not texture coordinates.
Now, assuming you meant that you want to obtain the texture colour at positions outside the [0, 1] range, it all depends on the texture addressing mode. If you use clamping, then values below 0 are the values at 0 and above 1 are the values at 1. Wrapping results in repeating the whole cycle of [0, 1] (as with the modulus of a division), and so on.
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
Oh sorry, I'm indeed mixing things up. I posted too soon without thinking right.
The pixelbox indeed holds the raw texture.
In my case tReal[0] and tReal[1] hold the x,y texture coordinates. And these values range from -10.0f to 110.0f in this case.
I'm wondering how to use these correctly. Must I clamp them to the range [0.0 .. 1.0]?
The pixelbox indeed holds the raw texture.
In my case tReal[0] and tReal[1] hold the x,y texture coordinates. And these values range from -10.0f to 110.0f in this case.
I'm wondering how to use these correctly. Must I clamp them to the range [0.0 .. 1.0]?
- Kencho
- OGRE Retired Moderator
- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
- Contact:
Re: Find the color of a vertex?
That's up to you. Sometimes you will want to clamp it, and sometimes you'll want to wrap it. Would you tile that texture? If so, wrap it. Otherwise, clamp it
-
- Greenskin
- Posts: 103
- Joined: Tue Feb 27, 2007 2:55 pm
Re: Find the color of a vertex?
I just can't seem to get any vertex color data using the above code.
Could any of you gurus please check if I'm doing anything wrong?
(Both using clamping and wrapping I'm not getting any color data)
Could any of you gurus please check if I'm doing anything wrong?
(Both using clamping and wrapping I'm not getting any color data)
-
- Kobold
- Posts: 30
- Joined: Sun Nov 09, 2008 5:16 am
- Location: Shanghai, China
Re: Find the color of a vertex?
You tried to get tex_coord data from the same vertex buffer source that stores the position data. However they may be of different sources.
Btw don't do lock/unlock in the vertex loop.
Btw don't do lock/unlock in the vertex loop.
-
- Kobold
- Posts: 30
- Joined: Sun Nov 09, 2008 5:16 am
- Location: Shanghai, China
Re: Find the color of a vertex?
Just have a look at my comment.
Code: Select all
SubMesh* submesh; // Initialized elsewhere
Ogre::VertexData* vertex_data = submesh->useSharedVertices ? data.mesh->sharedVertexData : submesh->vertexData;
if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
{
if(submesh->useSharedVertices) {
added_shared = true;
shared_offset = current_offset;
}
const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
const Ogre::VertexElement* norElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL);
/* the texElem may be of a different source from the posElem. You could try getSource to check it */
const Ogre::VertexElement* texElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES, 0);
/* the vbuf is the buffer for the position data, you can pass in texElem->getSource() as the param to get tex_coord data */
Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
float* pReal;
float* nReal;
float* tReal;
for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) {
posElem->baseVertexPointerToElement(vertex, &pReal);
norElem->baseVertexPointerToElement(vertex, &nReal);
/* after you get the tReal for the texture UV data, you could use it to get the color info from the texture( pixel box )
usually the UV data should be two floats of the range [0.0, 1.0] */
texElem->baseVertexPointerToElement(vertex, &tReal);
/* don't do lock/unlock here. move it out of the loop. */
// What I'm trying to do here is find the (base) color of the current vertex
Pass* pass = ((MaterialPtr) MaterialManager::getSingleton().getByName(submesh->getMaterialName()))->getTechnique(0)->getPass(0);
if (pass->getNumTextureUnitStates() > 0) {
TextureUnitState* texunit = pass->getTextureUnitStateIterator().getNext();
TexturePtr texture = texunit->_getTexturePtr();
// Get the pixel buffer
HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
/* don't use HBL_DISCARD since you want to read but not change the texture data. Try HBL_READ_ONLY */
// Lock the pixel buffer and get a pixel box
pixelBuffer->lock(HardwareBuffer::HBL_DISCARD);
const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
int width = pixelBox.getWidth();
int height = pixelBox.getHeight();
std::cout << "width=" << width << " height=" << height << "\n";
/* you may need to check the format for the pixel box. uint8 is not always the case. */
uint8* pDest = static_cast<uint8*>(pixelBox.data);
// pDest contains our RGBA data (considering color format)
pixelBuffer->unlock();
}
}
}