A simple opengl application makes a creaking sound.
#include <windows.h>
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
OpenGL is only a specification it is up to the driver manufacturer to implement the specification to a driver that the specific graphics card supports.Developers need to retrieve the location of the functions and store them in function pointers.
Library's like glew or glad manages this task , so before calling any opengl function we need to initilize them.
The squeaking sound is due to increased power consumption of the card.
Enabling v-sync locks the framerate and thus reduces the GPU cycles, and lowers power consumption.
It can be either done from the property panel of the card or through code , in case of GLFW.
glfwSwapInterval( 1 )
Related
I'm working with GLFW3 + OpenGL in C under Windows 7 64-bit. Since responsive resizing is very important to my application I'm using a secondary thread for logic + rendering loops so rendering won't be interrupted when the UI thread blocks (e.g. when the user holds down the mouse on the window frame).
This works great except that it sometimes causes the contents of my window to flicker while the user is resizing the window. I suspect there's something I still don't fully understand about the consequences of rendering from a secondary thread and the possible interactions with window resizing - this is my first time working with multithreading.
Here's a minimal code sample that reproduces the problem:
#include <GL/gl3w.h>
#include <GLFW/glfw3.h>
#include <pthread.h>
GLFWwindow* window;
void *threadfun(void *arg);
int main () {
pthread_t mythread;
glfwInit();
window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
pthread_create(&mythread, NULL, &threadfun, (void *)NULL);
while (!glfwWindowShouldClose(window)) glfwWaitEvents();
pthread_join(mythread, NULL);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
void *threadfun (void *arg) {
glfwMakeContextCurrent(window);
gl3wInit();
glClearColor(0.0f, 0.5f, 0.0f, 1.0f);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
}
}
(I'm compiling with mingw-w64 x86_64-6.3.0-posix-seh-rt_v5-rev1 in case that's relevant.)
I need to get webcam video feed using C, GTK2/3, Cairo.
However can't find any references about it.
Below shows how did I try using opencv. It is unsuccessful.I need to know some other method using gstreamer, cairo.
I'm expecting simple code to get video to GTK window. Really appreciate if someone can provide example code.
/*
gcc -o weby3 att3.c `pkg-config --libs --cflags gtk+-2.0 opencv`
*/
#include "highgui.h"
#include <gtk/gtk.h>
#include <opencv/cv.h>
#include <opencv/cxcore.h>
GdkPixbuf* pix;
IplImage* frame;
CvCapture* capture;
gboolean
expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
while(1) {
frame = cvQueryFrame( capture );
if(!frame) break;
pix = gdk_pixbuf_new_from_data((guchar*) frame->imageData,
GDK_COLORSPACE_RGB, FALSE, frame->depth, frame->width,
frame->height, (frame->widthStep), NULL, NULL);
gdk_draw_pixbuf(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pix, 0, 0, 0, 0,
-1, -1, GDK_RGB_DITHER_NONE, 0, 0); /* Other possible values are GDK_RGB_DITHER_MAX, GDK_RGB_DITHER_NORMAL */
char c = cvWaitKey(33);
if( c == 27 ) break;
}
cvReleaseCapture( &capture );
return TRUE;
}
int main( int argc, char** argv ) {
/* GtkWidget is the storage type for widgets */
GtkWidget *window;
GtkWidget *drawing_area;
gtk_init (&argc, &argv);
CvCapture* capture = cvCreateCameraCapture(0);
/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Hello WebCam and OpenCV!");
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Now add a child widget to the aspect frame */
drawing_area = gtk_drawing_area_new();
/* window since we are forcing a aspect ratio */
gtk_widget_set_size_request(drawing_area, 600, 400);
gtk_container_add(GTK_CONTAINER (window), drawing_area);
gtk_widget_show(drawing_area);
g_signal_connect (G_OBJECT (drawing_area), "expose_event",
G_CALLBACK (expose_event_callback), NULL);
/* and the window */
gtk_widget_show (window);
/* All GTK applications must have a gtk_main(). Control ends here
* and waits for an event to occur (like a key press or
* mouse event). */
gtk_main ();
return 0;
}
The main problem I see here is that you're not properly integrating your opencv code into the GTK event model.
GTK basically works with a message pump. Messages are sent in a queue, and GTK reads and unqueue them to react to those messages. In GTK 2, the expose-event event is emitted when a widget or portion of it needs to be drawn (in GTK 3, the draw event is used). You're suposed to connect a callback to that event to catch the event. Then in your callback, you draw a single frame, and then give the control back to GTK. It will call your callback again when it needs the next frame.
The problem here is that you never give the hand back to GTK, as your opencv code is enclosed in an infinite while(1) loop. You should instead just draw a single frame, and return.
The key event logic should also be handled using GTK, and not in your expose-event callback. Just call gtk_main_quit once you have seen the keystroke you're waiting for.
EDIT:
Once you can display one frame, you have to display them all. Call gtk_widget_queue_draw to tell GTK that the widget needs to be redrawn.
Once this is done, you'll see that you need some way of calling gtk_widget_queue_draw periodically. This is easilly done with GLib functions like g_timeout_add or g_idle_add. These functions tell the main event loop (what I called "message pump" above") to call a callback after a determined amount of time (for g_timeout_add) or just when there is no other events to process (for g_idle_add). Call gtk_widget_queue_draw in that callback and you're done.
Be aware that g_timeout_add doesn't allow to have a perfect timing, so the time between each frame may be too different from one frame to another. You may avoid this by augmenting the priority passed to g_timeout_add. You may also use a GTimer to compute in your timeout callback the time elapsed between the last frame and the current time, and deduce time remaining until your next frame. Then call g_timeout_add with that more accurate time. Don't forget to return FALSE instead of TRUE at the end of the timeout callback if you use the GTimer trick, otherwise you'll have n timeout callbacks running at frame n.
I have a small X11 application which has two threads.
In one thread, I am listening to X11 events using XGrabKey() and then in a loop XNextEvent(). The other thread is doing other stuff and is not related to X11.
Here's the code of the relevant thread:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/XF86keysym.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
volatile bool loop = true;
void keyGrab(void)
{
Display *display = XOpenDisplay(0);
Window root = DefaultRootWindow(display);
int keycode = XKeysymToKeycode(display, XF86XK_AudioPlay);
XGrabKey(display, keycode, AnyModifier, root, False, GrabModeAsync, GrabModeAsync);
XSelectInput(display, root, KeyPressMask);
while (loop) {
XEvent event;
XNextEvent(display, &event);
switch (event.type) {
case KeyPress: puts("Play key pressed"); break;
}
}
XUngrabKey(display, keycode, AnyModifier, root);
XCloseDisplay(display);
}
The goal is that the other thread can tell this thread to stop.
Now the problem is that setting loop = false in the other thread will of course not terminate this thread, at least not immediately. This thread is stuck in XNextEvent() because that's a blocking call. So here's my question: What is the standard pattern how to get XNextEvent() to return?
I guess I need the other Thread to use XSendEvent(), but I couldn't find any hints on how to do that. I wouldn't even know which message type would be appropriate. Would it be ClientMessage? Something else? I actually tried sending a ClientMessage from the other thread, but I got the following error message:
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 25 (X_SendEvent)
Value in failed request: 0x0
Serial number of failed request: 12
Current serial number in output stream: 12
Here's the relevant code snippet from the other thread that I tried and triggered the error (display and root are initialized by the first thread):
XEvent event;
memset(&event, 0, sizeof(event));
event.type = ClientMessage;
XSendEvent(display, root, False, 0, &event);
Note that the other thread doesn't need any X11 code by itself. The only purpose why the other thread would use X11 is to tell this thread to terminate.
Please keep in mind that there is no window in context. The root window of course does not count, as this is only for globally catching keys. So, destroying the window is not a solution.
According to these pages
how to quit the blocking of xlib's XNextEvent
http://www.linuxquestions.org/questions/programming-9/xnextevent-select-409355/#post2431460
The best solution would be perform a select on the X event queue socket
getting the socket is achieved by
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
Display *dis;
Window win;
int x11_fd;
fd_set in_fds;
struct timeval tv;
XEvent ev;
int main() {
dis = XOpenDisplay(NULL);
win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 256, 256,\
0, BlackPixel (dis, 0), BlackPixel(dis, 0));
// You don't need all of these. Make the mask as you normally would.
XSelectInput(dis, win,
ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
ButtonPressMask | ButtonReleaseMask | StructureNotifyMask
);
XMapWindow(dis, win);
XFlush(dis);
// This returns the FD of the X11 display (or something like that)
x11_fd = ConnectionNumber(dis);
// Main loop
while(1) {
// Create a File Description Set containing x11_fd
FD_ZERO(&in_fds);
FD_SET(x11_fd, &in_fds);
// Set our timer. One second sounds good.
tv.tv_usec = 0;
tv.tv_sec = 1;
// Wait for X Event or a Timer
if (select(x11_fd+1, &in_fds, 0, 0, &tv))
printf("Event Received!\n");
else
// Handle timer here
printf("Timer Fired!\n");
// Handle XEvents and flush the input
while(XPending(dis))
XNextEvent(dis, &ev);
}
return(0);
}
Use XCheckWindowEvent in your message loop to see if there are any messages (followed by XNextEvent if one exists), and since this is non-blocking you can proceed to use pthread_cond_timedwait or whatever equivalent may exist in the threading library you are using. That way the blocking is in your hands rather than xlib's. If it times out it will check for another event, and then resume to waiting for your thread.
I have a simple multithreaded Gtk+2.0 application that acquires data from multiple sources (microphone, webcam, temperature sensor), and displays data from these as images on screen (webcam frame grabs, microphone data represented as oscilloscope renders, text, etc).
It's to my understanding from the Gtk manual and various articles that only the main processing thread should use any Gtk functions/calls that affect the UI. However, the main() entry point blocks on gtk_main() until I close the UI. With the exception of event handlers that are mapped to things like when I click on a button or slider in my UI, it seems the only option left open to me is to spawn a few pthreads and have them do the periodic sampling of data and updating information on-screen in the UI.
I remember from doing some MFC GUI development a long ways back that a similar principle applied: only a single specific thread should be updating the UI elements. How do I accomplish this in C with Gtk+2.0?
Thank you.
According to the documentation, the main even loop can accept sources from different threads:
A GMainContext can only be running in a single thread, but sources can
be added to it and removed from it from other threads.
So you can inject the code in the UI thread from your working thread by:
creating a GSource (e.g., by using g_idle_source_new);
adding the code you want to be executed with g-source-set-callback;
attaching it to the UI thread context with g_source_attach().
Here is a sample program for GTK+2 and GLib >= 2.32:
#include <gtk/gtk.h>
#define N_THREADS 100
#define N_ITERATIONS 100
GtkWidget *bar;
GMainContext *context;
static gboolean
update_progress_bar(gpointer user_data)
{
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar),
g_random_double_range(0, 1));
return G_SOURCE_REMOVE;
}
static gpointer
thread_func(gpointer user_data)
{
int n_thread = GPOINTER_TO_INT(user_data);
int n;
GSource *source;
g_print("Starting thread %d\n", n_thread);
for (n = 0; n < N_ITERATIONS; ++n) {
/* If you want to see anything you should add a delay
* to let the main loop update the UI, e.g.:
* g_usleep(g_random_int_range(1234, 567890));
*/
source = g_idle_source_new();
g_source_set_callback(source, update_progress_bar, NULL, NULL);
g_source_attach(source, context);
g_source_unref(source);
}
g_print("Ending thread %d\n", n_thread);
return NULL;
}
gint
main(gint argc, gchar *argv[])
{
GtkWidget *window;
GThread *thread[N_THREADS];
int n;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
bar = gtk_progress_bar_new();
gtk_container_add(GTK_CONTAINER(window), bar);
context = g_main_context_default();
for (n = 0; n < N_THREADS; ++n)
thread[n] = g_thread_new(NULL, thread_func, GINT_TO_POINTER(n));
gtk_widget_show_all(window);
gtk_main();
for (n = 0; n < N_THREADS; ++n)
g_thread_join(thread[n]);
return 0;
}
I would do your sampling in separate threads, as you suggest. The question then is how you update the UI. What I would do is to use a 'self-pipe'. This is normally done to communicate from signal handlers, but it works just fine between threads when one of the threads can't wait on a condition variable. What you do here is set up a dedicated pipe, write one character to the pipe in the thread that has got the data, and select() on the read end of the pipe in the main program's select() loop. Details here: Using self-pipe, how can I avoid that the event loop stalls on read()? - useful background on its origins here.
You can then make GTK+ listen on the read end of the pipe. Your problem is thus reduced to making GTK+ respond to something on an FD - see here (first answer) for how.
Using GTK and C, how can I start/stop a long calculation (in a seperate thread) using a button? I have working code that does just that but I have little confidence that it isa reasonable method (i.e., "right").
I have a single button whose label toggles from "start" to "stop". I also have a global pthread_t variable to store a thread. My approach is to either launch or cancel a thread through the button's clicked signal handler depending on the value of a global boolean-like "idle" flag which indicates if the thread is currently running or not.
I wanted a working well-designed minimum test case so that I can easily understand the code to adapt for a larger program. This question is very similar to Python&PyGTK: Stop while on button click but that question is in python which I don't know.
My code --- posted below --- seems to work but I'm not confident in it because I can easily bring the system to its knees by just clicking the start/stop button a few times in rapid succession.
I'd be curious to see how others would (independently) solve this, how their approach compares to mine, and also a code-review for my own approach if it is actually a decent way.
#include <gtk/gtk.h>
#include <pthread.h>
/* suppress unused variable warnings */
#define UNUSED(x) (void)(x)
typedef struct _Data {
GtkWidget *window1,
*button1;
gint idle;
pthread_t calcthread;
} Data;
static Data *data;
void *calcfunc(void *arg) {
int i;
UNUSED(arg);
data->idle=FALSE;
gtk_button_set_label(GTK_BUTTON(data->button1),"Stop");
/* This is intended to simulated a long calculation that may finish.
Adjust the limit as needed */
for(i=1;i<2e9;++i) {
}
data->idle=TRUE;
pthread_exit(NULL);
}
/* this is our click event handler.... it suppose to start or stop
the "calcthread" depending on the value of the "idle" flag */
void on_button1_clicked(GtkWidget *widget, Data *ldata) {
int ret;
UNUSED(widget);
UNUSED(ldata);
if ( data->idle==TRUE ) {
printf("idle.. starting thread\n");
ret=pthread_create( &data->calcthread, NULL, calcfunc, NULL);
if ( ret !=0 ) {
g_error("ERROR: could not create thread\n");
}
} else {
printf("not idle... canceling thread...");
ret= pthread_cancel( data->calcthread );
if ( ret != 0 ) {
g_error("ERROR: could not cancel thread\n");
} else {
printf("canceled\n");
}
data->idle=TRUE;
gtk_button_set_label(GTK_BUTTON(data->button1),"start");
}
}
/* just defines our setup */
int main (int argc, char *argv[]) {
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
gtk_init(&argc, &argv);
data=g_slice_new0(Data);
data->idle=TRUE; /* initial state */
printf("idle is %d\n",data->idle);
/* add widgets and objects to our structure */
data->window1=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(data->window1),250,250);
data->button1=gtk_button_new_with_label("Start");
gtk_container_add(GTK_CONTAINER(data->window1),GTK_WIDGET(data->button1));
gtk_signal_connect(GTK_OBJECT(data->window1), "delete-event",
gtk_main_quit, NULL);
gtk_signal_connect(GTK_OBJECT(data->button1), "clicked",
G_CALLBACK(on_button1_clicked), NULL);
gtk_widget_show_all(GTK_WIDGET(data->window1));
gtk_main();
/* Don't forget to free the memory! */
g_slice_free(Data, data);
gdk_threads_leave();
return 0;
}
As you are calling GTK functions from the secondary thread you need to wrap the call to
gtk_button_set_label(GTK_BUTTON(data->button1),"Stop");
with gdk_threads_enter/gdk_threads_leave calls. However, it is better practice to only call GTK functions from one thread. The easiest way is with an idle function using g_idle_add as this will be called from the main thread, however in your case you could just move the call to gtk_button_set_label from calcfunc into on_button1_clicked.
You should also set data->idle = FALSE in the on_button1_clicked handler to solve the race condition where you click the button too quickly.
Another way you could do this is without threads and that is to run the GTK main loop during the long operation. In your loop you just need to pump the Gtk event loop.
for(i=1;i<2e9;++i) {
while (gtk_events_pending ()) {
gtk_main_iteration ();
}
}
This means you avoid all the threading problems and needing to lock data access. You could stop the calculation by checking a boolean value each iteration which gets set in the on_button1_clicked handler.
The following code does what I asked. It uses pthreads. I don't know if it's the most elegant but it seems to work. The trick was using two flags: one for the idle state and one for a cancel request, which avoids needing to cancel the thread using the "pthread_cancel" function, which I find to be unusual in real code.
#include <gtk/gtk.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#define UNUSED(x) (void)(x)
#define handle_error_en(en, msg) do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
typedef struct _Data {
GtkWidget *window1,
*button1;
} Data;
static Data *data;
static pthread_mutex_t calcmutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t calcthread=0;
static gboolean idle=TRUE,cancel_request=FALSE;
void *calcfunc(void *arg) {
int i,s;
UNUSED(arg);
g_print("\tstarting thread\n");
s = pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
if (s != 0) {
handle_error_en(s, "pthread_setcancelstate");
}
gdk_threads_enter();
gtk_button_set_label(GTK_BUTTON(data->button1),"Stop");
gdk_threads_leave();
g_print("\tstarting work...\n");
for (i=0; i<100000000 ;++i) {
/* check for cancelation */
pthread_mutex_lock(&calcmutex);
if ( cancel_request ) {
g_print("\t[cancel request noted].\n");
pthread_mutex_unlock(&calcmutex);
break;
}
pthread_mutex_unlock(&calcmutex);
/* do "calculation" */
i=i*1*-1*1*-1;
}
g_print("\tdone work.\n");
gdk_threads_enter();
gtk_button_set_label(GTK_BUTTON(data->button1),"Start");
gdk_threads_leave();
pthread_mutex_lock(&calcmutex);
cancel_request=FALSE;
idle=TRUE;
pthread_mutex_unlock(&calcmutex);
g_print("\tdone thread.\n");
pthread_exit(NULL);
}
void on_button1_clicked(GtkWidget *widget, gpointer *ldata) {
int s;
UNUSED(widget);
UNUSED(ldata);
g_print("entered on_button1_clicked\n");
pthread_mutex_lock(&calcmutex);
if ( idle ) {
g_print("idle, starting thread\n");
s = pthread_create(&calcthread, NULL, calcfunc, NULL);
if (s != 0) {
handle_error_en(s, "pthread_create");
}
idle=FALSE;
} else {
g_print("not idle and not first time, making canceling request.\n");
cancel_request=TRUE;
}
pthread_mutex_unlock(&calcmutex);
g_print("finished on_button1_clicked\n");
}
/* just defines our setup */
int main (int argc, char *argv[]) {
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
gtk_init(&argc, &argv);
data=g_slice_new0(Data);
printf("initial idle is %d\n",idle);
/* add widgets and objects to our structure */
data->window1=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(data->window1),250,250);
data->button1=gtk_button_new_with_label("Start");
gtk_container_add(GTK_CONTAINER(data->window1),GTK_WIDGET(data->button1));
gtk_signal_connect(GTK_OBJECT(data->window1), "delete-event",
gtk_main_quit, NULL);
gtk_signal_connect(GTK_OBJECT(data->button1), "clicked",
G_CALLBACK(on_button1_clicked), NULL);
gtk_widget_show_all(GTK_WIDGET(data->window1));
gtk_main();
/* free the memory and stuff */
g_slice_free(Data, data);
pthread_mutex_destroy(&calcmutex);
gdk_threads_leave();
return 0;
}
This compiles warningless with
gcc -Wall -Wextra -Wconversion -pedantic `pkg-config --cflags --libs gtk+-2.0` start_stop.c -o start_stop
Well in Java I would call interrupt() on that Thread, the thread would then get an InterruptedException, and would be able to clean up in its exception handler's catch or finally block before exiting.
In C there is several options:
send that thread a signal with kill(), and have the signal handler longjmp() to a point in your code where you previously called setjmp(). For cleanup, you'd just do something when setjmp() returns non-zero, meaning it's resuming from the subsequent longjmp() call.
call pthread_cancel(). The only real cleanup you get here is that the cancellation handlers you previously registered with pthread_cleanup_push() will get called.
have either a volatile variable or a lock protected variable that gets checked periodically (for example once every loop iteration) and set to some value when the calculation should be canceled. Cleanup is easy because you can do whatever you like when the flag is set and you break out of the loop.
I dislike all of them: signals mean you have to handle partial failures (eg. short reads and writes on files and sockets) and errno==EINTR correctly everywhere in your code while avoiding all kinds of gotchas that exist with signal handlers (such as the small stack size and limits on what system calls are safe to use), pthread_cancel() means you have to drag state around between the thread function and the cancellation handlers, and the flag can impact performance since it has to read uncached memory or take a lock every time and if you don't check it often enough then the thread won't respond immediately when the flag is set.