小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

linux – 如果“純XCB”O(jiān)penGL是不可能的,那么在xcb / glx.h中找到的XCB / GLX API的用途是什么?

 印度阿三17 2019-06-27

官方的XCB文檔告訴我們using OpenGL purely with XCB is impossible:一個(gè)人也必須使用Xlib.

巴特梅西(XCB的創(chuàng)始人)This post并未暗示這應(yīng)該是不可能的.但我確定我錯(cuò)過(guò)了一些東西.

我花了好幾個(gè)小時(shí)瀏覽xcb / glx.h,它組織得很好here.在我看來(lái),它就像一個(gè)完整的API.但我無(wú)法讓它發(fā)揮作用.

問(wèn)題

> XCB / GLX API無(wú)用嗎? xcb / glx.h的目的是什么?
>如何使用API???

(注意:這是了解XCB如何工作的持續(xù)努力的一部分.)

相關(guān)SO thread.

次要的,啰嗦的東西

如果有人愿意采取行動(dòng),這里是來(lái)自XCB郵件列表中原始帖子的來(lái)源,刪除了一點(diǎn)并放入一個(gè)文件中.

您會(huì)注意到xcb_glx_make_context_current返回錯(cuò)誤169(不知道這意味著什么),但前提是xcb_glx_create_window為其最后兩個(gè)參數(shù)取0和NULL.這些參數(shù)涉及一系列屬性,它們似乎是由函數(shù)xcb_glx_create_window_attribs返回的,但我無(wú)法弄清楚如何使用它…

int main()之前的長(zhǎng)輔助函數(shù)僅表示兩個(gè)返回兩個(gè)整數(shù)xcb_glx_fbconfig_t fbconfig xcb_visualid_t glx_visual,對(duì)應(yīng)于第一個(gè)“匹配”幀緩沖配置.在我的平臺(tái)上,這些是0xa7和0x24.它們正是Xlib / GLX例程(實(shí)際工作)返回的原因,所以我知道我選擇的幀緩沖配置很好.

所以,問(wèn)題似乎發(fā)生在xcb_glx_create_window和xcb_glx_make_context_current之間…

// gcc main2.c -o main -lxcb -lxcb-glx -lGL && ./main2
// TODO free replies

#include <stdio.h>
#include <stdlib.h>
#include <xcb/glx.h>
#include <GL/gl.h>

#define W 1024
#define H 1024

// parameter types returned by xcb_glx_get_fb_configs
#define GLX_DRAWABLE_TYPE               0x8010
#define GLX_RENDER_TYPE                 0x8011
#define GLX_DOUBLEBUFFER                5
#define GLX_RED_SIZE                    8
#define GLX_GREEN_SIZE                  9
#define GLX_BLUE_SIZE                   10
#define GLX_RGBA_BIT                    0x00000001
#define GLX_RGBA_TYPE                   0x8014
#define GLX_STENCIL_SIZE                13
#define GLX_DEPTH_SIZE                  12
#define GLX_BUFFER_SIZE                 2
#define GLX_ALPHA_SIZE                  11
#define GLX_X_RENDERABLE                0x8012

#define GLX_FBCONFIG_ID                 0x8013
#define GLX_VISUAL_ID                   0x800b

#define GLX_WINDOW_BIT                  0x00000001
#define GLX_PIXMAP_BIT                  0x00000002
#define GLX_PBUFFER_BIT                 0x00000004


// ------------------------------------------------------------------------------------------------
// fbconfig and visual?
uint32_t glx_attrs[] = {
  GLX_DOUBLEBUFFER, 1,
  GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT|GLX_PIXMAP_BIT|GLX_PBUFFER_BIT,
  GLX_X_RENDERABLE, 1,  
  GLX_RED_SIZE, 8,
  GLX_GREEN_SIZE, 8,
  GLX_BLUE_SIZE, 8,
  GLX_ALPHA_SIZE, 8,
  GLX_STENCIL_SIZE, 8,
  GLX_DEPTH_SIZE, 24,
  GLX_BUFFER_SIZE, 32,
  GLX_RENDER_TYPE, GLX_RGBA_BIT,
};

// ------------------------------------------------------------------------------------------------
// This function searches for an @param prop_name in the @param property list of properties of size @param prop. Prop is property count and not buffer size.
uint32_t glx_get_property(const uint32_t* property, const uint props, uint32_t prop_name){
  uint i=0;
  while(i < props*2){
      if(property[i] == prop_name)
        return property[i 1];
      else i  = 2;
  }
  return -1;
}

// This function chooses and returns specific fbconfig id depending on attributes specified in 
// @param attrib list. @param attribsz is the number of properties(not list size)
int32_t glx_choose_fbconfig(xcb_connection_t* connection, uint32_t screen_num, uint32_t* attrib, uint32_t attribsz){
  xcb_generic_error_t* xerror;

  xcb_glx_get_fb_configs_reply_t* fbconfigs = xcb_glx_get_fb_configs_reply(connection, xcb_glx_get_fb_configs(connection, screen_num), NULL);
  uint32_t* prop = xcb_glx_get_fb_configs_property_list(fbconfigs);

  uint32_t* fbconfig_line   = prop;
  uint32_t  fbconfig_linesz = fbconfigs->num_properties * 2;

  for(uint i=0 ; i<fbconfigs->num_FB_configs; i  ){  // for each fbconfig line
      uint good_fbconfig = 1;

    for(uint j=0 ; j<attribsz*2; j  = 2){  // for each attrib
    // if property found != property given
        if(glx_get_property(fbconfig_line, fbconfigs->num_properties, attrib[j]) != attrib[j 1]) {
            good_fbconfig = 0; // invalidate this fbconfig entry, sine one of the attribs doesn't match
            break;
        }
    }

    // if all attribs matched, return with fid
    if(good_fbconfig){
        uint32_t fbconfig_id = glx_get_property(fbconfig_line, fbconfigs->num_properties , GLX_FBCONFIG_ID);
        free(fbconfigs);
        return fbconfig_id;
    }

    fbconfig_line  = fbconfig_linesz; // next fbconfig line;
  }
  return -1;
}

// This function returns @param attrib value from a line containing GLX_FBCONFIG_ID of @param fid
// It kind of queries particular fbconfig line for a specific property.
uint32_t glx_get_attrib_from_fbconfig(xcb_connection_t* connection, uint32_t screen_num, uint32_t fid, uint32_t attrib){
  xcb_glx_get_fb_configs_reply_t* fbconfigs = xcb_glx_get_fb_configs_reply(connection, xcb_glx_get_fb_configs(connection, screen_num), NULL);
  uint32_t* prop   = xcb_glx_get_fb_configs_property_list(fbconfigs);

  uint i = 0;
  uint fid_found = 0;
  while(i < fbconfigs->length){
    if(prop[i] == GLX_FBCONFIG_ID) {
      if(prop[i 1] == fid){
        fid_found = 1;
        i -= i%(fbconfigs->num_properties * 2); // going to start of the fbconfig  line
        uint32_t attrib_value = glx_get_property(&prop[i], fbconfigs->num_properties, attrib);
        free(fbconfigs);
        return attrib_value;
      }
    }
    i =2;
  }
  if(fid_found) printf("glx_get_attrib_from_fbconfig: no attrib %u was found in a fbconfig with GLX_FBCONFIG_ID %u\n", attrib, fid);
  else printf("glx_get_attrib_from_fbconfig: GLX_FBCONFIG_ID %u was not found!\n", fid);
  return -1;
}

// ------------------------------------------------------------------------------------------------
int main(){
  xcb_generic_error_t* xerror; // To hold errors!
  int screen_number;

  xcb_connection_t* connection = xcb_connect(NULL, &screen_number);
  xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;   // getting the default screen
  printf("screen %d  root %d\n", screen_number, screen->root);

  xcb_colormap_t    colormap    = xcb_generate_id(connection);  // generating XID's for our objects!
  xcb_window_t      window      = xcb_generate_id(connection);
  xcb_glx_context_t glx_context = xcb_generate_id(connection);
  xcb_glx_window_t  glx_window  = xcb_generate_id(connection);

  // ----------------------------------------------------------------------------------------------
  xcb_glx_query_version_reply_t* glx_version = xcb_glx_query_version_reply(connection, xcb_glx_query_version(connection, 0, 0), NULL);
  printf("glx %d.%d  response_type %x  pad0 %x  sequence %x  length %d\n",
    glx_version->major_version, glx_version->minor_version, glx_version->response_type,
    glx_version->pad0, glx_version->sequence, glx_version->length);

  // ----------------------------------------------------------------------------------------------
  xcb_glx_fbconfig_t fbconfig   = glx_choose_fbconfig(connection, screen_number, glx_attrs, sizeof(glx_attrs)/2/sizeof(uint32_t));
  xcb_visualid_t glx_visual     = glx_get_attrib_from_fbconfig(connection, screen_number, fbconfig, GLX_VISUAL_ID);
  printf("fbconfig %x  glx_visual %x\n", fbconfig, glx_visual);

  // ----------------------------------------------------------------------------------------------
  xcb_glx_create_new_context(connection, glx_context, fbconfig, screen_number, GLX_RGBA_TYPE, 0, 1);  // New-style context?
  // xcb_glx_create_context(connection, glx_context, glx_visual, 0, 0, 1);  // Alt method! Old-style context?

  if(!(xcb_glx_is_direct_reply(connection, xcb_glx_is_direct(connection, glx_context), NULL)->is_direct))
    puts("glx context is not direct!");

  // ----------------------------------------------------------------------------------------------
  xcb_create_colormap(connection , XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, glx_visual);  // creating colormap

  // creating a window, using our new colormap
  uint32_t window_mask = XCB_CW_BACK_PIXEL|XCB_CW_EVENT_MASK|XCB_CW_COLORMAP;
  uint32_t window_attrs[] = {0x444444, XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_KEY_PRESS, colormap};

  xcb_create_window(connection, screen->root_depth, window, screen->root, 0,0, W,H, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, glx_visual, window_mask, window_attrs);
  xcb_map_window(connection, window);

  xcb_glx_create_window(connection, screen_number, fbconfig, window, glx_window, 0, NULL);
  xcb_flush(connection);

  // ----------------------------------------------------------------------------------------------
  xcb_glx_make_context_current_reply_t* reply_ctx = xcb_glx_make_context_current_reply(connection, xcb_glx_make_context_current(connection, 0, glx_window, glx_window, glx_context), NULL);
  if(!reply_ctx)  puts("ERROR  xcb_glx_make_context_current returned NULL!");
  xcb_glx_context_tag_t glx_context_tag = reply_ctx->context_tag;

  // alternative ?
  // xcb_glx_make_current_reply_t* reply_mc = xcb_glx_make_current_reply(connection, xcb_glx_make_current(connection, glx_window, glx_context, 0), NULL);
  // xcb_glx_context_tag_t glx_context_tag = reply_mc->context_tag;

  // ----------------------------------------------------------------------------------------------
  xcb_glx_get_error_reply(connection, xcb_glx_get_error(connection, glx_context_tag), &xerror);
  if(xerror)  printf("\nERROR  xcb_glx_get_error %d\n", xerror->error_code);

  // ----------------------------------------------------------------------------------------------
  xcb_generic_event_t* event;
  uint running = 1;
  while(running){
    event = xcb_poll_for_event(connection);
    if(event){
      switch (event->response_type) {
        case XCB_EXPOSE:
          glClearColor(0, .5, 1, 1);  // Blue
          glFlush();
          xcb_glx_swap_buffers(connection, glx_context_tag, glx_window);
          puts("Expose!");
          break;
        case XCB_KEY_PRESS: // exit on key press
          running = 0;
          break;
      }
    }
    free(event);
  }

  xcb_disconnect(connection);
}

解決方法:

這里需要了解的重要事項(xiàng)是XCB函數(shù)直接映射到X11協(xié)議請(qǐng)求.這意味著xcb_glx_ *函數(shù)直接映射到X11 GLX協(xié)議請(qǐng)求.請(qǐng)參閱https://www./registry/OpenGL/specs/gl/glx1.4.pdf中的“第4章”.它列出了所有可用的GLX請(qǐng)求.例如,glAreTexturesResident從xcb / glx.h(https://xcb./manual/glx_8h_source.html)映射到xcb_glx_are_textures_resident_ * API.在Khronos規(guī)范中,您可以閱讀請(qǐng)求做什么.

What’s the purpose of xcb/glx.h?

XCB-GLX只與X服務(wù)器通信,它不執(zhí)行任何硬件初始化或觸摸OpenGL客戶端狀態(tài).因此,XCB-GLX不能用作GLX API的替代品. [1]

硬件初始化和其他GL內(nèi)容由openGL lib完成.這就是規(guī)范的“另一半”實(shí)施的地方.在Linux上,libsa由mesa(https://cgit./mesa/mesa/tree/src/glx)提供.你可以看到glx目錄中的文件包含Xlib.h,所以我想這就是Xlib依賴的來(lái)源.這解釋了“GLX API與Xlib緊密結(jié)合.因此,X Windows上的OpenGL應(yīng)用程序必須使用Xlib,因此不能僅使用XCB.” [1].

Is the XCB/GLX API useless?

雖然XCB-GLX API對(duì)最終用戶XCB應(yīng)用程序開(kāi)發(fā)人員沒(méi)什么價(jià)值,但它可以用于開(kāi)發(fā)基于XCB的新OpenGL和GLX實(shí)現(xiàn). XCB可以提高OpenGL庫(kù)的速度和質(zhì)量. [1]

因此,為了獲得純XCB GLX,有人需要在openGL lib中重新實(shí)現(xiàn)GLX:

>公開(kāi)基于XCB的API以初始化硬件等.
>應(yīng)該使用xcb_glx API與X服務(wù)器進(jìn)行通信,而不是Xlib.

來(lái)自[1]的文檔說(shuō)“GLX系統(tǒng)有兩個(gè)角色,它與X服務(wù)器通信并初始化客戶端和硬件狀態(tài).”

xcb-glx負(fù)責(zé)溝通.另一個(gè)角色(基于XCB的OpenGL和GLX實(shí)現(xiàn))目前尚未實(shí)現(xiàn),也不太可能實(shí)現(xiàn).

“GLX API是根據(jù)Xlib指定的,glX函數(shù)使用Xlib Displays,Windows,Visuals等.GLX實(shí)現(xiàn)也是使用Xlib構(gòu)建的.” (參見(jiàn)libGL.so的導(dǎo)出符號(hào)).為了完成第二個(gè)角色,我們需要一個(gè)使用XCB連接,窗口,視覺(jué)效果的相同API.

[1] https://xcb./opengl/

免責(zé)聲明:這是我對(duì)收集的理解.

來(lái)源:https://www./content-3-274751.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多