Very simple test view in MonoTouch draws a line using Core Graphics but view content is not shown - cocoa-touch

I give up now on this very simple test I've been trying to run. I want to add a subview to my window which does nothing but draw a line from one corner of the iPhone's screen to the other and then, using touchesMoved() it is supposed to draw a line from the last to the current point.
The issues:
1. Already the initial line is not visible.
2. When using Interface Builder, the initial line is visible, but drawRect() is never called, even if I call SetNeedsDisplay().
It can't be that hard...can somebody fix the code below to make it work?
In main.cs in FinishedLaunching():
oView = new TestView();
oView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
oView.Frame = new System.Drawing.RectangleF(0, 0, 320, 480);
window.AddSubview(oView);
window.MakeKeyAndVisible ();
The TestView.cs:
using System;
using MonoTouch.UIKit;
using MonoTouch.CoreGraphics;
using System.Drawing;
using MonoTouch.CoreAnimation;
using MonoTouch.Foundation;
namespace Test
{
public class TestView : UIView
{
public TestView () : base()
{
}
public override void DrawRect (RectangleF area, UIViewPrintFormatter formatter)
{
CGContext oContext = UIGraphics.GetCurrentContext();
oContext.SetStrokeColor(UIColor.Red.CGColor.Components);
oContext.SetLineWidth(3.0f);
this.oLastPoint.Y = UIScreen.MainScreen.ApplicationFrame.Size.Height - this.oLastPoint.Y;
this.oCurrentPoint.Y = UIScreen.MainScreen.ApplicationFrame.Size.Height - this.oCurrentPoint.Y;
oContext.StrokeLineSegments(new PointF[] {this.oLastPoint, this.oCurrentPoint });
oContext.Flush();
oContext.RestoreState();
Console.Out.WriteLine("Current X: {0}, Y: {1}", oCurrentPoint.X.ToString(), oCurrentPoint.Y.ToString());
Console.Out.WriteLine("Last X: {0}, Y: {1}", oLastPoint.X.ToString(), oLastPoint.Y.ToString());
}
private PointF oCurrentPoint = new PointF(0, 0);
private PointF oLastPoint = new PointF(320, 480);
public override void TouchesMoved (MonoTouch.Foundation.NSSet touches, UIEvent evt)
{
base.TouchesMoved (touches, evt);
UITouch oTouch = (UITouch)touches.AnyObject;
this.oCurrentPoint = oTouch.LocationInView(this);
this.oLastPoint = oTouch.PreviousLocationInView(this);
this.SetNeedsDisplay();
}
}
}

You overrode the wrong Draw method.
You overrode DrawRect (RectangleF, UIViewPrintFormatter) which is used for printing.
You want to override Draw (RectangleF)

Related

What am I doing wrong in drawing a line in wxWidgets?

// cMain.cpp
#include "cMain.h"
cMain::cMain() : wxFrame(nullptr, wxID_ANY, "ImProcGUI", wxPoint(50, 50), wxSize(800, 600)) {
m_MenuBar = new wxMenuBar();
// File Menu
m_FileMenu = new wxMenu();
m_FileMenu->Append(wxID_OPEN, _T("&Open"));
m_FileMenu->Append(wxID_OPEN, _T("&Save"));
m_FileMenu->Append(wxID_OPEN, _T("&Quit"));
m_MenuBar->Append(m_FileMenu, _T("&File"));
// About Menu
m_HelpMenu = new wxMenu();
m_HelpMenu->Append(wxID_ABOUT, _T("&About"));
m_MenuBar->Append(m_HelpMenu, _T("&Help"));
SetMenuBar(m_MenuBar);
}
wxBEGIN_EVENT_TABLE(cMain, wxFrame)
EVT_PAINT(cMain::OnPaint)
wxEND_EVENT_TABLE()
cMain::~cMain() {
}
void cMain::onPaint(wxPaintEvent& event) {
wxPaintDC dc(this);
wxCoord x1 = 50, y1 = 60;
wxCoord x2 = 190, y2 = 60;
dc.DrawLine(x1, y1, x2, y2);
}
// cMain.h
#include "wx/wx.h"
class cMain : public wxFrame
{
public:
cMain();
~cMain();
wxWindow* m_Window = nullptr;
wxMenuBar* m_MenuBar = nullptr;
wxMenu* m_FileMenu = nullptr;
wxMenu* m_HelpMenu = nullptr;
void onPaint(wxPaintEvent& event);
DECLARE_EVENT_TABLE()
};
Above is the code I have. I am not sure what I am doing wrong. I have a main frame, onto which I want to draw. When I run the code, however, the line is not there. (in my first attempt, I tried to put a window onto the frame and to draw onto it, but the line was not there in that case too)
You're drawing on the frame, but your entire frame is covered by m_Window, which hides whatever you draw. You probably don't need this window at all, but if you do, you need to draw on it, not on the frame itself.
Also note that you're using both the event table and Connect() with your handler, which is not catastrophic, but still wrong and, at best, useless. Use one or the other, or, better, use Bind() (rather than Connect()).
Moreover, you've made a typo in your handler name: you used OnPaint() in EVT_PAINT macro, which just happens to be the name of a base class handler doing nothing, rather than your onPaint(). So your handler is not called at all.

World class doesn't display my background

I have a class called World that contains all the entities that make interaction with the player (obstacles, background, scenario) and this class has a method called drawWorld() in which draw all entities. The first thing I put on this method was the background, but it doesn't draw the background texture and I don't know why.
This render method is from my game screen and where I call the method drawWorld():
#Override
public void render(float delta) {
// OpenGL clear screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(Gdx.gl.GL_COLOR_BUFFER_BIT | Gdx.gl.GL_DEPTH_BUFFER_BIT);
// Set the projection matrix for the SpriteBatch
this.game.spriteBatch.setProjectionMatrix(this.game.orthoCamera.combined);
// Act stage
this.game.stage.act(delta);
// SpriteBatch begins
this.game.spriteBatch.begin();
// Draw world
this.world.drawWorld();
// Draw stage
this.game.stage.draw();
// SpriteBatch ends
this.game.spriteBatch.end();
}
And here I render the background:
public void drawWorld() {
// Draw background
this.game.spriteBatch.draw(this.background, 0, 0);
}
Without forget that I created the background texture:
// Load background image
this.background = Assets.manager.get(Assets.background);
What am I doing wrong?
When you create a Stage with only a ViewPort, under the hood, the Stage creates and uses it's own Batch. So, in your render method, you have game.spritBatch drawing your background and then Stage's Batch drawing the stage within between the begin and end of game.spriteBatch. That is a big no no.
The way this should be done is like this:
Creating the Stage:
this.game.stage = new Stage(this.viewPort, this.game.spriteBatch); // For efficiency, you can use the same spriteBatch
Render:
#Override
public void render(float delta) {
// OpenGL clear screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(Gdx.gl.GL_COLOR_BUFFER_BIT | Gdx.gl.GL_DEPTH_BUFFER_BIT);
// Set the projection matrix for the SpriteBatch
this.game.spriteBatch.setProjectionMatrix(this.game.orthoCamera.combined);
// Act stage
this.game.stage.act(delta);
// SpriteBatch begins
this.game.spriteBatch.begin();
// Draw world
this.world.drawWorld();
// SpriteBatch ends
this.game.spriteBatch.end();
// Draw stage
this.game.stage.draw(); // After spriteBatch.end()!!
}
See the docs for more about the Stage(Viewport viewport, Batch batch) constructor.

Detect when mouse is not in QGraphicsScene

I am having a class inherited from QGraphicsScene. I have a mouseMoveEvent in this class. Based on the mouse move I am sending the co ordinates via signal to the main window. I have multiple GraphicViews in main window. Based on the scene from which the signal is received I am display the scene co ordinates using QGraphicsTextItem.
The problem is when I move out of the scene area I am unable to hide the QGraphicsTextItem.
Can someone give me a work around for this?
Class Scene::QGraphicsScene
{
void MouseMoveEvent(QGraphicsSceneMouseEvent *Event)
{
int XPos = event.x();
int YPos = event.y();
emit SignalPos(XPos,YPos);
}
}
//In Main Window
connect(scene1,SignalPos(int,int),this,SlotPos1(int,int);
//Similarly for scene2,scene3,scene4
void MainWindow::SlotPos(int X, int Y)
{
m_qgtxtItemX.setText(QString::x);
//I want to hide this once I am out of scene.It is a member variable. I tried
//taking local variable but it didn't work.
//Similarly for y and other slots
}
Install an event filter on the scene.
scene1->installEventFilter(this);
then implement the method in the class that is referenced by "this":
bool eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Leave)
{
qDebug() << "Mouse left the scene";
}
return false;
}
Just tried it and it worked! If you are installing the event filter on more than one object, please use "watched" to differentiate between them.
Best,

Using Core OpenGL to programmatically create a context with depth buffer: What am I doing wrong?

I'm trying to create an OpenGL context with depth buffer using Core OpenGl. I then wish to display the OpenGL content via a CAOpenGLLayer. From what I've read it seems I should be able to create the desired context by the following method:
I declare the following instance variable in the interface
#interface TorusCAOpenGLLayer : CAOpenGLLayer
{
//omitted code
CGLPixelFormatObj pix;
GLint pixn;
CGLContextObj ctx;
}
Then in the implementation I override copyCGLContextForPixelFormat, which I believe should create the required context
- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
{
CGLPixelFormatAttribute attrs[] =
{
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
(CGLPixelFormatAttribute)0
};
NSLog(#"Pixel format error:%d", CGLChoosePixelFormat(attrs, &pix, &pixn)); //returns 0
NSLog(#"Context error: %d", CGLCreateContext(pix, NULL, &ctx)); //returns 0
NSLog(#"The context:%p", ctx); // returns same memory address as similar NSLog call in function below
return ctx;
}
Finally I override drawInCGLContext to display the content.
-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat: (CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
{
// Set the current context to the one given to us.
CGLSetCurrentContext(glContext);
int depth;
NSLog(#"The context again:%p", glContext); //returns the same memory address as the NSLog in the previous function
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(0.5, 0.5, 1.0, 1.0, -1.0, 1.0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glGetIntegerv(GL_DEPTH_BITS, &depth);
NSLog(#"%i bits depth", depth); // returns 0
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//drawing code here
// Call super to finalize the drawing. By default all it does is call glFlush().
[super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
}
The program compiles fine and displays the content, but without the depth testing. Is there something extra I have to do to get this to work? Or is my entire approach wrong?
Looks like I was overriding the wrong method. To obtain the required depth buffer one should override the copyCGLPixelFormatForDisplayMask like so:
- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
CGLPixelFormatAttribute attributes[] =
{
kCGLPFADepthSize, 24,
0
};
CGLPixelFormatObj pixelFormatObj = NULL;
GLint numPixelFormats = 0;
CGLChoosePixelFormat(attributes, &pixelFormatObj, &numPixelFormats);
if(pixelFormatObj == NULL)
NSLog(#"Error: Could not choose pixel format!");
return pixelFormatObj;
}
Based on the code here.

How to implement Mouse Look in Java3d

I'm at a loss here. I've got a simple terrain generation algorithm working, and I've got some simple keyboard navigation working by extending ViewPlatformAWTBehavior and handling my own events. That's all well and good, and I can follow terrain. Hooray!
What I'd like to do is get some simple "mouse look" working. MouseRotate is close, but I'm looking for something more like an FPS ... where you aren't going to roll the camera, you're limited to 90 degrees vertical (up or down), and the mouse cursor is captured by the JFrame (with an escape).
I just can't seem to get it to work. I can capture the mouse event just fine, and mouseMoved works. I could probably just use an invisible cursor, and that would get me a large part of the way there (maybe), but I'd be stuck when trying to keep the mouse in the screen ... as soon as you're out of the frame, the mouse would be visible and stop rotating the view.
I keep thinking I must be going about this wrong, because this has to be a fairly common implementation, but I can't find anything on it.
Does anyone have some pointers or references?
If you want this is the code to make a full screen window which will help you with mouse problems
package fullscreen;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class FullScreen extends JFrame{
private JPanel contentPane = new JPanel();
private JButton fullscreenButton = new JButton("Fullscreen Mode");
private boolean Am_I_In_FullScreen = false;
private int PrevX,PrevY,PrevWidth,PrevHeight;
public static void main(String[] args) {
FullScreen frame = new FullScreen();
frame.setSize(600,500);
frame.setVisible(true);
}
public FullScreen(){
super("My FullscreenJFrame");
setContentPane(contentPane);
//From Here starts the trick
FullScreenEffect effect = new FullScreenEffect();
fullscreenButton.addActionListener(effect);
contentPane.add(fullscreenButton);
fullscreenButton.setVisible(true);
}
private class FullScreenEffect implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
if(Am_I_In_FullScreen == false){
PrevX = getX();
PrevY = getY();
PrevWidth = getWidth();
PrevHeight = getHeight();
dispose(); //Destroys the whole JFrame but keeps organized every Component
//Needed if you want to use Undecorated JFrame
//dispose() is the reason that this trick doesn't work with videos
setUndecorated(true);
setBounds(-10,-100,getToolkit().getScreenSize().width+30,getToolkit()
.getScreenSize().height+110);
setVisible(true);
Am_I_In_FullScreen = true;
}
else{
setVisible(true);
setBounds(PrevX, PrevY, PrevWidth, PrevHeight);
dispose();
setUndecorated(false);
setVisible(true);
Am_I_In_FullScreen = false;
}
}
}
}