我尝试使用gl 3.3上下文创建窗口,但是当我尝试调整它时,它正在吃cpu并且滞后。
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#include <GL/glext.h>
struct _WGelWindowX11{
Display *XDspl;
Window XWin;
Colormap XCMap;
GLXContext glContext;
};
typedef struct _WGelWindowX11 WGelWindowX11;
#define WGEL_WINDOWX11(obj) ((WGelWindowX11*)obj)
int aiAttr[]={
GLX_X_RENDERABLE, True,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_DOUBLEBUFFER, True,
None
};
int aiAttrGL[]={
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
None
};
void *WGelWindowNew(void){
WGelWindowX11 *Result=malloc(sizeof(WGelWindowX11));
Result->XDspl=XOpenDisplay(NULL);
if (!Result->XDspl){
perror("Cannot open display.\n");
return NULL;
}
//Gettin' matchin' framebuffer configuration
int iFBCount;
GLXFBConfig *pFBConf=glXChooseFBConfig(Result->XDspl, DefaultScreen(Result->XDspl), aiAttr, &iFBCount);
if(!pFBConf){
perror("Cannot get FBConfig.\n");
return NULL;
}
int iBestFBC=-1, iWorstFBC=-1, iBestNSampl=-1, iWorstNSampl=999,iSamplBuff, iSampl, i;
for(i=0; i<iFBCount; i++){
XVisualInfo *vi=glXGetVisualFromFBConfig(Result->XDspl, pFBConf[i]);
if (vi){
glXGetFBConfigAttrib(Result->XDspl, pFBConf[i], GLX_SAMPLE_BUFFERS, &iSamplBuff);
glXGetFBConfigAttrib(Result->XDspl, pFBConf[i], GLX_SAMPLES, &iSampl);
if (iBestFBC<0 || iSamplBuff && iSampl>iBestNSampl) iBestFBC=i, iBestNSampl=iSampl;
if (iWorstFBC<0 || !iSamplBuff || iSampl<iWorstNSampl) iWorstFBC=i, iWorstNSampl=iSampl;
}
XFree(vi);
}
GLXFBConfig FBConfBest=pFBConf[iBestFBC];
XFree(pFBConf);
XVisualInfo *XVslnfo=glXGetVisualFromFBConfig(Result->XDspl, FBConfBest);
XSetWindowAttributes XWinAttr;
Result->XCMap=XCreateColormap(Result->XDspl, RootWindow(Result->XDspl, XVslnfo->screen), XVslnfo->visual, AllocNone);
XWinAttr.colormap=Result->XCMap;
XWinAttr.background_pixmap=None;
XWinAttr.border_pixel=0;
XWinAttr.event_mask=StructureNotifyMask|ExposureMask|KeyPressMask;
Atom wmDeleteMessage=XInternAtom(Result->XDspl, "WM_DELETE_WINDOW", FALSE);
Result->XWin=XCreateWindow(Result->XDspl, RootWindow(Result->XDspl, XVslnfo->screen), 0, 0, 300, 300, 0, XVslnfo->depth, InputOutput, XVslnfo->visual, CWBorderPixel|CWColormap|CWEventMask, &XWinAttr);
if(!Result->XWin){
perror("Cannot create window.\n");
return NULL;
}
XFree(XVslnfo);
XStoreName(Result->XDspl, Result->XWin, "WGel Window" );
XSetWMProtocols(Result->XDspl, Result->XWin, &wmDeleteMessage, 1);
XMapWindow(Result->XDspl, Result->XWin);
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs=(PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((GLubyte*)"glXCreateContextAttribsARB");
Result->glContext=glXCreateContextAttribs(Result->XDspl, FBConfBest, 0, True, aiAttrGL);
if(!Result->glContext){
perror("Cannot create GL 3.3 context\n");
return NULL;
}
glXMakeCurrent(Result->XDspl, Result->XWin, Result->glContext);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
return (void*)Result;}
Display *WGelX11GetDisplay(ptr window){
return WGEL_WINDOWX11(window)->XDspl;}
Window *WGelX11GetWindow(ptr window){
return &(WGEL_WINDOWX11(window)->XWin);
}
int main(void){
ptr frmMain=WGelWindowNew();
Display *dpy=WGelX11GetDisplay(frmMain);
XEvent e;
while(XNextEvent(dpy, &e)>=0){
if ((!XPending(dpy))&&(e.type==Expose)){
glClear(GL_COLOR_BUFFER_BIT);
glXSwapBuffers(dpy, *WGelX11GetWindow(frmMain));
}
if (e.type==ClientMessage){
XDestroyWindow(dpy, e.xclient.window);
break;
}
}
XCloseDisplay(dpy);
return EXIT_SUCCESS;}
当我调整它们时, GTK+
窗口并没有那么难,所以我想应该有办法摆脱这种滞后。
答案 0 :(得分:1)
首先,您必须忽略所有Expose事件并仅处理最后一个事件。 你可以这样做:
XNextEvent(dpy, &e);
switch (e.type)
{
case Expose:
/* Unless this is the last contiguous expose,
* don’t draw the window */
if (e.xexpose.count == 0)
{
// DRAW THINGS
}
break;
case ClientMessage:
XDestroyWindow(dpy, e.xclient.window);
break;
default:
break;
}
为了更好地处理Resizing,您必须捕获ConfigureNotify事件。
答案 1 :(得分:0)
可能和我在这里写的相同:Is there a way to change ConfigureNotify event frequency in X11?
基本修复:不要在每次调整大小事件时重新绘制,鼠标生成事件的速度要比重绘屏幕快得多。