Cocos2d CCDrawNode fill with color - cocos2d-iphone

I am using cocos2d to ccdrawnode.DrawLineList method to create diamong shape. I am using the following code
`var diamond = new CCDrawNode();
diamond.DrawLineList(new CCV3F_C4B[] {
new CCV3F_C4B(new CCPoint(0,height/2), fillColor),
new CCV3F_C4B(new CCPoint(height/2,height), fillColor),
new CCV3F_C4B(new CCPoint(height/2,height), fillColor),
new CCV3F_C4B(new CCPoint(height,height/2), fillColor),
new CCV3F_C4B(new CCPoint(height,height/2), fillColor),
new CCV3F_C4B(new CCPoint(height/2,0), fillColor),
new CCV3F_C4B(new CCPoint(height/2,0), fillColor),
new CCV3F_C4B(new CCPoint(0,height/2), fillColor)
});`
the diamond is drawn but the diamond is not filled with the color only the border is colored. How to fill the diamond shape with specific color in cocos2d

Related

Qt3D - Instance rendering of 2 squares. PrimitiveType? InstanceCount?

I'd like to display on the screen 2 squares using instance rendering.
The problem is :
When I draw 2 squares, they are connected. I can't draw multiple separate square.
I know it has to do with PrimitiveType : i'm using Qt3DRender::QGeometryRenderer::LineLoop or Qt3DRender::QGeometryRenderer::TriangleFan but is there a way to tell Qt to separate my data buffer in multiple instances ? so that the PrimitiveType apply on each instances and not all the vertices.
I got a function that create shapes :
Qt3DCore::QEntity* SceneBuilder::createShapeInstancing(const QList<QVector3D> & listVertices, int nbPointGeometry, const QColor color, Qt3DCore::QEntity * rootEntity)
{
// Material
Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial(rootEntity);
material->setAmbient(color);
// Custom entity
Qt3DCore::QEntity *customMeshEntity = new Qt3DCore::QEntity(rootEntity);
// Custom Mesh
Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer(rootEntity);
Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(customMeshRenderer);
Qt3DRender::QBuffer *vertexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);
int nbPointGeometry = nbPoint;
QByteArray vertexBufferData;
vertexBufferData.resize(listVertices.size() * nbPointGeometry * sizeof(QVector3D));
QVector3D *posData = reinterpret_cast<QVector3D *>(vertexBufferData.data());
QList<QVector3D>::const_iterator it;
for (it = listVertices.begin(); it != listVertices.end(); it++)
{
*posData = *it;
++posData;
}
vertexDataBuffer->setData(vertexBufferData);
//Attributes
Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute();
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
positionAttribute->setBuffer(vertexDataBuffer);
positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
positionAttribute->setVertexSize(3);
positionAttribute->setByteOffset(0);
positionAttribute->setByteStride((0 + 3) * sizeof(float));
positionAttribute->setCount(listVertices.size());
//positionAttribute->setDivisor(1);
customGeometry->addAttribute(positionAttribute);
customMeshRenderer->setGeometry(customGeometry);
//customMeshRenderer->setInstanceCount(listVertices.size()/nbPoint);
if (nbPointGeometry == 1)
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points);
else if (nbPointGeometry == 2)
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
else if (nbPointGeometry == 3)
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
else
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop);
customMeshEntity->addComponent(customMeshRenderer);
customMeshEntity->addComponent(material);
return customMeshEntity;
}
When i call this function, i put my 2 squares inside the listVertices variables. So that all my squares are display in one draw call.
But the shapes are one way or another connected. Is there a way to remove that ? I'm not using InstanceCount or Divisor but i don't know how it works. I made some tests with it but nothing worked
Actually, I just found an example of instanced rendering here.
They subclassed QSphereGeometry and performed the instanced rendering in a shader. You could create a RectangleGeometry which holds the vertices for one triangle and equip it with the same functionality as the InstancedGeometry in the example.
Result:

QT3D with C ++ and rotation

I hope someone can help me with this problem. I am new to working with QT3D and I need to make a Qt3D application using QT C++ for a task, the problem I have is that I need to rotate the figure from a specific point but it always rotates from the center point. How can I specify that the rotation is made from one of the pivots in the figure? I need it to be able to simulate the movement of a pendulum. Please help someone who tells me how I can solve this problem, here is my code.
void window::paint(){
arm1 = new Qt3DExtras::QCylinderMesh();
arm1->setRadius(0.5);
arm1->setLength(3);
arm1Transform = new Qt3DCore::QTransform();
arm1Transform->setTranslation(QVector3D(-3, 3, 0));
arm1Transform->setScale(1.5f);
Qt3DExtras::QPhongMaterial *arm1Material = new Qt3DExtras::QPhongMaterial();
arm1Material->setDiffuse(Qt::red);
arm1Entity = new Qt3DCore::QEntity(rootEntity);
arm1Entity->addComponent(arm1);
arm1Entity->addComponent(arm1Material);
arm1Entity->addComponent(arm1Transform);
}
void window::on_pushButton_clicked(){
arm1Transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1.0f, 0.0f, 0.0f), angle++));
}
Thanks in advance.
You can make arm1Entity to be a child of a new QEntity. This new QEntity will be positioned at the point where you want to rotate from. So if you rotate the new QEntity, his child arm1Entity will rotate from the new QEntity's position.
EDIT code (not tested):
void window::paint(){
arm1PivotEntity = new Qt3DCore::QEntity(rootEntity);
arm1PivotTransform = new Qt3DCore::QTransform(arm1PivotEntity);
arm1PivotTransform->setTranslation(QVector3D(/*desired pivot position*/));
arm1PivotEntity->addComponent(arm1PivotTransform);
arm1 = new Qt3DExtras::QCylinderMesh();
arm1->setRadius(0.5);
arm1->setLength(3);
arm1Transform = new Qt3DCore::QTransform();
// as arm1 is now child of arm1 pivot, you need to set the relative position
arm1Transform->setTranslation(QVector3D(/*relative position to arm1pivot position*/));
arm1Transform->setScale(1.5f);
Qt3DExtras::QPhongMaterial *arm1Material = new Qt3DExtras::QPhongMaterial();
arm1Material->setDiffuse(Qt::red);
// made arm1 child of arm1pivot so it will inherits its rotation
arm1Entity = new Qt3DCore::QEntity(arm1PivotEntity);
arm1Entity->addComponent(arm1);
arm1Entity->addComponent(arm1Material);
arm1Entity->addComponent(arm1Transform);
}
void window::on_pushButton_clicked(){
arm1PivotTransform->setRotation(angle++));
}

Qt 3D: How to draw a cube with different textures on each face?

I'm new to Qt 3D (C++), and while I'm training with my first 3D app, I couldn't achieve the following:
Creating a cube with 6 different textures on each face... Until now, this is what I've tried:
// Cuboid shape data
Qt3DExtras::QCuboidMesh *cuboid = new Qt3DExtras::QCuboidMesh();
// CuboidMesh Transform
Qt3DCore::QTransform *cuboidTransform = new Qt3DCore::QTransform();
cuboidTransform->setScale(2.0f);
Qt3DExtras::QTextureMaterial *textureMaterial = new Qt3DExtras::QTextureMaterial();
Qt3DRender::QTextureCubeMap *cubMap = new Qt3DRender::QTextureCubeMap();
Qt3DRender::QTextureImage *f1 = new Qt3DRender::QTextureImage();
Qt3DRender::QTextureImage *f2 = new Qt3DRender::QTextureImage();
Qt3DRender::QTextureImage *f3 = new Qt3DRender::QTextureImage();
Qt3DRender::QTextureImage *f4 = new Qt3DRender::QTextureImage();
Qt3DRender::QTextureImage *f5 = new Qt3DRender::QTextureImage();
Qt3DRender::QTextureImage *f6 = new Qt3DRender::QTextureImage();
f1->setSource(QUrl("qrc:/rc/images/cubemap1.png"));
f1->setFace(Qt3DRender::QAbstractTexture::CubeMapNegativeX);
f2->setSource(QUrl("qrc:/rc/images/cubemap2.png"));
f2->setFace(Qt3DRender::QAbstractTexture::CubeMapPositiveX);
f3->setSource(QUrl("qrc:/rc/images/cubemap3.png"));
f3->setFace(Qt3DRender::QAbstractTexture::CubeMapNegativeY);
f4->setSource(QUrl("qrc:/rc/images/cubemap4.png"));
f4->setFace(Qt3DRender::QAbstractTexture::CubeMapPositiveY);
f5->setSource(QUrl("qrc:/rc/images/cubemap5.png"));
f5->setFace(Qt3DRender::QAbstractTexture::CubeMapNegativeZ);
f6->setSource(QUrl("qrc:/rc/images/cubemap6.png"));
f6->setFace(Qt3DRender::QAbstractTexture::CubeMapPositiveZ);
cubMap->addTextureImage(f1);
cubMap->addTextureImage(f2);
cubMap->addTextureImage(f3);
cubMap->addTextureImage(f4);
cubMap->addTextureImage(f5);
cubMap->addTextureImage(f6);
textureMaterial->setTexture(cubMap);
//Cuboid
m_cuboidEntity = new Qt3DCore::QEntity(m_rootEntity);
m_cuboidEntity->addComponent(cuboid);
m_cuboidEntity->addComponent(textureMaterial);
m_cuboidEntity->addComponent(cuboidTransform);
But it gives me a black cube.
I've googled for an example, but all I find is written in OpenGl, which I'm not familiar with. I believe it's possible using Qt C++ Classes only.
I would appreciate your help.
This could be related to back face culling.
could you set the following in your renderer?
activeFrameGraph: ForwardRenderer {
...
frustumCulling: false
}
When using Skybox (which is basically a CuboidMesh with different images on it), this is mandatory. Could be needed here too.
Try using f1->setSource(QUrl::fromLocalFile("...")); instead f1->setSource(QUrl("..."));, etc.
And remember about Status

Cocos2d Box2d - assign generic userData to bodyDef

Most examples I see of assigning userData go something like this:
CCSprite *sprite = [CCSprite spriteWithFile:#"whatever.png" rect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
sprite.tag = kWallTag;
[self addChild:sprite];
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
groundBodyDef.userData = (__bridge void*)sprite;
That's fine if you're using a sprite. But in my case, I don't want to create a sprite because I just want to test collisions with the screen edges. I could create a sprite the size of the screen with just a border but I don't want to use that much texture memory just for detecting walls. So my question is how to assign the kWallTag to the groundBodyDef, without assigning it a sprite. And how would I retrieve the tag value?
I've answered the first part:
GenericUserData *usrData = (GenericUserData*)malloc(sizeof(GenericUserData));
usrData->tag = kWallTag;
groundBodyDef.userData = usrData;
But I don't know how to test for the generic data:
if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
CCSprite *spriteA = (__bridge CCSprite *) bodyA->GetUserData();
CCSprite *spriteB = (__bridge CCSprite *) bodyB->GetUserData();
How do I test for generic user data instead of just assuming that it's a CCSprite?

How to detect all the visible sprites in a layer?

Can I detect all the visible sprites in a layer in order to use them.
Here i assume u r using Box2d with cocos2d
//here create ccsprite and add them to ur scene
while create body with bodydef
bodydef.userData=ccspriteobject;
for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//if the userdata is not null then ur sprite
CCSprite *actor = (CCSprite*)b->GetUserData();
Here is a small function you can use:
-(void)getAllChildren {
CCArray *childrenArray = [self children];
for(CCNode *myNode in childrenArray)
{
}
}