Exception thrown by IJawsRenderer() - c++

I’m using the Mako SDK and IJawsRenderer::render() to render all IDOMPathNodes with an IDOMImageBrush fill. When I do, the renderer throws an error 2000 exception for some nodes, but not all. What could be the cause?
IDOMBrushPtr pBrush;
pPath->getFill(pBrush);
if (pBrush)
{
IDOMBrush::eBrushType fillStyle = pBrush->getBrushType();
switch (fillStyle)
{
case IDOMBrush::eImage:
{
IJawsRendererPtr renderer = IJawsRenderer::create(jawsMako);
IDOMImagePtr renderedImage;
renderedImage = renderer->render(pNode, 800); // This is where the exception will eventually happen.
break;
}
default:
break;
}
}

It could be that the exception is thrown because the path passed to the renderer is too small. There is a lower limit of 1pt x 1pt (or 1.33 x 1.33 Mako units) for the renderer. Modify your code to check that the bounding box of the node is big enough, for example:
const double minimumRenderSize = 96.0 / 72.0;
...
IDOMBrushPtr pBrush;
pPath->getFill(pBrush);
FRect box;
pPath->getBounds(box);
box.dX = box.dX < minimumRenderSize ? minimumRenderSize : box.dX;
box.dY = box.dY < minimumRenderSize ? minimumRenderSize : box.dY;
if (pBrush)
{
IDOMBrush::eBrushType fillStyle = pBrush->getBrushType();
switch (fillStyle)
{
case IDOMBrush::eImage:
{
IJawsRendererPtr renderer = IJawsRenderer::create(jawsMako);
IDOMImagePtr renderedImage;
renderedImage = renderer->render(pNode, 800, IDOMColorSpacesRGB::create(jawsMako), box);
break;
}
default:
break;
}
}

Related

SDL stiff movement

i am making a pong game, lPad is left pad and rPad is the right pad, but i have a problem when any pad is moving up and when i release the up button and press down the pad stops for a while and then goes down, the other thing is i can't move both pads when pressing both controls(only one is moving) with this setup:
if(e.type == SDL_KEYDOWN) {
switch(e.key.keysym.sym) {
case SDLK_s:
lPad.y += 8;
if(lPad.y >= s.SCREEN_HEIGHT - lPad.getHeight()) {
lPad.y = s.SCREEN_HEIGHT - lPad.getHeight();
}
break;
case SDLK_w:
lPad.y -= 8;
if(lPad.y <= 0) {
lPad.y = 0;
}
break;
case SDLK_DOWN:
rPad.y += 8;
if(rPad.y >= s.SCREEN_HEIGHT - rPad.getHeight()) {
rPad.y = s.SCREEN_HEIGHT - rPad.getHeight();
}
break;
case SDLK_UP:
rPad.y -= 8;
if(rPad.y <= 0) {
rPad.y = 0;
}
break;
default:
break;
}
}
Any idea how to fix this and make it smooth ?
It's better to use SDL_GetKeyboardState(NULL) as the function to get input. This way, you can get the entire state of the keyboard simultaneously and thus allow for parallel inputs. If you use the while loop, each event will get caught individually, and thus be choppy.
Here is some sample code on how to use it:
const auto * keys = SDL_GetKeyboardState(NULL);
while(!done) {
while(SDL_PollEvent(&e)) {
if(e.type == SDL_QUIT) {
done = true;
}
}
SDL_PumpEvents();
if (keys[SDL_SCANCODE_UP]) {
p1.set_speed(0, -60000 * delta.count());
}
if (keys[SDL_SCANCODE_DOWN]) {
p1.set_speed(0, 60000 * delta.count());
}
if (keys[SDL_SCANCODE_LEFT]) {
p1.set_speed(-60000 * delta.count(), 0);
}
if (keys[SDL_SCANCODE_RIGHT]) {
p1.set_speed(60000 * delta.count(), 0);
}
Also, might I suggest having a speed variable? Using pixels is not a good way to scale movement, as it depends on the resolution of the screen. Using something based on a time step is much more robust.

Object movement in a 2D Array/Grid

I am trying to create a variation of the classic Snake game.
Basically what i am stuck on is how to restrict the snake movement to a 2D array whereby there will be a 20x20 grid.
At the moment, my snake head which is just a shape drawn with a midpoint, moves freely one pixel at a time within the game board. I require the snake to move one grid space at a time.
This is my snake code:
void Snake::move()
{
switch(direction_){
case Direction::North:
position_.y += 1;
break;
case Direction::East:
position_.x += 1;
break;
case Direction::South:
position_.y -= 1;
break;
case Direction::West:
position_.x -= 1;
}
if (position_.x < 6.4) position_.x = 44.8; else if (position_.x > 44.8) position_.x = 6.4;
if (position_.y < 0) position_.y = 38.4; else if (position_.y > 38.4) position_.y = 0;
}
void Snake::render(prg::Canvas& canvas) const
{
canvas.drawCircle(getPosition().x * 20, getPosition().y * 20,19.2,prg::Colour::GREEN);
}
void Snake::changeDirection(Direction new_direction)
{
direction_ = new_direction;
}
This is the code that handles keyboard input/movement
PlayerSnake::PlayerSnake()
{
prg::application.addKeyListener(*this);
}
PlayerSnake::~PlayerSnake()
{
prg::application.removeKeyListener(*this);
}
bool PlayerSnake::onKey(const prg::IKeyEvent::KeyEvent& key_event)
{
if(key_event.key_state == KeyEvent::KB_DOWN) {
switch(key_event.key) {
case KeyEvent::KB_LEFT_KEY:
changeDirection(Direction::West);
break;
case KeyEvent::KB_RIGHT_KEY:
changeDirection(Direction::East);
break;
case KeyEvent::KB_UP_KEY:
changeDirection(Direction::North);
break;
case KeyEvent::KB_DOWN_KEY:
changeDirection(Direction::South);
break;
}
}
return true;
}
I'm in desperate need of any suggestions and have been racking my brain trying to get the snake to move along a grid. I'm also new-ish to C++ so please understand.
Thanks :)
Don't think of the screen as the data. The screen is a representation of the data. This means that you have to figure out a way to map the data to it's visual equivalent.
If the grid is 20x20, but the screen rendering is 200x200, this implies a 1:10 ratio of pixels to cells. So, one possible method of drawing might look like this. (Sorry, using Processing syntax.)
In processing, one method of drawing a rectangle is using the command rect(int left, int top, int right, int bottom);
So, one implementation might look like this:
void draw_square(int cellx, int celly)
{
rect(cellx*10, celly*10, cellx*10+10, celly*10+10);
}

Xcode Collision Detection Error Cocos2D Assertion Error

I am making a ball game in cocos2D, where you can slide the ball in a direction, and it will travel until it collides with a wall. My collision detection is giving me an "assertion error" when I swipe the ball in a direction.
I am using tiledmap to make the levels.
The way I've coded it is that I find the tilesize that my ball is in, then, in a for loop, I check if there are any wall sprites around the ball.
Any ideas where its going wrong?
-(void)callEveryFrame:(ccTime)dt{
//Error Here vvv (Assertion Failure in -[CCTMXLayer tileAt:])
NSLog(#"First Touch x: /%f Last Touch x: /%f First Touch y: /%f Last Touch y: /%f", firstTouch.x, lastTouch.x, firstTouch.y, lastTouch.y);
if(swipeLeft || swipeRight || swipeDown || swipeUp)
{
bool collision = false;
int ballTileX = (player.position.x / level1.tileSize.width);
int ballTileY = (player.position.y / level1.tileSize.width);
int collisionAreaX = ballTileX-1;
int collisionAreaY = ballTileY-1;
for(int i = 0; i < 9; i++)
{
bool tilePresent = [background tileAt:CGPointMake(collisionAreaX, collisionAreaY)] != NULL;
if(tilePresent && CGRectIntersectsRect(CGRectMake(collisionAreaX*level1.tileSize.width, collisionAreaY*level1.tileSize.height, level1.tileSize.width, level1.tileSize.height), CGRectMake(ballTileX*level1.tileSize.width, ballTileY*level1.tileSize.height, level1.tileSize.width, level1.tileSize.height)))
{
collision = true;
break;
}
if(i % 3 == 0)
{
collisionAreaX -= 2;
collisionAreaY++;
}
else
{
collisionAreaX++;
}
}
if(collision) {
swipeLeft = false;
swipeRight = false;
swipeDown = false;
swipeUp = false;
}
}
}

ASSIMP & paintGL() ,slow rendering (and crash)

I am using Assimp to load a .3ds file, and a QGLWidget derived class to draw it using PaintGL(). It works with small .3ds files (some KBytes) but if i try to render bigger files (like 1MBytes) the application crashes. Is my way too bad and twisted? Am I doing something wrong?
With qDebug i understand that paintGL() works correctly.The problem is in ourRender method,because if i obscure the
for (int t = 0; t < p->getFaces().count(); ++t)
and in detail
glVertex3f(f.getVerticesArray()[s].getX(),f.getVerticesArray();
cycle it all works fast (but obviously nothing is painted) except grid and axis.With it,and loading some complicated 3ds,it crashes
my hardware is
Phenom II X3 2.10ghz,4GB and 6650M (last drivers)
On a Celeron 2.1 Ghz it crash
BUT on a i7 the program starts but render #2FPS (if I dont use "ourRender" method,it renders at 120fps on my pc)
void GLWidget::paintGL()
{
qDebug << "Start PaintGL() #" << times;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(objCamera->mPos.x, objCamera->mPos.y, objCamera->mPos.z,
0, objCamera->mView.y, 0,
objCamera->mUp.x, objCamera->mUp.y, objCamera->mUp.z);
if (drawLines) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
else glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
draw_grid();
drawAxis();
ourRender(this->scenaa);
qDebug << "Close PaintGL() #" << times;
}
And this is the "ourRender" method:
void GLWidget::ourRender(const Scene* sc){
QHash<QString, SceneObject*>& hash=sc->getObj();
double molt =1/20;
int counter =0;
for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
aiMatrix4x4 minchia(1,0,0,molt*20,0,1,0,molt*20,0,0,1,molt*20,0,0,0,1);
aiTransposeMatrix4(&minchia);
glPushMatrix();
const Mesh* p = dynamic_cast<Mesh*>(i.value());
glMultMatrixf((float*) &minchia);
if(p){
for (int t = 0; t < p->getFaces().count(); ++t) {
Face f = p->getFaces()[t];
GLenum face_mode;
switch(f.getVerticesArray().count()) {
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
QList<Vector3D> lista = f.getVerticesArray();
for(int s = 0; s < lista.count(); s++) {
if (p->getNormals().count()>0)
--------->glVertex3f(f.getVerticesArray()[s].getX(),f.getVerticesArray()[s].getY(),f.getVerticesArray()[s].getZ());
}
glEnd();
}
}
glPopMatrix();
molt+=13;
counter++;
}
glPopMatrix();
}
...in the derived QGLWidget class costructor...
SceneImporter* aa = new AssimpAdapter();
Scene * nuovo=aa->importFile("C:/Users/nicola/Desktop/Source/aces.3ds");
scenaa=nuovo;
We solved the problem modifying "ourender" method (using references instead of copyes)
void GLWidget::ourRender(Scene *&sc){
QHash<QString, SceneObject*>& hash=sc->getObj();
int counter =0;
for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
aiMatrix4x4 m;
aiTransposeMatrix4(&m);
glPushMatrix();
const Mesh* p = dynamic_cast<Mesh*>(i.value());
glMultMatrixf((float*) &m);
if(p){
//apply_material(aaFuori.GetScene()->mMaterials[counter]);
QList<Face>& faccie=p->getFaces();
for (int t = 0; t < faccie.count(); ++t) {
Face f = faccie[t];
GLenum face_mode;
switch(f.getVerticesArray().count()) {
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
QList<Vector3D>& lista = f.getVerticesArray();
int conta=lista.count();
glVertex3f(lista[0].x,lista[0].y,lista[0].z);
glVertex3f(lista[1].x,lista[1].y,lista[1].z);
glVertex3f(lista[2].x,lista[2].y,lista[2].z);
glEnd();
}
}
glPopMatrix();
counter++;
}
Now we can render 8MBytes .3Ds #4fps during camera rotations (instead of application crash).Could someone of you give us an opinion about this result?is it good or bad?
Optimizazion.The fact is that for every vertex we were accessing to a QList 3 times.Now we've modified it,and instead of Qlist we use a Vector3D* array that saves the position of the vertices and so we can use the GL method glVertex3fv((GLfloat*)array[numface].posvertex); So,given the pointer to the face,its much faster than before (4 to 10 fps on the same scene).
void GLWidget::ourRender(Scene *sc){
QHash<QString, SceneObject*>& hash=sc->getObj();
aiMatrix4x4 m;
for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
aiTransposeMatrix4(&m);
glPushMatrix();
Mesh* p = dynamic_cast<Mesh*>(i.value());
glMultMatrixf((float*) &m);
if(p){
QList<Face>& faccie=p->getFaces();
int numerofacce=faccie.count();
for (int t = 0; t < numerofacce; ++t) {
Face& f = faccie[t];
GLenum face_mode;
Vector3D* lista=f.arrayVertici;
switch(f.getVerticesArray().count()) {
case 1:
face_mode = GL_POINTS;
glBegin(face_mode);
glVertex3fv((GLfloat*)lista[0].pos);
break;
case 2:
face_mode = GL_LINES;
glBegin(face_mode);
glVertex3fv((GLfloat*)lista[0].pos);
glVertex3fv((GLfloat*)lista[1].pos);
break;
case 3:
face_mode = GL_TRIANGLES;
glBegin(face_mode);
glVertex3fv(&lista[0].pos[0]);
glVertex3fv(&lista[1].pos[0]);
glVertex3fv(&lista[2].pos[0]);
break;
default: face_mode = GL_POLYGON; break;
}
glEnd();
}
}
glPopMatrix();
counter++;
}
glPopMatrix();
}
Where Vector3D is initialized like this:
Vector3D::Vector3D(double x, double y, double z) {
setX(x);
setY(y);
setZ(z);
pos[0]=x; //vertex1
pos[1]=y; //vertex2
pos[2]=z; //vertex3
}
PS:Grimmy suggests me to use DisplayLists (discovered right now).Tomorrow I will try them.

How to make mouse movement work with no delay?

I'm making a program that let me click on the center of two concentric circles and, by mouse move, change it's position and i can do the same with it's radii.
The thing is that the mouse movement is followed by a delay response from the circles drawing making the radius follow the mouse instead of being exactly in the same position during the movement.
Would you guys know how to make it work like that? pin point following by the drawing.
a bit of the code that treats the mouse clicking and movements:
void DemoApp::OnLButtonDown(FLOAT pixelX, FLOAT pixelY)
{
SetCapture(m_hwnd);
mouseRegion = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - mouseRegion.x;
FLOAT yDifference = centerCircles.y - mouseRegion.y;
FLOAT distanceToCenter = sqrtf(xDifference*xDifference + yDifference*yDifference);
if(distanceToCenter < 10.0f)
{
centerMove = true;
minimumRadiusCircleMove = false;
maximumRadiusCircleMove = false;
}
else if((distanceToCenter > (minimumRadius - 1.0f)) && (distanceToCenter < (minimumRadius + 1.0f)))
{
minimumRadiusCircleMove = true;
centerMove = false;
maximumRadiusCircleMove = false;
}
else if((distanceToCenter > (maximumRadius - 1.0f)) && (distanceToCenter < (maximumRadius + 1.0f)))
{
maximumRadiusCircleMove = true;
centerMove = false;
minimumRadiusCircleMove = false;
}
else
{
centerMove = false;
minimumRadiusCircleMove = false;
maximumRadiusCircleMove = false;
}
InvalidateRect(m_hwnd, NULL, FALSE);
}
void DemoApp::OnMouseMove(int pixelX, int pixelY, DWORD flags)
{
if (flags & MK_LBUTTON)
{
if(centerMove)
{
centerCircles = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT distanceLeftToCenterCircles = abs(centerCircles.x - bitmapTopLeft);
FLOAT distanceTopToCenterCircles = abs(centerCircles.y - bitmapTopRight);
percentageFromLeft = distanceLeftToCenterCircles / displaySizeWidth;
percentageFromTop = distanceTopToCenterCircles / displaySizeHeight;
}
else if(minimumRadiusCircleMove)
{
radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - radiusSelection.x;
FLOAT yDifference = centerCircles.y - radiusSelection.y;
minimumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
minimumRadiusPercentage = minimumRadius/(displaySizeWidth/2);
}
else if(maximumRadiusCircleMove)
{
radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - radiusSelection.x;
FLOAT yDifference = centerCircles.y - radiusSelection.y;
maximumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
maximumRadiusPercentage = maximumRadius/(displaySizeWidth/2);
}
InvalidateRect(m_hwnd, NULL, FALSE);
}
}
void DemoApp::OnLButtonUp()
{
ReleaseCapture();
}
According to MSDN ( http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx ) InvalidateRect doesn’t cause the window to be repainted until the next WM_PAINT and "The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window." so it’s not immediate.
I found a possible solution on MSDN here Drawing Without the WM_PAINT Message
i've found a solution to that problem!
It's way simple than expected, all you got to do is add a flag while creating the render target, that way the mousemove will respond way faster:
the flag is: D2D1_PRESENT_OPTIONS_IMMEDIATELY.
// Create Direct2d render target.
hr = m_pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(m_hwnd, size, D2D1_PRESENT_OPTIONS_IMMEDIATELY),
&m_pRenderTarget
);