Looping in OpenGL with glutTimerFunc(...) - glut

I want to create a program that draws some objects to scene using OpenGL, where I am continually changing the position of those object manually. To achieve this, I need to run some kind of loop where on each loop, it changes the position of the objects, and then draws to the screen, before repeating.
Given that glutMainLoop() is a non-returning function, and is also compulsory to run an OpenGL program, I need to run my loop with some sort of timer.
Now my solution which works is similar to the following:
void Render()
{
// Draw some objects using OpenGL
// ......
// ......
}
void Loop
{
// Update the positions of the objects
// ......
// ......
glutPostRedisplay();
glutTimerFunc(1, Loop, 0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
GlutCreateWindow("Test");
glutDisplayFunc(Render);
glutMainLoop();
glutTimerFunc(1, Loop, 0);
}
However, I am not sure I understand why there is the need for the glutTimerFunc() call in main(). Why can I not just replace it with a direct call to Loop()?
For example:
int main(int argc, char** argv)
{
glutInit(&argc, argv);
GlutCreateWindow("Test");
glutDisplayFunc(Render);
glutMainLoop();
Loop();
}
This does not work. The objects do not move on the screen as expected, and furthermore, then OpenGL window is totally unresponsive; I cannot even close it by clocking the cross on the title bar.
Surely glutTimerFunc(1, Loop, 0); just calls Loop() in the same way I have done in the second example, so why does this not work...?

Basically, the glutTimerFunc waits for a number of milliseconds to pass before calling the callback (in your case, Loop()). In this way it acts like a refresh operation.
Check out →GLUT API for more detail
void glutTimerFunc(unsigned int numMilliseconds, functionCallback, value);
So, that means you can pass in something like this:
glutTimerFunc(1000 / SCREEN_FPS, Loop, 0);
For extra info on main loops
deWitter's Gameloop
However, as your project gets more complex, you might find that you want the objects in your scenes rendering at constant speed. In addition to the glutTmerFunc, you can make you animations work with elapsed time - found by calculating the difference between the current time and previously current time.
Hope this helps!

Here's a really simple glutTimerFunc() example from a real program.
I wanted to hi-jack the title bar for command input. When you typed stuff, it appeared in the title bar and when you pressed return, it executed the command. I wanted a blinking cursor.
char title[80]; // This is where our keystrokes go.
char * cursor = NULL; // This points to the cursor character.
void cursorBlink(int id) {
if (cursor) {
*cursor = (*cursor == ' ') ? '_' : ' ';
glutSetWindowTitle(title);
glutTimerFunc(1000.0, cursorBlink, 0);
}
}
This isn't quite the whole thing. The ESC key gets us into command line entry mode. This sets up the title string and the cursor pointer, and it also has to make the first call to cursorBlink() to get the loop started. When command entry is done, the cursor point gets set back to NULL, and the loop shuts itself down.
The cursorBlink argument is not used. This is common with simple animations. Don't worry about it.

Related

Creating multiple windows in gtkmm

I started to learn gtkmm library and probably don't understand the way it works. Here's the problem: I've copied simple example from gtkmm tutorial, and want to modify it to create as many windows as I want by clicking the button.
Why can't I just write code like in function on_button_clicked() below?
class Hello : public Gtk::Window {
public:
Hello() :m_button("create copy") {
set_border_width(20);
m_button.signal_clicked().connect(sigc::mem_fun(*this, &Hello::on_button_clicked));
add(m_button);
show_all_children();
}
protected:
void on_button_clicked();
Gtk::Button m_button;
};
void Hello::on_button_clicked() {
Hello new_window;
new_window.show();
}
int main (int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
Hello hw;
return app->run(hw);
}
The reason a new window is not displayed is how C++ has been used in the method Hello::on_button_clicked().
The line :
Hello new_window;
creates a new window with local scope.
new_window.show();
This marks the window to be shown when GTK+ is back in control.
The line
}
exits the method and all local variables are destroyed. Which means that new_window is deleted before it can be seen.
To keep the window and have it shown the object must be stored so that it is not automatically destroyed. This could be allocated on the heap and a pointer kept to it in another class for easy access to the window.

Why the loop "scanf" method dead circle in objective-c lanuguage?

I write a small console program in objective-c. It need to use the scanf method to receive the number.When I enter a character, it will make a mistake.So I try to solve it,but it has entered a cycle of death! See the following code, to help me solve it, thank you very much!
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
int num1 = 0;
NSLog(#"Please input number:");
while (!scanf("%d", &num1)) {
fflush(stdin);
NSLog(#"Input error,just input number:");
}
}
return 0;
}
The documentation for fflush states:
The function fflush() forces a write of all buffered data for the given output or update stream via the
stream's underlying write function. The open status of the stream is unaffected.
and you are trying to flush input. Try fpurge:
The function fpurge() erases any input or output buffered in the given stream.
Also do not write !scanf(...). Check the documentation, this function returns an integer, not a boolean, and the value could be positive or negative (look up the definition of EOF). A negative value indicates an error, but the ! operator will yield false and your code would not ask for new input.
If successful scanf returns the number of items successfully parsed, check for that.
The documentation for all these functions is available via Xcode or the man command.
HTH

C Blocks indirection and misalignment

The following code throws an EXC_BAD_ACCESS error (specifically a general protection fault error) and I would like to know why you cannot misalign a block pointer and execute it.
#include <stdio.h>
int main(int argc, const char * argv[])
{
void (^blocky)() = ^{
printf("Hello!\n");
printf("Hello Again!\n");
};
blocky = *(&blocky+1);
blocky = *(&blocky-1);
blocky();
return 0;
}
But the following works:
#include <stdio.h>
int main(int argc, const char * argv[])
{
void (^blocky)() = ^{
printf("Hello!\n");
printf("Hello Again!\n");
};
blocky = *(&blocky+1-1);
blocky();
return 0;
}
Edit (answer to misaligning code blocks):
If you treat a block like a structure, you can find that the value that points to the executable code in memory is offset 16 bytes from the start of the block and is 8 bytes long.
You are able to change this value effectively pointing execution to another place in memory. Generally, this will crash.
Assuming you know the specific address in memory for another piece of executable code, you may direct it there.
Why this is useful:
It isn't. Never do this. Really. Never.
The pointer manipulation in the first example is wrong. Try this:
#include <stdio.h>
typedef void (^blocky_t)();
int main(int argc, const char * argv[])
{
blocky_t blocky = ^{
printf("Hello!\n");
printf("Hello Again!\n");
};
printf("blocky=%p\n", blocky);
blocky = (blocky_t)((char *)blocky + 1);
printf("blocky=%p\n", blocky);
blocky = (blocky_t)((char *)blocky - 1);
printf("blocky=%p\n", blocky);
blocky();
return 0;
}
$ clang -o blocky blocky.c
$ ./blocky
blocky=0x10574d040
blocky=0x10574d041
blocky=0x10574d040
Hello!
Hello Again!
When I ran your code, I got:
blocky=0x10e0ba040
blocky=0x7fff51b46c10
blocky=0x1300000000
Where:
The first address is within the __TEXT segment of the program.
The second address is near the stack.
The third is who-knows-where.
Your question really has nothing to do with blocks. You're just manipulating pointers to local variables in a way that doesn't make sense.
First, you never use the block pointer that you assign to blocky. You take the address of the local variable blocky on the stack, and then add one word to it, and dereference it. Depending on the architecture, the stack probably grows down, which means this is before all the variables on the stack frame, and is probably the return address of the current stack frame. Or it may be something else. You then assign this value to blocky.
Then, you take the address of the local variable blocky on the stack again, and then subtract one word from it, and dereference it. Again, assuming the stack grows down, this might be past the end of the current stack frame, which would be garbage. You then assign this value to blocky. You then try to run this as a pointer to a block. Of course this doesn't work.
In the second piece of code, you take the address of the local variable blocky on the stack again, and then add and subtract one word from it (which of course is the pointer to the local variable blocky again), and dereference it (which is the value of blocky), and assign it to blocky. This operation does nothing.

User triggered event in libevent

I am currently writing a multi-threaded application using libevent.
Some events are triggered by IO, but I need a couple of events that are triggered accross threads by the code itself, using event_active().
I have tried to write a simple program that shows where my problem is:
The event is created using event_new(), and the fd set to -1.
When calling event_add(), if a timeout struct is used, the event is later properly handled by event_base_dispatch.
If event_add(ev, NULL) is used instead, it returns 0 (apparently successful), but event_base_dispatch() returns 1 (which means no the event was not properly registered.)
This behavior can be tested using the following code and swapping the event_add lines:
#include <event2/event.h>
#include <unistd.h>
void cb_func (evutil_socket_t fd, short flags, void * _param) {
puts("Callback function called!");
}
void run_base_with_ticks(struct event_base *base)
{
struct timeval one_sec;
one_sec.tv_sec = 1;
one_sec.tv_usec = 0;
struct event * ev1;
ev1 = event_new(base, -1, EV_PERSIST, cb_func, NULL);
//int result = event_add(ev1, NULL);
int result = event_add(ev1, &one_sec);
printf("event_add result: %d\n",result);
while (1) {
result = event_base_dispatch(base);
if (result == 1) {
printf("Failed: event considered as not pending dispite successful event_add\n");
sleep(1);
} else {
puts("Tick");
}
}
}
int main () {
struct event_base *base = event_base_new();
run_base_with_ticks(base);
return 0;
}
Compilation: g++ sample.cc -levent
The thing is, I do not need the timeout, and do not want to use a n-years timeout as a workaround. So if this is not the right way to use user-triggered events, I would like to know how it is done.
Your approach is sound. In Libevent 2.0, you can use event_active() to activate an event from another thread. Just make sure that you use evthread_use_windows_threads() or evthread_use_pthreads() as appropriate beforehand, to tell Libevent to use the right threading library.
As for needing an extra event: in Libevent 2.0 and earlier, an event loop will exit immediately when there are no pending events added. Your best bet there is probably the timeout trick you discovered.
If you don't like that, you can use the internal "event_base_add_virtual" function to tell the event_base that it has a virtual event. This function isn't exported, though, so you'll have to say something like:
void event_base_add_virtual(struct event_base *);
// ...
base = event_base_new();
event_base_add_virtual(base); // keep it from exiting
That's a bit of a hack, though, and it uses an undocumented function, so you'd need to watch out in case it doesn't work with a later version of Libevent.
Finally, this method won't help you now, but there's a patch pending for future versions of Libevent (2.1 and later) to add a new flag to event_base_loop() to keep it from exiting when the loop is out of events. The patch is over on Github; it is mainly waiting for code review, and for a better name for the option.
I just got burned by this with libevent-2.0.21-stable. It is quite clearly a bug. I hope they fix it in a future release. In the meantime, updating the docs to warn us about it would be helpful.
The best workaround seems to be the fake timeout as described in the question.
#nickm, you didn't read the question. His example code uses event_new() like you described; there is a bug in libevent that causes it to fail when using a NULL timeout (but return 0 when you call event_add()).

C Callback in Objective-C (IOKIT)

I am trying to write some code that interacts with an USB device in Objective C, and I got stuck on setting the callback function for incoming reports. In my case it's an IOKIT function but I think the problem is more general as I (apparently) don't know how to correctly set a C callback function in Objective-C. I've got a Class "USBController" that handles the io functions
USBController.m:
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDLib.h>
#import "USBController.h"
static void Handle_IOHIDDeviceIOHIDReportCallback(
void * inContext, // context from IOHIDDeviceRegisterInputReportCallback
IOReturn inResult, // completion result for the input report operation
void * inSender, // IOHIDDeviceRef of the device this report is from
IOHIDReportType inType, // the report type
uint32_t inReportID, // the report ID
uint8_t * inReport, // pointer to the report data
CFIndex InReportLength) // the actual size of the input report
{
printf("hello"); //just to see if the function is called
}
#implementation USBController
- (void)ConnectToDevice {
...
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
...
}
...
#end
All the functions are also declared in the header file.
I think I did pretty much the same as what I've found here, but it doesn't work. The project compiles nicely and everything works up till the moment there is input and the callback function is to be called. Then I get an "EXC_BAD_ACCESS" error. The first three arguments of the function are correct. I'm not so sure about the context..
What did I do wrong?
I am not sure at all that your EXEC_BAD_ACCESS depends on your callback. Indeed, if you say that it is called (I suppose you see the log) and since it only logs a message, there should be no problem with this.
EXEC_BAD_ACCESS is caused by an attempt to access an already deallocated object. You can get more information in two ways:
execute the program in debug mode, so when it crashes you will be able to see the stack content;
activate NSZombies or run the program using the performance tool Zombies; this will tell you exactly which object was accessed after its deallocation.
I know how to fix this. When calling this:
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
You don't include the code for the creation/type of the value called report. However the method name "Handle_IOHIDDeviceIOHIDReportCallback" comes from an Apple document where there is an error in the creation of the report value. https://developer.apple.com/library/archive/technotes/tn2187/_index.html
CFIndex reportSize = 64;
uint8_t report = malloc( reportSize ); // <---- WRONG
IOHIDDeviceRegisterInputReportCallback( deviceRef,
report,
reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,
context );
Instead do this:
uint8_t *report = (uint8_t *)malloc(reportSize);