OpenGL ES HTC TP2 - Windows Mobile Software Development

I've been beating my head against the wall on this, so it's time to ask for help.
I've ported my game engine from iPhone to Windows CE (it actually started out many years ago as a WinCE engine, so I've developed it with portability in mind). I've also maintained a Windows build (full windows) all along for development.
I'm having problems initializing OpenGL ES on the HTC Touch Pro 2. Now what is maddening is that one of the builds worked fine, but I can't reproduce that success.
For starters, I'm linking to the Vincent OGLES implementation. If I use the Vincent libGLES_CM.DLL on a Dell x50v then it renders fine using software (so it's very slow - I haven't begun to see about using the GLES lite hardware implementation on that device yet). So is using the Vincent implementation without the software renderer DLL the correct method on a device like the TP2?
I tried this OpenGL ES SDK:
http://www.khronos.org/message_boards/viewtopic.php?f=11&t=1433
But it crashes on the first call to any OGLES API (eglGetDisplay). So I assume the linker lib is not mapping correctly to the TP2's DLL.
With Vincent it is failing at eglCreateContext, which returns EGL_BAD_ATTRIBUTE. If I do not specify an attribute list (which I see is how many other implementations call that routine) then it crashes. If I send an attribute array just containing EGL_NONE then it also crashes. It has to have at least one actual attribute to not crash.
I'm using attributes that are valid, and have tried many, many combinations, but it still returns EGL_BAD_ATTRIBUTE.
Any suggestions would be greatly appreciated.

Here's the code. I've tried calling eglCreateContext before and after eglCreateWindowSurface, because I've seen implementations do it both ways, but it made no difference.
Code:
g_hMainDC = GetDC(hWnd);
EGLConfig* configs = NULL;
const EGLint configAttribs[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, EGL_DONT_CARE,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, EGL_DONT_CARE,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
glesDisplay = eglGetDisplay(g_hMainDC);
if (!glesDisplay) {
return false;
}
if (!eglInitialize(glesDisplay, NULL, NULL)) {
return false;
}
EGLint num_configs = 0;
if (!eglGetConfigs(glesDisplay, NULL, 0, &num_configs)) {
return false;
}
if (num_configs==0) {
return false;
}
configs = new EGLConfig[num_configs];
eglGetConfigs(glesDisplay,configs,sizeof(EGLConfig),&num_configs);
EGLConfig config = NULL;
if (!eglChooseConfig(glesDisplay, configAttribs, &config, 1, &num_configs)) {
return false;
}
if (num_configs==0) {
return false;
}
if (config==NULL) {
return false;
}
// Let’s create our rendering context
glesContext=eglCreateContext(glesDisplay, config, EGL_NO_CONTEXT, configAttribs);
if(!glesContext) {
return false;
}
glesSurface = eglCreateWindowSurface(glesDisplay, config, hWnd, NULL);
if (!glesSurface) {
return false;
}

Okay. Finally got a handle on this. You can't pass attributes to eglCreateContext or eglCreateWindowSurface or it will always return EGL_BAD_ATTRIBUTE. It has to be an empty array or a NULL pointer.
My app was running out of memory on the stack, and it would fail in eglCreateContext. I increased the stack size in the link settings and that fixed it. I had played around with the stack size earlier, and reverted my settings because it did not appear that had anything to do with the OGL ES initialization problems I was having.

Try to google the Xperia SDK which come with workable OpenGL ES samples.

Related

DirectShow: Video-Preview and taking photo (with working code)

Questions
As mentioned in the text below the TakePicture() method is not working properly on the HTC HD 2 device. It would be nice if someone could look at the code below and tell me if it is right or wrong what I'm doing.
Introduction
I recently asked a question on another forum about displaying a video preview and taking camera image with DirectShow. The tricky thing about the topic is, that it's very hard to find good examples and the documentation and the framework itself is very hard to understand for someone who is new to windows programming and C++ in general.
Nevertheless I managed to create a class that implements most of this features and probably works with most mobile devices. Probably because as far as I know the DirectShow implementation depends a lot on the device itself. I could only test it with the HTC HD and HTC HD2, which are known as quite incompatible.
HTC HD
- Working: Video preview, writing photo to file
- Not working: Set video resolution (CRASH), set photo resolution (LOW quality)
HTC HD 2
- Working: Set video resolution, set photo resolution
- Problematic: Video Preview rotated
- Not working: Writing photo to file
To make it easier for others by providing a working example, I decided to share everything I have got so far below. I removed all of the error handling for the sake of simplicity. As far as documentation goes, I can recommend you to read the MSDN documentation about the topic. After that the code below is pretty straight forward.
Code:
void Camera::Init()
{
CreateComObjects();
_captureGraphBuilder->SetFiltergraph(_filterGraph);
InitializeVideoFilter();
InitializeStillImageFilter();
}
Dipslay a video preview (working with any tested handheld):
Code:
void Camera::DisplayVideoPreview(HWND windowHandle)
{
IVideoWindow *_vidWin;
_filterGraph->QueryInterface(IID_IMediaControl,(void **) &_mediaControl);
_filterGraph->QueryInterface(IID_IVideoWindow, (void **) &_vidWin);
_videoCaptureFilter->QueryInterface(IID_IAMVideoControl,
(void**) &_videoControl);
_captureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, _videoCaptureFilter, NULL, NULL);
CRect rect;
long width, height;
GetClientRect(windowHandle, &rect);
_vidWin->put_Owner((OAHWND)windowHandle);
_vidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
_vidWin->get_Width(&width);
_vidWin->get_Height(&height);
height = rect.Height();
_vidWin->put_Height(height);
_vidWin->put_Width(rect.Width());
_vidWin->SetWindowPosition(0,0, rect.Width(), height);
_mediaControl->Run();
}
HTC HD2: If set SetPhotoResolution() is called FindPin will return E_FAIL. If not, it will create a file full of null bytes. HTC HD: Works
void Camera::TakePicture(WCHAR *fileName)
{
CComPtr<IFileSinkFilter> fileSink;
CComPtr<IPin> stillPin;
CComPtr<IUnknown> unknownCaptureFilter;
CComPtr<IAMVideoControl> videoControl;
_imageSinkFilter.QueryInterface(&fileSink);
fileSink->SetFileName(fileName, NULL);
_videoCaptureFilter.QueryInterface(&unknownCaptureFilter);
_captureGraphBuilder->FindPin(unknownCaptureFilter, PINDIR_OUTPUT,
&PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0, &stillPin);
_videoCaptureFilter.QueryInterface(&videoControl);
videoControl->SetMode(stillPin, VideoControlFlag_Trigger);
}
Set resolution: Works great on HTC HD2. HTC HD won't allow SetVideoResolution() and only offers one low resolution photo resolution:
Code:
void Camera::SetVideoResolution(int width, int height)
{
SetResolution(true, width, height);
}
void Camera::SetPhotoResolution(int width, int height)
{
SetResolution(false, width, height);
}
void Camera::SetResolution(bool video, int width, int height)
{
IAMStreamConfig *config;
config = NULL;
if (video)
{
_captureGraphBuilder->FindInterface(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, _videoCaptureFilter, IID_IAMStreamConfig,
(void**) &config);
}
else
{
_captureGraphBuilder->FindInterface(&PIN_CATEGORY_STILL,
&MEDIATYPE_Video, _videoCaptureFilter, IID_IAMStreamConfig,
(void**) &config);
}
int resolutions, size;
VIDEO_STREAM_CONFIG_CAPS caps;
config->GetNumberOfCapabilities(&resolutions, &size);
for (int i = 0; i < resolutions; i++)
{
AM_MEDIA_TYPE *mediaType;
if (config->GetStreamCaps(i, &mediaType,
reinterpret_cast<BYTE*>(&caps)) == S_OK )
{
int maxWidth = caps.MaxOutputSize.cx;
int maxHeigth = caps.MaxOutputSize.cy;
if(maxWidth == width && maxHeigth == height)
{
VIDEOINFOHEADER *info =
reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);
info->bmiHeader.biWidth = maxWidth;
info->bmiHeader.biHeight = maxHeigth;
info->bmiHeader.biSizeImage = DIBSIZE(info->bmiHeader);
config->SetFormat(mediaType);
DeleteMediaType(mediaType);
break;
}
DeleteMediaType(mediaType);
}
}
}
Other methods used to build the filter graph and create the COM objects:
v
Code:
oid Camera::CreateComObjects()
{
CoInitialize(NULL);
CoCreateInstance(CLSID_CaptureGraphBuilder, NULL, CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void **) &_captureGraphBuilder);
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **) &_filterGraph);
CoCreateInstance(CLSID_VideoCapture, NULL, CLSCTX_INPROC,
IID_IBaseFilter, (void**) &_videoCaptureFilter);
CoCreateInstance(CLSID_IMGSinkFilter, NULL, CLSCTX_INPROC,
IID_IBaseFilter, (void**) &_imageSinkFilter);
}
void Camera::InitializeVideoFilter()
{
_videoCaptureFilter->QueryInterface(&_propertyBag);
wchar_t deviceName[MAX_PATH] = L"\0";
GetDeviceName(deviceName);
CComVariant comName = deviceName;
CPropertyBag propertyBag;
propertyBag.Write(L"VCapName", &comName);
_propertyBag->Load(&propertyBag, NULL);
_filterGraph->AddFilter(_videoCaptureFilter,
L"Video Capture Filter Source");
}
void Camera::InitializeStillImageFilter()
{
_filterGraph->AddFilter(_imageSinkFilter, L"Still image filter");
_captureGraphBuilder->RenderStream(&PIN_CATEGORY_STILL,
&MEDIATYPE_Video, _videoCaptureFilter, NULL, _imageSinkFilter);
}
void Camera::GetDeviceName(WCHAR *deviceName)
{
HRESULT hr = S_OK;
HANDLE handle = NULL;
DEVMGR_DEVICE_INFORMATION di;
GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, 0x93, 0x3E,
0x4D, 0x7E, 0x3C, 0x86 };
di.dwSize = sizeof(di);
handle = FindFirstDevice(DeviceSearchByGuid, &guidCamera, &di);
StringCchCopy(deviceName, MAX_PATH, di.szLegacyName);
}
Full header file:
Code:
#ifndef __CAMERA_H__
#define __CAMERA_H__
class Camera
{
public:
void Init();
void DisplayVideoPreview(HWND windowHandle);
void TakePicture(WCHAR *fileName);
void SetVideoResolution(int width, int height);
void SetPhotoResolution(int width, int height);
private:
CComPtr<ICaptureGraphBuilder2> _captureGraphBuilder;
CComPtr<IGraphBuilder> _filterGraph;
CComPtr<IBaseFilter> _videoCaptureFilter;
CComPtr<IPersistPropertyBag> _propertyBag;
CComPtr<IMediaControl> _mediaControl;
CComPtr<IAMVideoControl> _videoControl;
CComPtr<IBaseFilter> _imageSinkFilter;
void GetDeviceName(WCHAR *deviceName);
void InitializeVideoFilter();
void InitializeStillImageFilter();
void CreateComObjects();
void SetResolution(bool video, int width, int height);
};
#endif
Hey, in the FindInterface for the you're not checking the return code, which has to be S_OK; if not, the config is NULL and using config-> will cause your crash. If FindInterface for PIN_CATEGORY_PREVIEW is failing, try FindInterface for PIN_CATEGORY_CAPTURE.

Developing in C# possible?

I have no knowledge of Silverlight or XNA, I downloaded the Development tools, but I want to know if its possible to develop in C# even though it wont be native.............
thanx in advance
just for your understanding you can never code native with C# - therefore you'd need C/C++.
Silverlight and XNA development on WP7 is only supported in C# initially so it seems you're all ready!
didn't you check the code sample included in the Devtools?
RAMMANN said:
just for your understanding you can never code native with C# - therefore you'd need C/C++.
Silverlight and XNA development on WP7 is only supported in C# initially so it seems you're all ready!
didn't you check the code sample included in the Devtools?
Click to expand...
Click to collapse
I havent checked the sample codes yet, so I can code entirely in C# no silverlight knowledge needed?
I believe, you'll need to use Expression Blend to put your code behind a fancy Silverlight UI.
Doesn't seem that hard if you follow the training school videos school at http://www.microsoft.com/design/toolbox/
it's exactly the same like you used to develop with .NETCF though you have another bag of assemblies referenced. so stuff like file/registry access or PInvoke are gone. see it yourself:
/*
Copyright (c) 2010 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;
using Microsoft.Phone.Shell;
namespace AccelerometerSample
{
/// <summary>
/// This sample shows how to use the device's accelerometer
/// </summary>
public partial class MainPage : PhoneApplicationPage
{
AccelerometerSensor accelerometer;
#region Initialization
/// <summary>
/// Constructor for the PhoneApplicationPage object.
/// In this method, the Application Bar is initialized.
/// </summary>
public MainPage()
{
InitializeComponent();
ApplicationBar = new ApplicationBar();
ApplicationBar.Visible = true;
ApplicationBarIconButton startStopButton = new ApplicationBarIconButton(new Uri("/Images/startstop.png", UriKind.Relative));
startStopButton.Click += new EventHandler(startStopButton_Click);
ApplicationBar.Buttons.Add(startStopButton);
}
#endregion
#region User Interface
/// <summary>
/// Click handler for the start/stop button.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void startStopButton_Click(object sender, EventArgs e)
{
// If the accelerometer is null, it is initialized and started
if (accelerometer == null)
{
// Get the default accelerometer for the device
accelerometer = AccelerometerSensor.Default;
// Add an event handler for the ReadingChanged event.
accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingAsyncEventArgs>(accelerometer_ReadingChanged);
// The Start method could throw and exception, so use a try block
try
{
statusTextBlock.Text = "starting accelerometer";
accelerometer.Start();
}
catch (AccelerometerStartFailedException exception)
{
statusTextBlock.Text = "error starting accelerometer";
}
}
else
{
// if the accelerometer is not null, call Stop
try
{
accelerometer.Stop();
accelerometer = null;
statusTextBlock.Text = "accelerometer stopped";
}
catch (AccelerometerStopFailedException exception)
{
statusTextBlock.Text = "error stopping accelerometer";
}
}
}
#endregion
#region Accelerometer Event Handling
/// <summary>
/// The event handler for the accelerometer ReadingChanged event.
/// BeginInvoke is used to pass this event args object to the UI thread.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void accelerometer_ReadingChanged(object sender, AccelerometerReadingAsyncEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() => MyReadingChanged(e));
}
/// <summary>
/// Method for handling the ReadingChanged event on the UI thread.
/// This sample just displays the reading value.
/// </summary>
/// <param name="e"></param>
void MyReadingChanged(AccelerometerReadingAsyncEventArgs e)
{
statusTextBlock.Text = accelerometer.State.ToString();
XTextBlock.Text = e.Value.Value.X.ToString("0.00");
YTextBlock.Text = e.Value.Value.Y.ToString("0.00");
ZTextBlock.Text = e.Value.Value.Z.ToString("0.00");
}
#endregion
}
}
Click to expand...
Click to collapse
You need Silverlight or XNA knowledge, but the language is C#! Silverlight and XNA are just the Framework to use for developing Apps...it's still C#.
dragi
silverlight is the ui aspect of your app
there are things you will need to know about silverlight to get your information from say a database to display on fields of your application.
xna is for gaming programming (gpu interfacing, its what is used for console and zune game programming).
Thanx all!
I think I understand it now.
The developing is still being done in C# but you Need knowledge of Silverlight and XNA to use those Frameworks!
I think I will start with something really simple drawing an image on the screen

Closing gps in gps event handler - endless loop

In my application when I get position latitude and longitude from GPS, I am downloading bing map to a picture box. I've been trying now to protect my application in case there is no internet connection. I've done that in the GetMap function and it works fine. After that I want to close gps - the problem is that I'm trying to do that in gps event handler - it is so because I update the picture box constantly:
Code:
void UpdateData(object sender, System.EventArgs args)
{
menuGPS.Text = "Enable GPS";
menuZoom.Enabled = false;
menuView.Enabled = false;
}
void gps_LocationChanged(object sender, Microsoft.WindowsMobile.Samples.Location.LocationChangedEventArgs args)
{
if (args.Position.LatitudeValid && args.Position.LongitudeValid)
{
if (isCameraEnabled == false)
{
try
{
pbMap.Invoke((UpdateMap)delegate()
{
pbMap.Image = bingMap.GetMap(args.Position.Latitude,
args.Position.Longitude,
zoom,
mapStyle);
});
if (pbMap.Image == null)
{
Invoke(updateDataHandler);
gpsData.gps.LocationChanged -= gps_LocationChanged;
gpsData.closeGPS();
}
}
catch (ArgumentException ex)
{
MessageBox.Show("An error has occured:" + ex.Message , "Error");
}
}
else
{
}
}
}
So after the gpsData.gps.LocationChanged -= gps_LocationChanged; and gpsData.closeGPS(); are being called in the event handler the gps gets stuck in the WaitForGpsEvents() method in GPS.cs in the while loop because bool lisening value is not changed to false.
If I put gpsData.gps.LocationChanged -= gps_LocationChanged; and gpsData.closeGPS(); to the void UpdateData(object sender, System.EventArgs args) then it stops in the Close() method on the lock condition:
// block until our event thread is finished before
// we close our native event handles
lock (this)
How can I close the GPS?

Hooking a protected List in an Inner Class with an odd set of Parameters

So, I'm getting fairly good at hooking and modifying classes, but this one is so unique, I'm not quite sure how to approach hooking it to do what I want. Code for the method/class I want to attack:
Code:
private class CreateLaunchPointListTask
extends AsyncTask<Void, Void, List<LaunchPoint>>
{
private CreateLaunchPointListTask() {}
protected List<LaunchPoint> doInBackground(Void... paramVarArgs)
{
paramVarArgs = mContext.getString(2131558445);
Object localObject = new Intent("android.intent.action.MAIN");
((Intent)localObject).addCategory(paramVarArgs);
paramVarArgs = new LinkedList();
PackageManager localPackageManager = mContext.getPackageManager();
localObject = localPackageManager.queryIntentActivities((Intent)localObject, 129);
int j = ((List)localObject).size();
int i = 0;
while (i < j)
{
ResolveInfo localResolveInfo = (ResolveInfo)((List)localObject).get(i);
if (activityInfo != null) {
paramVarArgs.add(new LaunchPoint(mContext, localPackageManager, localResolveInfo));
}
i += 1;
}
return paramVarArgs;
}
public void onPostExecute(List<LaunchPoint> arg1)
{
synchronized (mLock)
{
mAllLaunchPoints.clear();
mAllLaunchPoints.addAll(???);
synchronized (mCachedActions)
{
LaunchPointListGenerator.access$502(LaunchPointListGenerator.this, true);
if (!mCachedActions.isEmpty()) {
((LaunchPointListGenerator.CachedAction)mCachedActions.remove()).apply();
}
}
}
LaunchPointListGenerator.access$602(LaunchPointListGenerator.this, true);
Iterator localIterator = mListeners.iterator();
while (localIterator.hasNext()) {
((LaunchPointListGenerator.Listener)localIterator.next()).onLaunchPointListGeneratorReady();
}
}
}
So, while this is a big chunk of code, everything I want to do is really in the first few lines:
Code:
paramVarArgs = mContext.getString(2131558445);
Object localObject = new Intent("android.intent.action.MAIN");
((Intent)localObject).addCategory(paramVarArgs);
So, string 2131558445 is a specific intent. What I would like to do is add *another* category after 2131558445 is added to localObject.
That would be the simplest implementation.
A more advanced implementation would be to actually and return a second LinkedList, paramVarArgs2, that only matches up to the second intent category that we're inserting.
Any help would be greatly appreciated.

Reducing module memory footprint

Hello fellow devs
It's a well known fact that all modules are loaded into all processes, even if they have nothing to do with them, which makes a pretty big difference if you have ~20 modules active and ~30 processes running.
Would something like this prevent the situation from happening?
Code:
public final class XposedInit implements IXposedHookLoadPackage
{
// Only one field and one method which means small memory footprint?
private IXposedHookLoadPackage mainModule = null;
@Override
public final void handleLoadPackage(final LoadPackageParam lpp) throws Throwable
{
// Hardcode the packages we really use
if (lpp.packageName.equals("android") || lpp.packageName.equals(getClass().getPackage().getName()))
{
// Initialize the real part of the module only if it's really going to be used
if (mainModule == null) mainModule = new MyMainGrandModule();
mainModule.handleLoadPackage(lpp);
}
}
}
Any insight appreciated.

Categories

Resources