iOS cocos2d v3 convert openGL code to CCDrawNode - ios

I have a visit method for the dot indicator of my Sliding Menu Grid.
- (void) visit
{
[super visit];//< Will draw after glPopScene.
BOOL showPagesIndicator = YES;
ccColor4B pagesIndicatorNormalColor_ = ccc4([sud integerForKey:key_int_r], [sud integerForKey:key_int_g], [sud integerForKey:key_int_b], 255);
ccColor4B pagesIndicatorSelectedColor_ = ccc4(255, 255, 255, 255);
if (showPagesIndicator)
{
int totalScreens = iPageCount;
// Prepare Points Array
CGFloat n = (CGFloat)totalScreens; //< Total points count in CGFloat.
CGFloat pY = pageIndicatorPosition.y; //< Points y-coord in parent coord sys.
CGFloat d = may_double(16.0f); //< Distance between points.
CGPoint points[totalScreens];
for (int i=0; i < totalScreens; ++i)
{
CGFloat pX = pageIndicatorPosition.x + d * ( (CGFloat)i - 0.5f*(n-1.0f) );
points[i] = ccp (pX, pY);
}
// Set GL Values
#if COCOS2D_VERSION >= 0x00020000
// ccGLEnable(CC_GL_BLEND);
ccPointSize( may_double(6.0 * CC_CONTENT_SCALE_FACTOR()) );
#define DRAW_4B_FUNC ccDrawColor4B
#else
glEnable(GL_POINT_SMOOTH);
GLboolean blendWasEnabled = glIsEnabled( GL_BLEND );
glEnable(GL_BLEND);
// save the old blending functions
int blend_src = 0;
int blend_dst = 0;
glGetIntegerv( GL_BLEND_SRC, &blend_src );
glGetIntegerv( GL_BLEND_DST, &blend_dst );
glPointSize( may_double(6.0 * CC_CONTENT_SCALE_FACTOR()) );
#define DRAW_4B_FUNC glColor4ub
#endif
ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
// Draw Gray Points
DRAW_4B_FUNC(pagesIndicatorNormalColor_.r,
pagesIndicatorNormalColor_.g,
pagesIndicatorNormalColor_.b,
pagesIndicatorNormalColor_.a);
ccDrawPoints( points, totalScreens );
// Draw White Point for Selected Page
DRAW_4B_FUNC(pagesIndicatorSelectedColor_.r,
pagesIndicatorSelectedColor_.g,
pagesIndicatorSelectedColor_.b,
pagesIndicatorSelectedColor_.a);
ccDrawPoint(points[iCurrentPage]);
// Restore GL Values
#if COCOS2D_VERSION >= 0x00020000
ccPointSize(1.0f);
#else
glPointSize(1.0f);
glDisable(GL_POINT_SMOOTH);
if (! blendWasEnabled)
glDisable(GL_BLEND);
// always restore the blending functions too
ccGLBlendFunc( blend_src, blend_dst);
// glBlendFunc( blend_src, blend_dst );
#endif
}
}
It worked fine for my earlier projects but not working for cocos2d v3. I get errors (not valid for C99 etc) for almost every openGL statements, such as glPointSize/ccPointSize and glColor4ub. I have tried to use CCDrawNode (the OOP way) but still it's not one to one translation. (glGetIntegerv etc)
The following link is the test project I created (with errors, notice that the screen is not scrollable, and the dot indicator is not shown (i.e. the visit function is not working)
https://drive.google.com/file/d/0BzH5x38rukpYaVlWdUJPWW9EYWc/edit?usp=sharing
EDIT:
I have tried to use [renderer enqueueMethod:#selector(drawDotIndicators) target:self]; and put the visit code in drawDotIndicators method. It is not working either
(the end of this tutorial: https://www.makegameswith.us/docs/#!/cocos2d/1.1/customrendering)

Related

loading mesh with DirectXTK

I use DirectXTK to load mesh. First, I import .fbx into vs2015 and build, then get .cmo file. Then I use DirectXTK load .cmo as follow:
bool MeshDemo::BuildModels()
{
m_fxFactory.reset(new EffectFactory(m_pd3dDevice));
m_states.reset(new CommonStates(m_pd3dDevice));
m_model = Model::CreateFromCMO(m_pd3dDevice, L"T54.cmo", *m_fxFactory, true, true);
return true;
}
void MeshDemo::Render()
{
m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, Colors::Silver);
m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
XMVECTOR qid = XMQuaternionIdentity();
const XMVECTORF32 scale = { 0.01f, 0.01f, 0.01f };
const XMVECTORF32 translate = { 0.f, 0.f, 0.f };
XMMATRIX world = XMLoadFloat4x4(&m_world);
XMVECTOR rotate = XMQuaternionRotationRollPitchYaw(0, XM_PI / 2.f, XM_PI / 2.f);
rotate = XMQuaternionRotationRollPitchYaw(0, XM_PI / 2.f, XM_PI / 2.f);
XMMATRIX local = XMMatrixMultiply(world, XMMatrixTransformation(
g_XMZero, qid, scale, g_XMZero, rotate, translate));
local *= XMMatrixRotationX(-XM_PIDIV2);
m_model->Draw(m_pImmediateContext, *m_states, local, XMLoadFloat4x4(&m_view),
XMLoadFloat4x4(&m_proj));
m_pSwapChain->Present(0, 0);
}
But I can't get correct results,the angle of wheel and some details are different with the .fbx model.
what should I do? Any idear?
Your model is fine, but your culling is inverted, and this is why the render is wrong.
Triangles sent to the GPU have a winding order, it has to be consistent, clock wise or counter clock wise by rearranging the triangle vertices. Then, a render state define what is the front side, and what has to be culled away, front, back or none.

(iOS) Accelerometer Graph (convert g-force to +/- 128) granularity

I am using this Accelerometer graph from Apple and trying to convert their G-force code to calculate +/- 128.
The following image shows that the x, y, z values in the labels do not match the output on the graph: (Note that addX:y:z values are what is shown in the labels above the graph)
ViewController
The x, y, z values are received from a bluetooth peripheral, then converted using:
// Updates LABELS
- (void)didReceiveRawAcceleromaterDataWithX:(NSInteger)x Y:(NSInteger)y Z:(NSInteger)z
{
dispatch_async(dispatch_get_main_queue(), ^{
_labelAccel.text = [NSString stringWithFormat:#"x:%li y:%li z:%li", (long)x, (long)y, (long)z];
});
}
// Updates GRAPHS
- (void)didReceiveAcceleromaterDataWithX:(NSInteger)x Y:(NSInteger)y Z:(NSInteger)z
{
dispatch_async(dispatch_get_main_queue(), ^{
float xx = ((float)x) / 8192;
float yy = ((float)y) / 8192;
float zz = ((float)z) / 8192;
[_xGraph addX:xx y:0 z:0];
[_yGraph addX:0 y:yy z:0];
[_zGraph addX:0 y:0 z:zz];
});
}
GraphView
- (BOOL)addX:(UIAccelerationValue)x y:(UIAccelerationValue)y z:(UIAccelerationValue)z
{
// If this segment is not full, then we add a new acceleration value to the history.
if (index > 0)
{
// First decrement, both to get to a zero-based index and to flag one fewer position left
--index;
xhistory[index] = x;
yhistory[index] = y;
zhistory[index] = z;
// And inform Core Animation to redraw the layer.
[layer setNeedsDisplay];
}
// And return if we are now full or not (really just avoids needing to call isFull after adding a value).
return index == 0;
}
- (void)drawLayer:(CALayer*)l inContext:(CGContextRef)context
{
// Fill in the background
CGContextSetFillColorWithColor(context, kUIColorLightGray(1.f).CGColor);
CGContextFillRect(context, layer.bounds);
// Draw the grid lines
DrawGridlines(context, 0.0, 32.0);
// Draw the graph
CGPoint lines[64];
int i;
float _granularity = 16.f; // 16
NSInteger _granualCount = 32; // 32
// X
for (i = 0; i < _granualCount; ++i)
{
lines[i*2].x = i;
lines[i*2+1].x = i + 1;
lines[i*2].y = xhistory[i] * _granularity;
lines[i*2+1].y = xhistory[i+1] * _granularity;
}
CGContextSetStrokeColorWithColor(context, _xColor.CGColor);
CGContextStrokeLineSegments(context, lines, 64);
// Y
for (i = 0; i < _granualCount; ++i)
{
lines[i*2].y = yhistory[i] * _granularity;
lines[i*2+1].y = yhistory[i+1] * _granularity;
}
CGContextSetStrokeColorWithColor(context, _yColor.CGColor);
CGContextStrokeLineSegments(context, lines, 64);
// Z
for (i = 0; i < _granualCount; ++i)
{
lines[i*2].y = zhistory[i] * _granularity;
lines[i*2+1].y = zhistory[i+1] * _granularity;
}
CGContextSetStrokeColorWithColor(context, _zColor.CGColor);
CGContextStrokeLineSegments(context, lines, 64);
}
How can I calculate the above code to show the correct accelerometer values on the graph with precision?
I post this as an aswer not a comment, because I have not enough reputation, but what I'll write might be enough to send you in the right direction, that it even may count as an answer...
Your question still doesn't include what is really important. I assume the calculation of the xx/yy/zz is no problem. Although I have no idea what the 8192 is supposed to mean.
I guess the preblem is in the part where you map your values to pixel coordinates...
the lines[] contains your values in a range of 1/8192th of the values in the label. so your x value of -2 should be at a pixel position of -0.0000something, so slightly(far less than 1 Pixel) above the view... Because you see the line a lot further down there must be some translation in place (not shown in your code)
The second part that is important but not shown is DrawGridlines. Probably in there is a different approach to map the values to pixel-coordinates...
Use the debugger to check what pixel-coordinates you get when draw your +127-line and what you get if you insert the value of +127 in your history-array
And some Ideas for improvements when reading your code:
1.)Put the graph in it's own class that draws one graph(and has only one history. Somehow you seem to have that partially already (otherwise I cannot figure out your _xGraph/_yGraph/_zGraph) But on the other hand you draw all 3 values in one drawLayer??? Currently you seem to have 3*3 history buffers of which 3*2 are filled with zeros...
2.) use one place where you do the calculation of Y that you use both for drawing the grid and drawing the lines...
3.) use CGContextMoveToPoint(); + CGContextAddLineToPoint(); instead of copying into lines[] with these ugly 2*i+1 indecies...

Update Widgets in PDF using Podofo

I am using PdfAnnotation.SetContents to set the value of an annotation.If the annotation is of type FreeText, only then this method correctly works and the value gets displayed on the PDF (using PDF Reader).If the type is Widget, the value gets set as content in pdf dictionary but does not get displayed.Is there a way i could set the value of a widget?
I found the solution, In order for the content to get displayed, an Appearance ("AP") Dictionary has to be set.
This could be used for that:
void PdfField::CreateFieldAppearance(PdfMemDocument *memDoc, const PdfString &value)
{
if( !m_pWidget->HasAppearanceStream() )
{
PdfRect pageRect;
PdfPainter painter;
PoDoFo::PdfRect rect = this->GetWidgetAnnotation()->GetRect();
unsigned int width = rect.GetWidth();
unsigned int height = rect.GetHeight();
PdfRect pdfRect(0, 0, width, height);
PdfXObject xObj(pdfRect, memDoc);
painter.SetPage(&xObj);
painter.SetClipRect(pdfRect);
painter.Save();
painter.SetColor(221.0/255.0, 228.0/255.0, 1.0);
painter.FillRect(0, 0, width, height);
painter.Restore();
// make rotation
painter.Save();
/***********************************************************************************/
// Rotation Logic
double angle = this->GetPage()->GetRotation();
if (angle) {
double radAngle = angle * M_PI / 180;
int cosA = (int)cos(radAngle);
int sinA = (int)sin(radAngle);
double translateY = rect.GetWidth(); // The View goes out of the bound, sits on top
painter.SetTransformationMatrix(cosA, sinA, -sinA, cosA, translateY, 0);
}
/***********************************************************************************/
PdfFont *font = memDoc->CreateFont("Helvetica", true, false);
font->SetFontSize(15);
// Do the drawing
painter.SetFont(font);
painter.BeginText(10, 5);
painter.SetStrokeWidth(20);
painter.AddText(value);
painter.EndText();
painter.FinishPage();
// This is very important. Not only does it disable the editing.
// Also it does correct the appearance issue on Adobe Readers.
this->SetReadOnly(true);
// The Stream Object has to be saved to the annotation
PoDoFo::PdfDictionary dict;
dict.AddKey( "N", xObj.GetObject()->Reference() );
this->GetFieldObject()->GetDictionary().AddKey( "AP", dict );
}
}

GB2ShapeCache Shape Scale? (Physics Editor) [Box2D]

There is a class associated with the program Physics Editor called GB2ShapeCache that loads shapes that I make in the program. I noticed that it is not currently possible to change the scale of the shapes on the fly so I would like to be able to scale the fixtures for the shapes that I made in Physics Editor. Now the scale of my CCSprite in my app can be random so currently in the addShapesWithFile method, I do this for polygons:
vertices[vindex].x = (offset.x * sprite.scaleX) / ptmRatio_;
vertices[vindex].y = (offset.y * sprite.scaleY) / ptmRatio_;
and this for circles:
circleShape->m_radius = ([[circleData objectForKey:#"radius"] floatValue] / ptmRatio_) *sprite.scale;
I also changed the method so that I can pass in my sprite so I can get the scale to:
-(void) addShapesWithFile:(NSString*)plist forSprite:(CCSprite*)sprite
so that I can pass in my sprite so I can get the scale.
HOWEVER, I find this to be inefficient because I should not have to reload ALL my shapes in my plist since they are already added.
So is there any way to do what I am doing now but in the addFixturesToBody method? This way I do not re-create the already added plist shapes and I only scale the fixtures when it is ready to be added to my body.
If anyone needs to see more code or needs more info, feel free to ask. I know this issue must be simple!!!
Thanks!
I would recommend implementing it in the addFixturesToBody method.
(see https://github.com/AndreasLoew/GBox2D/blob/master/GBox2D/GB2ShapeCache.mm)
Try this method below, this should scale the shapes accordingly to the sprite's they are for. Just pass in your CCSprite and this method will handle the rest.
- (void)addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape forSprite:(CCSprite*)sprite {
BodyDef *so = [shapeObjects_ objectForKey:shape];
assert(so);
FixtureDef *fix = so->fixtures;
if ((sprite.scaleX == 1.0f) && (sprite.scaleY == 1.0f)) {
// simple case - so do not waste any energy on this
while(fix) {
body->CreateFixture(&fix->fixture);
fix = fix->next;
}
} else {
b2Vec2 vertices[b2_maxPolygonVertices];
while(fix) {
// make local copy of the fixture def
b2FixtureDef fix2 = fix->fixture;
// get the shape
const b2Shape *s = fix2.shape;
// clone & scale polygon
const b2PolygonShape *p = dynamic_cast<const b2PolygonShape*>(s);
if(p)
{
b2PolygonShape p2;
for(int i=0; i<p->m_vertexCount; i++)
{
vertices[i].x = p->m_vertices[i].x * sprite.scaleX;
vertices[i].y = p->m_vertices[i].y * sprite.scaleY;
}
p2.Set(vertices, p->m_vertexCount);
fix2.shape = &p2;
}
// clone & scale circle
const b2CircleShape *c = dynamic_cast<const b2CircleShape *>(s);
if(c) {
b2CircleShape c2;
c2.m_radius = c->m_radius * sprite.scale;
c2.m_p.x = c->m_p.x * sprite.scaleX;
c2.m_p.y = c->m_p.y * sprite.scaleY;
fix2.shape = &c2;
}
// add to body
body->CreateFixture(&fix2);
fix = fix->next;
}
}
}

2D Pixel Shader has no effect?

I set up a basic pixel shader (right now, its configured for testing), and it doesn't seem to do anything. I set it up like so:
uniform extern texture ScreenTexture;
const float bloomThreshhold = 0.4;
const float existingPixelColorMult = 1.1;
sampler ScreenS = sampler_state
{
Texture = <ScreenTexture>;
};
float4 BloomedColor(float2 texCoord: TEXCOORD0) : COLOR
{
// pick a pixel on the screen for this pixel, based on
// the calculated offset and direction
float2 temp = texCoord;
temp.x += 1;
float4 mainPixelColor = 0;
/*
float4 pixelPlus1X = tex2D(ScreenS, temp);
temp.x -= 2;
float4 pixelMinus1X = tex2D(ScreenS, temp);
temp.x += 1;
temp.y += 1;
float4 pixelPlus1Y = tex2D(ScreenS, temp);
temp.y -= 2;
float4 pixelMinus1Y = tex2D(ScreenS, temp);
*/
return mainPixelColor;
}
technique Bloom
{
pass P0
{
PixelShader = compile ps_1_1 BloomedColor();
}
}
with the loading code like:
glowEffect = Content.Load<Effect>("GlowShader");
glowEffect.CurrentTechnique = glowEffect.Techniques[0];
and use code is:
spriteBatch.Begin();
glowEffect.Begin();
glowEffect.CurrentTechnique.Passes[0].Begin();
spriteBatch.Draw(screenImage, Vector2.Zero, Color.White);
spriteBatch.End();
glowEffect.CurrentTechnique.Passes[0].End();
glowEffect.End();
Loading seems to work fine, and there are no errors thrown when I use that method to render the texture, but it acts like the effect code isn't in there. It can't be that I'm using the wrong version of shaders (I tested with 2.0 and 1.1 versions), so why? (Using XNA 3.1)
You're returning 0 for every pixel. You have commented out any code that would return a different value than 0. 0 is black and if you're doing any sort of render you'll either get black (if the blend mode shows this as a color) or no change (if the blend mode multiplies the result). You can of course (if you were just attempting to see if the shader is being loaded and operated) try using an oddball color. Neon green anyone? Then, once you confirm it is being at least processed, start uncommenting that code and assessing the result.
Finally, if Bloom is what you're after, Microsoft has a very useful sample you will probably learn a lot from here:
http://create.msdn.com/en-US/education/catalog/sample/bloom
If you're using XNA 4.0, see what Shawn Hargreaves has to say about this.

Resources