Help with callback function in code converted to a class
by Paul Griffiths · in Torque Game Engine · 05/29/2006 (4:24 am) · 21 replies
I'm adding a web-cam video capture library to Torque codevis.com/vidcapture/index.html and i have images saved to files working.
But I'm having a problem with a callback function.
I took a code example and converted it to a class but a callback function is creating an error.
The error is:
c:\Torque\SDK\engine\TMessenger\VideoCapture.h(395): error C2664: 'CVVidCapture::StartImageCap' : cannot convert parameter 2 from 'bool (CVRES,CVImage *,void *)' to 'CVVidCapture::CVVIDCAP_CALLBACK'
The original example code was:
and i put this inside a class, thus it's now:
It's called in a line of code:
I'm quite new to c++ so I'm stumped! Any ideas?
But I'm having a problem with a callback function.
I took a code example and converted it to a class but a callback function is creating an error.
The error is:
c:\Torque\SDK\engine\TMessenger\VideoCapture.h(395): error C2664: 'CVVidCapture::StartImageCap' : cannot convert parameter 2 from 'bool (CVRES,CVImage *,void *)' to 'CVVidCapture::CVVIDCAP_CALLBACK'
The original example code was:
//-------------------------------------------------------------------------
// capCallback is the main image capture callback.
//
// We play with the image a bit inside to test out
// CVImage's functions.
//
bool capCallback( CVRES status,
CVImage* imagePtr,
void* userParam)
{
static int xOffset = 0;
static int yOffset = 0;
...
return true;
}and i put this inside a class, thus it's now:
//-------------------------------------------------------------------------
// capCallback is the main image capture callback.
//
// We play with the image a bit inside to test out
// CVImage's functions.
//
bool GuiVideoCameraCapture::capCallback( CVRES status,
CVImage* imagePtr,
void* userParam)
{
static int xOffset = 0;
static int yOffset = 0;
...
return true;
}It's called in a line of code:
started = CVSUCCESS(vidCap->StartImageCap(CVImage::CVIMAGE_GREY, capCallback,0));
I'm quite new to c++ so I'm stumped! Any ideas?
#2
Simply put, the function/method you're passing into StartImageCap needs to be a standard C function and not associated with any namespace.
Unfortunately it's difficult to work around a modular solution to this problem. You might want to consider using a friend function as a wrap-around for it, and that's the best I can think of.
There's a better explaination to why this is a problem found on the C++ Faq site here.
- Eric
05/29/2006 (7:49 am)
It looks like your StartImageCap is asking for a callback function that's a C function pointer as apposed to a C++ method pointer (I'm not entirely certain about the name of function pointers to methods in C++).Simply put, the function/method you're passing into StartImageCap needs to be a standard C function and not associated with any namespace.
Unfortunately it's difficult to work around a modular solution to this problem. You might want to consider using a friend function as a wrap-around for it, and that's the best I can think of.
There's a better explaination to why this is a problem found on the C++ Faq site here.
- Eric
#3
05/29/2006 (9:14 am)
Use a static function.
#4
Isn't guarenteed to work.
It will generally complain about how it can't convert from bool (GuiVideoCameraCapture::capCallback*)(CVRES,CVImage *,void *) to CVVidCapture::CVVIDCAP_CALLBACK (or whatever the exact syntax is). The static method will still be associated with the class namespace and AFAIK you cannot cast a static method pointer into a c function pointer - I believe it's mentioned somewhere on the link I showed above.
- Eric
05/29/2006 (9:34 am)
Quote:
Use a static function.
Isn't guarenteed to work.
It will generally complain about how it can't convert from bool (GuiVideoCameraCapture::capCallback*)(CVRES,CVImage *,void *) to CVVidCapture::CVVIDCAP_CALLBACK (or whatever the exact syntax is). The static method will still be associated with the class namespace and AFAIK you cannot cast a static method pointer into a c function pointer - I believe it's mentioned somewhere on the link I showed above.
- Eric
#5
05/29/2006 (10:29 am)
I tried making a wrapper and also tried making a static function , but no such luck which is a shame. I still got image capture but not video capture.
#7
Unless you're a C++ Standard evangelist, casting a static member function to a C function pointer will work on almost all modern C++ compilers, and you can pass the pointer to the object in the userParam.
However, a more correct way to do what you want to do is to just use a C function and pass the 'this' pointer of your object to the C function, and then call a member function of your class from within the C function. i.e.:
And just make your class method a regular (non-static) method. i.e:
Note that you don't really need the userParam argument in your member function at this point.
05/29/2006 (11:13 am)
Quote:
It will generally complain about how it can't convert from bool (GuiVideoCameraCapture::capCallback*)(CVRES,CVImage *,void *) to CVVidCapture::CVVIDCAP_CALLBACK (or whatever the exact syntax is). The static method will still be associated with the class namespace and AFAIK you cannot cast a static method pointer into a c function pointer - I believe it's mentioned somewhere on the link I showed above.
Unless you're a C++ Standard evangelist, casting a static member function to a C function pointer will work on almost all modern C++ compilers, and you can pass the pointer to the object in the userParam.
However, a more correct way to do what you want to do is to just use a C function and pass the 'this' pointer of your object to the C function, and then call a member function of your class from within the C function. i.e.:
bool capCallback( CVRES status, CVImage* imagePtr, void* userParam)
{
GuiVideoCameraCapture* camCap = (GuiVideoCameraCapture*)userParam;
return camCap->capCallback( status, imagePtr );
}
.....
started = CVSUCCESS(vidCap->StartImageCap(CVImage::CVIMAGE_GREY, capCallback, [b]this[/b] ));And just make your class method a regular (non-static) method. i.e:
bool GuiVideoCameraCapture::capCallback( CVRES status, CVImage* imagePtr )
{
static int xOffset = 0;
static int yOffset = 0;
return true;
}Note that you don't really need the userParam argument in your member function at this point.
#8
and pass an instance of that structure as the userParam.
05/29/2006 (11:19 am)
Unless of course, you need to pass something else in your userParam. In that case, you can make a small structure, i.e.:struct UserParamStruct
{
GuiVideoCameraCapture* mObject;
void* mUserParam;
};and pass an instance of that structure as the userParam.
#9
It will generally complain about how it can't convert from bool (GuiVideoCameraCapture::capCallback*)(CVRES,CVImage *,void *) to CVVidCapture::CVVIDCAP_CALLBACK (or whatever the exact syntax is). The static method will still be associated with the class namespace and AFAIK you cannot cast a static method pointer into a c function pointer - I believe it's mentioned somewhere on the link I showed above.
[/quote]
You are referring to www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2. It's true that it's not guaranteed to work by the C++ standard, nonetheless it does work on all compilers that I know of and that includes all compilers supported by Torque. On those compilers a static member function behaves exactly the same as a regular "free" function. BTW, there is no "association" between a static method and the class namespace. In fact there's is no concept in C++ as a "class namespace". There's a "class scope" concept in C++, but it's quite different. Don't make confusion between C++ and TorqueScript ;)
What Paul needs is simply:
1) declare a non-static method GuiVideoCameraCapture::capCallback like the one above
2) declare a static method GuiVideoCameraCapture::capCallbackStatic like this:
3) assuming that you invoke StartImageCap from inside a method of class GuiVideoCameraCapture, the invocation will be:
If you still get errors, please post the exact definition of CVVidCapture::CVVIDCAP_CALLBACK, as it is might declare a calling convention (such as __stdcall), in which case the calling convention must be added to the declaration of capCallbackStatic.
05/29/2006 (11:25 am)
Quote:Isn't guarenteed to work.
[quote]
Use a static function.
It will generally complain about how it can't convert from bool (GuiVideoCameraCapture::capCallback*)(CVRES,CVImage *,void *) to CVVidCapture::CVVIDCAP_CALLBACK (or whatever the exact syntax is). The static method will still be associated with the class namespace and AFAIK you cannot cast a static method pointer into a c function pointer - I believe it's mentioned somewhere on the link I showed above.
[/quote]
You are referring to www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2. It's true that it's not guaranteed to work by the C++ standard, nonetheless it does work on all compilers that I know of and that includes all compilers supported by Torque. On those compilers a static member function behaves exactly the same as a regular "free" function. BTW, there is no "association" between a static method and the class namespace. In fact there's is no concept in C++ as a "class namespace". There's a "class scope" concept in C++, but it's quite different. Don't make confusion between C++ and TorqueScript ;)
What Paul needs is simply:
1) declare a non-static method GuiVideoCameraCapture::capCallback like the one above
bool GuiVideoCameraCapture::capCallback(CVRES status, CVImage* imagePtr)
{
static int xOffset = 0;
static int yOffset = 0;
...
return true;
}notice that the userParam parameter has been removed.2) declare a static method GuiVideoCameraCapture::capCallbackStatic like this:
bool GuiVideoCameraCapture::capCallbackStatic(CVRES status, CVImage* imagePtr, void* userParam)
{
return static_cast<GuiVideoCameraCapture*>(userParam)->capCallback(status, imagePtr);
}3) assuming that you invoke StartImageCap from inside a method of class GuiVideoCameraCapture, the invocation will be:
started = CVSUCCESS(vidCap->StartImageCap(CVImage::CVIMAGE_GREY, capCallbackStatic, this));Notice the "this" instead of the "0" as the last parameter.
If you still get errors, please post the exact definition of CVVidCapture::CVVIDCAP_CALLBACK, as it is might declare a calling convention (such as __stdcall), in which case the calling convention must be added to the declaration of capCallbackStatic.
#10
c:\Torque\SDK\engine\TMessenger\VideoCapture.h(410): error C2664: 'CVVidCapture::StartImageCap' : cannot convert parameter 2 from 'bool (CVRES,CVImage *,void *)' to 'CVVidCapture::CVVIDCAP_CALLBACK'
I'm guessing the definition is:
typedef bool (*CVVIDCAP_CALLBACK)( CVRES status,
CVImage* imagePtr,
void* userParam );
05/29/2006 (1:33 pm)
Alberto, i tried your idea and still have errors:c:\Torque\SDK\engine\TMessenger\VideoCapture.h(410): error C2664: 'CVVidCapture::StartImageCap' : cannot convert parameter 2 from 'bool (CVRES,CVImage *,void *)' to 'CVVidCapture::CVVIDCAP_CALLBACK'
I'm guessing the definition is:
typedef bool (*CVVIDCAP_CALLBACK)( CVRES status,
CVImage* imagePtr,
void* userParam );
#11
05/29/2006 (1:37 pm)
Heres a cut down version of what i have done:#if (defined(STOP_BEFORE_EXIT) || defined(LOOP_TEST))
#include <conio.h>
#endif
#ifdef STOP_BEFORE_EXIT
// Clear any existing keystrokes, then wait for a final one on exit.
#define EXIT_MACRO printf("Press any key to exit...\n"); \
while (kbhit()) {getch();} \
getch();
#else
#define EXIT_MACRO
#endif
#include <stdio.h>
#include "VidCapture.h"
// You only need to include this if you plan on using CodeVis utility
// or tracing functions
#include "CVUtil.h"
class GuiVideoCameraCapture
{
bool TestIt();
void CaptureFrame();
bool enumCallback( const char* devname,
void* userParam);
bool capCallback ( CVRES status,
CVImage* image);
void SlowNegateImage(CVImage* image);
// Global test device name
char gDeviceName[256];
// Global frame count
int gFrameNum; // Offset
// Global device number
int gDevNum;
CVImage* grabImage;
public:
GuiVideoCameraCapture();
char imageData;
unsigned char getImage(){grabImage->GetRawDataPtr();}
int getImageSize(){grabImage->AbsSize();}
bool GuiVideoCameraCapture::capCallbackStatic(CVRES status, CVImage* imagePtr, void* userParam){ return static_cast<GuiVideoCameraCapture*>(userParam)->capCallback(status, imagePtr);}
};
GuiVideoCameraCapture::GuiVideoCameraCapture(void) {
// Global frame count
gFrameNum = 0; // Offset
// Global device number
gDevNum = 0;
CaptureFrame();
}
//-------------------------------------------------------------------------
// Callback for enumeration of capture devices.
//
// We're just saving the first one that comes by
// into gDeviceName[] and using it.
bool GuiVideoCameraCapture::enumCallback(const char* devname, void* userParam)
{
// if (gDevNum < 1) // use the first device
if (gDevNum <= 1) // use the second device
{
dStrcpy(gDeviceName,devname);
}
gDevNum++;
printf("Device: %s\n",devname);
return true;
}
//-------------------------------------------------------------------------
// capCallback is the main image capture callback.
//
// We play with the image a bit inside to test out
// CVImage's functions.
//
bool GuiVideoCameraCapture::capCallback( CVRES status, CVImage* imagePtr)
{
static int xOffset = 0;
static int yOffset = 0;
// Only try to work with the image pointer if the
// status is successful!
if (CVSUCCESS(status))
{
char framePath[260];
sprintf(framePath,"cap_frame_%d",gFrameNum);
CVAssert(imagePtr != 0, "This shouldn't happen. Bad image pointer.");
printf("Captured frame %d.\n", gFrameNum);
// Create a sub image
CVImage* subImg = 0;
int subWidth = imagePtr->Width() / 4;
int subHeight = imagePtr->Height() / 5;
if (CVFAILED(CVImage::CreateSub( imagePtr,
subImg,
xOffset,
yOffset,
subWidth,
subHeight)))
{
printf("Failed creating sub image!\n");
}
else
{
// Negate the sub image
SlowNegateImage(subImg);
// Create a sub image of the sub image 5 pixels in from each side
CVImage *subSubImg = 0;
if (CVFAILED(CVImage::CreateSub( subImg,
subSubImg,
5,
5,
subWidth-10,
subHeight-10)))
{
printf("Failed creating sub image of sub image\n");
// Release first sub image
CVImage::ReleaseImage(subImg);
}
else
{
// Release first sub image
// (this shouldn't delete subImg - subSubImg holds a reference)
CVImage::ReleaseImage(subImg);
// Negate subSubImg - this should restore the center of subImg
// area to its original colors, just leaving a 5 pixel border of
// negative around it.
SlowNegateImage(subSubImg);
// Release subSubImg
CVImage::ReleaseImage(subSubImg);
}
// Setup offsets for next sub image
xOffset += subWidth;
yOffset += subHeight;
if (imagePtr->Width() - xOffset < subWidth)
{
xOffset = 0;
}
if (imagePtr->Height() - yOffset < subHeight)
{
yOffset = 0;
}
}
// Save the base image
if (CVFAILED(CVImage::Save(framePath, imagePtr)))
{
printf("Failed saving image!\n");
}
gFrameNum++;
}
else
{
// From here, you'd usually want to signal your main thread
// that the capture has been terminated. This is the only notice
// you'll receive - no more callbacks after this.
//
// In this example, since we're just sleeping briefly, there's
// no need to signal the main thread.
//
printf("Capture failure in callback! Did you disconnect camera?\n");
}
// Halt on frame 25 just to test halting from within a callback.
if (gFrameNum == 25)
{
printf("Halting prematurely to test callback exit codes.\n");
printf("Returning false here should abort the capture.\n");
// Of course, you'll still need to call CVVidCapture::Stop()
// from the main thread to clean up.
return false;
}
return true;
}
//-------------------------------------------------------------------------
// SlowNegateImage() is a slow routine to negate an image.
//
// Works on any image type where the pixel values are 0-255,
// but it recalculates each pixel location in addition to
// having 2 subroutine calls per pixel - lots of overhead.
// Good for testing CVImage::GetPixel() and CVImage::SetPixel() though.
//
void GuiVideoCameraCapture::SlowNegateImage(CVImage* image)
{
// Verify that our getpixel/setpixel stuff works even
// on sub images by creating a negative within the
// sub image, then saving the parent (which should
// now have a negative rectangle in it)
for (int x = 0; x < image->Width(); x++)
{
for (int y=0; y < image->Height(); y++)
{
float r,g,b;
if (CVFAILED(image->GetPixel(x,y,r,g,b)))
{
printf("GetPixel Error!\n");
}
else
{
// Assumes images are 0-255. If not, this will
// generate funky results.
r = 255.0f - r;
g = 255.0f - g;
b = 255.0f - b;
if (CVFAILED(image->SetPixel(x,y,r,g,b)))
{
printf("SetPixel Error!\n");
}
}
}
}
}
#12
To this:
05/29/2006 (2:01 pm)
@Paul, try changing this:started = CVSUCCESS(vidCap->StartImageCap(CVImage::CVIMAGE_GREY, capCallbackStatic, this));
To this:
started = CVSUCCESS(vidCap->StartImageCap(CVImage::CVIMAGE_GREY, (CVVidCapture::CVVIDCAP_CALLBACK)capCallbackStatic, this));
#13
c:\Torque\SDK\engine\TMessenger\VideoCapture.h(410): error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'CVVidCapture::CVVIDCAP_CALLBACK'
05/29/2006 (2:10 pm)
No, i get:c:\Torque\SDK\engine\TMessenger\VideoCapture.h(410): error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'CVVidCapture::CVVIDCAP_CALLBACK'
#14
to this:
05/29/2006 (2:23 pm)
Ah, okay. You need to make capCallbackStatic a static method. Change this:bool GuiVideoCameraCapture::capCallbackStatic(CVRES status, CVImage* imagePtr, void* userParam){ return static_cast<GuiVideoCameraCapture*>(userParam)->capCallback(status, imagePtr);}to this:
static bool capCallbackStatic(CVRES status, CVImage* imagePtr, void* userParam){ return static_cast<GuiVideoCameraCapture*>(userParam)->capCallback(status, imagePtr);}
#15
05/29/2006 (2:27 pm)
Gerald, that compiled ok, thanks all!
#16
Next i have to render it to a gui. Any ideas?
05/29/2006 (2:46 pm)
Yes, thanks all that works fine, i now have a continuous stream of webcam captured images to files.Next i have to render it to a gui. Any ideas?
#17
when i create an instance of the class above and try to access some of it's functions, it always returns 0?
I create it by:
one of it's functions is
i access it by:
It always returns 0, though i know gFrameNum increases because it's used to name files saved to my harddrive which works.
Heres my full code:
05/29/2006 (5:48 pm)
Why always 0?when i create an instance of the class above and try to access some of it's functions, it always returns 0?
I create it by:
gvcc = new GuiVideoCameraCapture();
one of it's functions is
int getImageCount(){return gFrameNum;}i access it by:
int frameNumber = gvcc->getImageCount()
It always returns 0, though i know gFrameNum increases because it's used to name files saved to my harddrive which works.
Heres my full code:
#18
05/29/2006 (5:50 pm)
GuiVideoCameraCtrl.h//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _GUIVIDEOCAMERACONTROL_H_
#define _GUIVIDEOCAMERACONTROL_H_
#ifndef _GUICONTROL_H_
#include "gui/core/guiControl.h"
#endif
#ifndef _GTEXMANAGER_H_
#include "dgl/gTexManager.h"
#endif
#include "videoCapture.h"
/// Renders a bitmap.
class GuiVideoCameraCtrl : public GuiControl
{
private:
typedef GuiControl Parent;
protected:
StringTableEntry mBitmapName;
TextureHandle mTextureHandle;
Point2I startPoint;
bool mWrap;
GuiVideoCameraCapture* gvcc;
public:
//creation methods
DECLARE_CONOBJECT(GuiVideoCameraCtrl);
GuiVideoCameraCtrl();
static void initPersistFields();
//Parental methods
bool onWake();
void onSleep();
void inspectPostApply();
void setBitmap(const char *name,bool resize = false);
void setBitmap(const TextureHandle &handle,bool resize = false);
S32 getWidth() const { return(mTextureHandle.getWidth()); }
S32 getHeight() const { return(mTextureHandle.getHeight()); }
void onRender(Point2I offset, const RectI &updateRect);
void setValue(S32 x, S32 y);
};
#endif
#19
If i try to access the frame count or the image itself it returns 0 or null. I'm used to java.
05/29/2006 (5:51 pm)
GuiVideoCameraCtrl.cc//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "console/console.h"
#include "console/consoleTypes.h"
#include "dgl/dgl.h"
#include "GuiVideoCameraCtrl.h"
IMPLEMENT_CONOBJECT(GuiVideoCameraCtrl);
GuiVideoCameraCtrl::GuiVideoCameraCtrl(void)
{
mBitmapName = StringTable->insert("");
startPoint.set(0, 0);
mWrap = false;
gvcc = new GuiVideoCameraCapture();
}
void GuiVideoCameraCtrl::initPersistFields()
{
Parent::initPersistFields();
addGroup("Misc");
addField("bitmap", TypeFilename, Offset(mBitmapName, GuiVideoCameraCtrl));
addField("wrap", TypeBool, Offset(mWrap, GuiVideoCameraCtrl));
endGroup("Misc");
}
ConsoleMethod( GuiVideoCameraCtrl, setValue, void, 4, 4, "(int xAxis, int yAxis)"
"Set the offset of the bitmap.")
{
object->setValue(dAtoi(argv[2]), dAtoi(argv[3]));
}
ConsoleMethod( GuiVideoCameraCtrl, setBitmap, void, 3, 3, "(string filename)"
"Set the bitmap displayed in the control. Note that it is limited in size, to 256x256.")
{
object->setBitmap(argv[2]);
}
bool GuiVideoCameraCtrl::onWake()
{
if (! Parent::onWake())
return false;
setActive(true);
setBitmap(mBitmapName);
return true;
}
void GuiVideoCameraCtrl::onSleep()
{
mTextureHandle = NULL;
Parent::onSleep();
}
//-------------------------------------
void GuiVideoCameraCtrl::inspectPostApply()
{
// if the extent is set to (0,0) in the gui editor and appy hit, this control will
// set it's extent to be exactly the size of the bitmap (if present)
Parent::inspectPostApply();
if (!mWrap && (mBounds.extent.x == 0) && (mBounds.extent.y == 0) && mTextureHandle)
{
TextureObject *texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
}
}
void GuiVideoCameraCtrl::setBitmap(const char *name, bool resize)
{
mBitmapName = StringTable->insert(name);
if (*mBitmapName) {
mTextureHandle = TextureHandle(mBitmapName, BitmapTexture, true);
// Resize the control to fit the bitmap
if (resize) {
TextureObject* texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
Point2I extent = getParent()->getExtent();
parentResized(extent,extent);
}
}
else
mTextureHandle = NULL;
setUpdate();
}
void GuiVideoCameraCtrl::setBitmap(const TextureHandle &handle, bool resize)
{
mTextureHandle = handle;
// Resize the control to fit the bitmap
if (resize) {
TextureObject* texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
Point2I extent = getParent()->getExtent();
parentResized(extent,extent);
}
}
void GuiVideoCameraCtrl::onRender(Point2I offset, const RectI &updateRect)
{
if (mTextureHandle)
{
dglClearBitmapModulation();
if(mWrap)
{
TextureObject* texture = (TextureObject *) mTextureHandle;
RectI srcRegion;
RectI dstRegion;
float xdone = ((float)mBounds.extent.x/(float)texture->bitmapWidth)+1;
float ydone = ((float)mBounds.extent.y/(float)texture->bitmapHeight)+1;
int xshift = startPoint.x%texture->bitmapWidth;
int yshift = startPoint.y%texture->bitmapHeight;
for(int y = 0; y < ydone; ++y)
for(int x = 0; x < xdone; ++x)
{
srcRegion.set(0,0,texture->bitmapWidth,texture->bitmapHeight);
dstRegion.set( ((texture->bitmapWidth*x)+offset.x)-xshift,
((texture->bitmapHeight*y)+offset.y)-yshift,
texture->bitmapWidth,
texture->bitmapHeight);
dglDrawBitmapStretchSR(texture,dstRegion, srcRegion, false);
}
}
else
{
RectI rect(offset, mBounds.extent);
dglDrawBitmapStretch(mTextureHandle, rect);
}
int intCapture;
if (gvcc->grabImage != NULL) {
intCapture = gvcc->grabImage->Width();
} else {
intCapture =0;
}
// Currently only displays min/sec
char buf[256];
dSprintf(buf,sizeof(buf), "Frame:%d",gvcc->getImageCount());
// Center the text
offset.x += (mBounds.extent.x - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;
offset.y += (mBounds.extent.y - mProfile->mFont->getHeight()) / 2;
//dglSetBitmapModulation(mTextColor);
dglDrawText(mProfile->mFont, offset, buf);
}
if (mProfile->mBorder || !mTextureHandle)
{
RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
dglDrawRect(rect, mProfile->mBorderColor);
}
renderChildControls(offset, updateRect);
}
void GuiVideoCameraCtrl::setValue(S32 x, S32 y)
{
if (mTextureHandle)
{
TextureObject* texture = (TextureObject *) mTextureHandle;
x+=texture->bitmapWidth/2;
y+=texture->bitmapHeight/2;
}
while (x < 0)
x += 256;
startPoint.x = x % 256;
while (y < 0)
y += 256;
startPoint.y = y % 256;
}If i try to access the frame count or the image itself it returns 0 or null. I'm used to java.
#20
05/30/2006 (12:58 am)
Quote:It always returns 0, though i know gFrameNum increases because it's used to name files saved to my harddrive which works.I'm sorry but it's difficult for me to debug such a long piece of code out of its context. Have you tried setting a breakpoint and inspecting the object with a debugger? Are you sure that gFrameNum really increases on that particular instance?
Torque Owner Paul Griffiths
virtual CVRES StartImageCap( CVImage::CVIMAGE_TYPE imageType,
CVVIDCAP_CALLBACK callback,
void* userParam) = 0;
Any ideas? Has virtual got anything to do with it?