স্বচ্ছ পটভূমির সাথে কীভাবে একটি ওপেনএল রেন্ডারিং প্রসঙ্গ তৈরি করবেন?


101

রেন্ডারিং প্রসঙ্গে সাধারণত পটভূমিতে একটি শক্ত রঙ থাকে (কালো বা যাই হোক না কেন, নীচের চিত্রটি দেখুন):

বিকল্প পাঠ

আমি ভাবছি যে কোনও উইন্ডো সেটআপ করা সম্ভব, কোনও সাজসজ্জা ছাড়াই এবং স্বচ্ছ পটভূমি সহ, যদি আমাকে এতে ওপেনএল স্টোর সরবরাহ করতে দেয় তবে।

এটি এই ধারণাটি দেবে যে ত্রিভুজটি পর্দায় ভাসছে। স্বচ্ছ পটভূমি আপনাকে ডেস্কটপ বা অন্যান্য অ্যাপ্লিকেশনগুলি দেখতে দেয় যা এর পিছনে থাকতে পারে।

আপনি কি সোর্স কোড দিয়ে উদাহরণ দিতে পারেন?

প্ল্যাটফর্ম: উইন্ডোজ (কেবল উইন 32)

উত্তর:


100

এই ইস্যুতে কিছু সহায়তা পেতে একটি ব্যর্থ অনুগ্রহে কিছুটা খ্যাতি ব্যয় করার পরে অবশেষে বুঝতে পেরেছিলাম যে আমি আগ্রহী সেই সমস্যাটি কতটা জটিল।

এই কাজটি সম্পন্ন কয়েকটি ব্যক্তি খুব বেশি ভাগ করে না । আমার গবেষণার সময় আমি যা খুঁজছিলাম তা অর্জনের জন্য বিভিন্ন উপায় খুঁজে পেয়েছি। সবচেয়ে আকর্ষণীয় বিষয়গুলির মধ্যে একটি হ'ল অ্যারোজিএল , এবং এটি এমন কোনও কৌশল ব্যবহার করে কোডের স্নিপেটগুলি দেখায় যা এখন পর্যন্ত উল্লেখ করা হয়নি, যা গ্রাফিকগুলি ডিভাইস-স্বাধীন বিটম্যাপে (ডিআইবি) রেন্ডার করে ।

এই থ্রেডটিকে স্থায়ীভাবে বন্ধ করতে, নীচের উত্স কোডটি সেই কৌশলটি প্রয়োগ করে। কোডটি নিজেই এখানে উপস্থাপিত একটি অ্যাপ্লিকেশনটির সামান্য পরিবর্তন (( আন্ড্রেই সাপ্রোনভ ওয়াইয়ের জন্য ধন্যবাদ )

শেষের ফলাফলটি নীচের চিত্রটিতে দেখা যাবে:

এখানে চিত্র বর্ণনা লিখুন

কোডটি উইন্ডোজ এক্সপি (32-বিট) এবং উইন্ডোজ 8.1 (32-বিট) এ পরীক্ষিত হয়েছে। উপভোগ করুন!

#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>

#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")

#include <assert.h>
#include <tchar.h>

#ifdef  assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif

const TCHAR szAppName[]=_T("TransparentGL");
const TCHAR wcWndName[]=_T("WS_EX_LAYERED OpenGL");

HDC hDC;            
HGLRC m_hrc;        
int w(240);
int h(240); 

HDC pdcDIB;                 
HBITMAP hbmpDIB;            
void *bmp_cnt(NULL);        
int cxDIB(0); 
int cyDIB(0);   
BITMAPINFOHEADER BIH;       


BOOL initSC()
{
    glEnable(GL_ALPHA_TEST);        
    glEnable(GL_DEPTH_TEST);        
    glEnable(GL_COLOR_MATERIAL);

    glEnable(GL_LIGHTING);          
    glEnable(GL_LIGHT0);            

    glEnable(GL_BLEND);             
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0, 0, 0, 0);

    return 0;
}

void resizeSC(int width,int height)
{
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW );
    glLoadIdentity();
}

BOOL renderSC()
{   
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glPushMatrix();

    glColor3f(0, 1, 1);
    glBegin(GL_TRIANGLES);                              // Drawing Using Triangles
        glColor3f(1.0f,0.0f,0.0f);                      // Set The Color To Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top
        glColor3f(0.0f,1.0f,0.0f);                      // Set The Color To Green
        glVertex3f(-1.0f,-1.0f, 0.0f);                  // Bottom Left
        glColor3f(0.0f,0.0f,1.0f);                      // Set The Color To Blue
        glVertex3f( 1.0f,-1.0f, 0.0f);                  // Bottom Right
    glEnd();

    glPopMatrix();
    glFlush();

    return 0;
}

// DIB -> hDC
void draw(HDC pdcDest)
{
    assert(pdcDIB);

    verify(BitBlt(pdcDest, 0, 0, w, h, pdcDIB, 0, 0, SRCCOPY));
}

void CreateDIB(int cx, int cy)
{
    assert(cx > 0); 
    assert(cy > 0);

    cxDIB = cx ;
    cyDIB = cy ;

    int iSize = sizeof(BITMAPINFOHEADER);   
    memset(&BIH, 0, iSize);

    BIH.biSize = iSize;
    BIH.biWidth = cx;   
    BIH.biHeight = cy;  
    BIH.biPlanes = 1;   
    BIH.biBitCount = 24;    
    BIH.biCompression = BI_RGB;

    if(pdcDIB) 
        verify(DeleteDC(pdcDIB));

    pdcDIB = CreateCompatibleDC(NULL);
    assert(pdcDIB);

    if(hbmpDIB) 
        verify(DeleteObject(hbmpDIB));

    hbmpDIB = CreateDIBSection(
        pdcDIB,         
        (BITMAPINFO*)&BIH,  
        DIB_RGB_COLORS,     
        &bmp_cnt,       
        NULL,
        0);

    assert(hbmpDIB);
    assert(bmp_cnt);

    if(hbmpDIB)
        SelectObject(pdcDIB, hbmpDIB);
}

BOOL CreateHGLRC()
{
    DWORD dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP;

    PIXELFORMATDESCRIPTOR pfd ;
    memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)) ;
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 
    pfd.nVersion = 1;                       
    pfd.dwFlags =  dwFlags ;                
    pfd.iPixelType = PFD_TYPE_RGBA ;        
    pfd.cColorBits = 24 ;                   
    pfd.cDepthBits = 32 ;                   
    pfd.iLayerType = PFD_MAIN_PLANE ;       

   int PixelFormat = ChoosePixelFormat(pdcDIB, &pfd);
   if (PixelFormat == 0){
      assert(0);
      return FALSE ;
   }

   BOOL bResult = SetPixelFormat(pdcDIB, PixelFormat, &pfd);
   if (bResult==FALSE){
      assert(0);
      return FALSE ;
   }

   m_hrc = wglCreateContext(pdcDIB);
   if (!m_hrc){
      assert(0);
      return FALSE;
   }

   return TRUE;
}

LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;

    switch(msg) 
    {
        case WM_ERASEBKGND:
            return 0;
        break;

        case WM_CREATE:
        break;

        case WM_DESTROY:
            if(m_hrc)
            {
                wglMakeCurrent(NULL, NULL);
                wglDeleteContext(m_hrc) ;
            }
            PostQuitMessage(0) ;
        break;

        case WM_PAINT:
            hDC = BeginPaint(hWnd, &ps);
            renderSC(); // OpenGL -> DIB
            draw(hDC);  // DIB -> hDC
            EndPaint(hWnd, &ps);
        break;

        case WM_SIZE:
            w = LOWORD(lParam); h = HIWORD(lParam);         
            wglMakeCurrent(NULL, NULL);
            wglDeleteContext(m_hrc);

            CreateDIB(w, h);
            CreateHGLRC();
            verify(wglMakeCurrent(pdcDIB, m_hrc));

            initSC();
            resizeSC(w, h);
            renderSC();
        break;

        default: 
            return DefWindowProc(hWnd,msg,wParam,lParam);
    }

    return 0;
}

int WINAPI _tWinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str,int nWinMode)
{   
    WNDCLASSEX wc;
    memset(&wc, 0, sizeof(wc));
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WindowFunc;
    wc.cbClsExtra  = 0;
    wc.cbWndExtra  = 0;
    wc.hInstance = hThisInst;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_WINDOW);
    wc.lpszClassName = szAppName;

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
        return FALSE;
    }

    HWND hWnd = CreateWindowEx(WS_EX_LAYERED, szAppName, wcWndName,
                    WS_VISIBLE | WS_POPUP, 200, 150, w, h,
                    NULL, NULL, hThisInst, NULL);
    if(!hWnd){
        MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
        return FALSE;
    }

    verify(SetLayeredWindowAttributes(hWnd, 0x0, 0, LWA_COLORKEY));

    MSG msg;
    while(1) 
    {
        while (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){
            if (GetMessage(&msg, NULL, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else return 0;
        }
    } 

    return (FALSE); 
}

6
এটি বলার অপেক্ষা রাখে না যে এই কৌশলটি জটিল রেন্ডারিং এবং গ্রাফিক্স অ্যানিমেশনগুলির জন্য ব্যবহারিক নয়। প্রতিটি ফ্রেমের জন্য র‍্যামে জিপিইউ ডেটা অনুলিপি করা সিপিইউতে খুব চাওয়া, ফলস্বরূপ কম low : এই উত্তরে মন্তব্য চেক করুন stackoverflow.com/questions/4780756/...
karlphillip

4
নোট করুন যে উইন্ডোজ ভিস্তা এবং উইন্ডোজ 7 এ আপনি নীচের আমার x11argb ডেমোর মত একই প্রভাব অর্জন করতে পারেন। PIXELFORMATDESCRIPTOR রচনাটি সক্ষম করতে একটি নতুন পতাকা সমর্থন করে। যদিও আমি এখনও এর জন্য একটি ডেমো তৈরি করতে পারি না। এপ্রিল পর্যন্ত ঘটবে না, যদিও আমি আবার সময় পেয়েছি।
ডেটনল্ফ

40

যেহেতু এখনও পর্যন্ত প্রদত্ত সমস্ত উত্তরগুলি কেবল উইন্ডোজকে লক্ষ্যবস্তু করেছে, তবে অবশ্যই এটি একটি যৌগিক উইন্ডো ম্যানেজারের সাথে এক্স 11 এ করার দাবি রয়েছে, রেফারেন্সের জন্য আমি এখানে আমার উদাহরণ কোডটি পোস্ট করি ( https://github.com/datewolf এও পাওয়া যাবে) / কোডসাম্পলস / ব্লব / মাস্টার / স্যাম্পলস / ওপেনজিএল / এক্স 11আরজিবি_অপেনগল/x11argb_opengl.c

/*------------------------------------------------------------------------
 * A demonstration of OpenGL in a  ARGB window 
 *    => support for composited window transparency
 *
 * (c) 2011 by Wolfgang 'datenwolf' Draxinger
 *     See me at comp.graphics.api.opengl and StackOverflow.com

 * License agreement: This source code is provided "as is". You
 * can use this source code however you want for your own personal
 * use. If you give this source code to anybody else then you must
 * leave this message in it.
 *
 * This program is based on the simplest possible 
 * Linux OpenGL program by FTB (see info below)

  The simplest possible Linux OpenGL program? Maybe...

  (c) 2002 by FTB. See me in comp.graphics.api.opengl

  --
  <\___/>
  / O O \
  \_____/  FTB.

------------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xrender.h>
#include <X11/Xutil.h>

#define USE_CHOOSE_FBCONFIG

static void fatalError(const char *why)
{
    fprintf(stderr, "%s", why);
    exit(0x666);
}

static int Xscreen;
static Atom del_atom;
static Colormap cmap;
static Display *Xdisplay;
static XVisualInfo *visual;
static XRenderPictFormat *pict_format;
static GLXFBConfig *fbconfigs, fbconfig;
static int numfbconfigs;
static GLXContext render_context;
static Window Xroot, window_handle;
static GLXWindow glX_window_handle;
static int width, height;

static int VisData[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_DOUBLEBUFFER, True,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 16,
None
};

static int isExtensionSupported(const char *extList, const char *extension)
{

  const char *start;
  const char *where, *terminator;

  /* Extension names should not have spaces. */
  where = strchr(extension, ' ');
  if ( where || *extension == '\0' )
    return 0;

  /* It takes a bit of care to be fool-proof about parsing the
     OpenGL extensions string. Don't be fooled by sub-strings,
     etc. */
  for ( start = extList; ; ) {
    where = strstr( start, extension );

    if ( !where )
      break;

    terminator = where + strlen( extension );

    if ( where == start || *(where - 1) == ' ' )
      if ( *terminator == ' ' || *terminator == '\0' )
        return 1;

    start = terminator;
  }
  return 0;
}

static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
{    
    return d && e && arg && (e->type == MapNotify) && (e->xmap.window == *(Window*)arg);
}

static void describe_fbconfig(GLXFBConfig fbconfig)
{
    int doublebuffer;
    int red_bits, green_bits, blue_bits, alpha_bits, depth_bits;

    glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DOUBLEBUFFER, &doublebuffer);
    glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_RED_SIZE, &red_bits);
    glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_GREEN_SIZE, &green_bits);
    glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_BLUE_SIZE, &blue_bits);
    glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_ALPHA_SIZE, &alpha_bits);
    glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DEPTH_SIZE, &depth_bits);

    fprintf(stderr, "FBConfig selected:\n"
        "Doublebuffer: %s\n"
        "Red Bits: %d, Green Bits: %d, Blue Bits: %d, Alpha Bits: %d, Depth Bits: %d\n",
        doublebuffer == True ? "Yes" : "No", 
        red_bits, green_bits, blue_bits, alpha_bits, depth_bits);
}

static void createTheWindow()
{
    XEvent event;
    int x,y, attr_mask;
    XSizeHints hints;
    XWMHints *startup_state;
    XTextProperty textprop;
    XSetWindowAttributes attr = {0,};
    static char *title = "FTB's little OpenGL example - ARGB extension by WXD";

    Xdisplay = XOpenDisplay(NULL);
    if (!Xdisplay) {
        fatalError("Couldn't connect to X server\n");
    }
    Xscreen = DefaultScreen(Xdisplay);
    Xroot = RootWindow(Xdisplay, Xscreen);

    fbconfigs = glXChooseFBConfig(Xdisplay, Xscreen, VisData, &numfbconfigs);
    fbconfig = 0;
    for(int i = 0; i<numfbconfigs; i++) {
        visual = (XVisualInfo*) glXGetVisualFromFBConfig(Xdisplay, fbconfigs[i]);
        if(!visual)
            continue;

        pict_format = XRenderFindVisualFormat(Xdisplay, visual->visual);
        if(!pict_format)
            continue;

        fbconfig = fbconfigs[i];
        if(pict_format->direct.alphaMask > 0) {
            break;
        }
    }

    if(!fbconfig) {
        fatalError("No matching FB config found");
    }

    describe_fbconfig(fbconfig);

    /* Create a colormap - only needed on some X clients, eg. IRIX */
    cmap = XCreateColormap(Xdisplay, Xroot, visual->visual, AllocNone);

    attr.colormap = cmap;
    attr.background_pixmap = None;
    attr.border_pixmap = None;
    attr.border_pixel = 0;
    attr.event_mask =
        StructureNotifyMask |
        EnterWindowMask |
        LeaveWindowMask |
        ExposureMask |
        ButtonPressMask |
        ButtonReleaseMask |
        OwnerGrabButtonMask |
        KeyPressMask |
        KeyReleaseMask;

    attr_mask = 
        CWBackPixmap|
        CWColormap|
        CWBorderPixel|
        CWEventMask;

    width = DisplayWidth(Xdisplay, DefaultScreen(Xdisplay))/2;
    height = DisplayHeight(Xdisplay, DefaultScreen(Xdisplay))/2;
    x=width/2, y=height/2;

    window_handle = XCreateWindow(  Xdisplay,
                    Xroot,
                    x, y, width, height,
                    0,
                    visual->depth,
                    InputOutput,
                    visual->visual,
                    attr_mask, &attr);

    if( !window_handle ) {
        fatalError("Couldn't create the window\n");
    }

#if USE_GLX_CREATE_WINDOW
    int glXattr[] = { None };
    glX_window_handle = glXCreateWindow(Xdisplay, fbconfig, window_handle, glXattr);
    if( !glX_window_handle ) {
        fatalError("Couldn't create the GLX window\n");
    }
#else
    glX_window_handle = window_handle;
#endif

    textprop.value = (unsigned char*)title;
    textprop.encoding = XA_STRING;
    textprop.format = 8;
    textprop.nitems = strlen(title);

    hints.x = x;
    hints.y = y;
    hints.width = width;
    hints.height = height;
    hints.flags = USPosition|USSize;

    startup_state = XAllocWMHints();
    startup_state->initial_state = NormalState;
    startup_state->flags = StateHint;

    XSetWMProperties(Xdisplay, window_handle,&textprop, &textprop,
            NULL, 0,
            &hints,
            startup_state,
            NULL);

    XFree(startup_state);

    XMapWindow(Xdisplay, window_handle);
    XIfEvent(Xdisplay, &event, WaitForMapNotify, (char*)&window_handle);

    if ((del_atom = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", 0)) != None) {
        XSetWMProtocols(Xdisplay, window_handle, &del_atom, 1);
    }
}

static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
{
    fputs("Error at context creation", stderr);
    return 0;
}

static void createTheRenderContext()
{
    int dummy;
    if (!glXQueryExtension(Xdisplay, &dummy, &dummy)) {
        fatalError("OpenGL not supported by X server\n");
    }

#if USE_GLX_CREATE_CONTEXT_ATTRIB
    #define GLX_CONTEXT_MAJOR_VERSION_ARB       0x2091
    #define GLX_CONTEXT_MINOR_VERSION_ARB       0x2092
    render_context = NULL;
    if( isExtensionSupported( glXQueryExtensionsString(Xdisplay, DefaultScreen(Xdisplay)), "GLX_ARB_create_context" ) ) {
        typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
        glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
        if( glXCreateContextAttribsARB ) {
            int context_attribs[] =
            {
                GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
                GLX_CONTEXT_MINOR_VERSION_ARB, 0,
                //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
                None
            };

            int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler);

            render_context = glXCreateContextAttribsARB( Xdisplay, fbconfig, 0, True, context_attribs );

            XSync( Xdisplay, False );
            XSetErrorHandler( oldHandler );

            fputs("glXCreateContextAttribsARB failed", stderr);
        } else {
            fputs("glXCreateContextAttribsARB could not be retrieved", stderr);
        }
    } else {
            fputs("glXCreateContextAttribsARB not supported", stderr);
    }

    if(!render_context)
    {
#else
    {
#endif
        render_context = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0, True);
        if (!render_context) {
            fatalError("Failed to create a GL context\n");
        }
    }

    if (!glXMakeContextCurrent(Xdisplay, glX_window_handle, glX_window_handle, render_context)) {
        fatalError("glXMakeCurrent failed for window\n");
    }
}

static int updateTheMessageQueue()
{
    XEvent event;
    XConfigureEvent *xc;

    while (XPending(Xdisplay))
    {
        XNextEvent(Xdisplay, &event);
        switch (event.type)
        {
        case ClientMessage:
            if (event.xclient.data.l[0] == del_atom)
            {
                return 0;
            }
        break;

        case ConfigureNotify:
            xc = &(event.xconfigure);
            width = xc->width;
            height = xc->height;
            break;
        }
    }
    return 1;
}

/*  6----7
   /|   /|
  3----2 |
  | 5--|-4
  |/   |/
  0----1

*/

GLfloat cube_vertices[][8] =  {
    /*  X     Y     Z   Nx   Ny   Nz    S    T */
    {-1.0, -1.0,  1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0
    { 1.0, -1.0,  1.0, 0.0, 0.0, 1.0, 1.0, 0.0}, // 1
    { 1.0,  1.0,  1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2
    {-1.0,  1.0,  1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3

    { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0}, // 4
    {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0}, // 5
    {-1.0,  1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0}, // 6
    { 1.0,  1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0}, // 7

    {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0}, // 5
    {-1.0, -1.0,  1.0, -1.0, 0.0, 0.0, 1.0, 0.0}, // 0
    {-1.0,  1.0,  1.0, -1.0, 0.0, 0.0, 1.0, 1.0}, // 3
    {-1.0,  1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, // 6

    { 1.0, -1.0,  1.0,  1.0, 0.0, 0.0, 0.0, 0.0}, // 1
    { 1.0, -1.0, -1.0,  1.0, 0.0, 0.0, 1.0, 0.0}, // 4
    { 1.0,  1.0, -1.0,  1.0, 0.0, 0.0, 1.0, 1.0}, // 7
    { 1.0,  1.0,  1.0,  1.0, 0.0, 0.0, 0.0, 1.0}, // 2

    {-1.0, -1.0, -1.0,  0.0, -1.0, 0.0, 0.0, 0.0}, // 5
    { 1.0, -1.0, -1.0,  0.0, -1.0, 0.0, 1.0, 0.0}, // 4
    { 1.0, -1.0,  1.0,  0.0, -1.0, 0.0, 1.0, 1.0}, // 1
    {-1.0, -1.0,  1.0,  0.0, -1.0, 0.0, 0.0, 1.0}, // 0

    {-1.0, 1.0,  1.0,  0.0,  1.0, 0.0, 0.0, 0.0}, // 3
    { 1.0, 1.0,  1.0,  0.0,  1.0, 0.0, 1.0, 0.0}, // 2
    { 1.0, 1.0, -1.0,  0.0,  1.0, 0.0, 1.0, 1.0}, // 7
    {-1.0, 1.0, -1.0,  0.0,  1.0, 0.0, 0.0, 1.0}, // 6
};

static void draw_cube(void)
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][0]);
    glNormalPointer(GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][3]);
    glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][6]);

    glDrawArrays(GL_QUADS, 0, 24);
}

float const light0_dir[]={0,1,0,0};
float const light0_color[]={78./255., 80./255., 184./255.,1};

float const light1_dir[]={-1,1,1,0};
float const light1_color[]={255./255., 220./255., 97./255.,1};

float const light2_dir[]={0,-1,0,0};
float const light2_color[]={31./255., 75./255., 16./255.,1};

static void redrawTheWindow()
{
    float const aspect = (float)width / (float)height;

    static float a=0;
    static float b=0;
    static float c=0;

    glDrawBuffer(GL_BACK);

    glViewport(0, 0, width, height);

    // Clear with alpha = 0.0, i.e. full transparency
        glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-aspect, aspect, -1, 1, 2.5, 10);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glLightfv(GL_LIGHT0, GL_POSITION, light0_dir);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);

    glLightfv(GL_LIGHT1, GL_POSITION, light1_dir);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_color);

    glLightfv(GL_LIGHT2, GL_POSITION, light2_dir);
    glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_color);

    glTranslatef(0., 0., -5.);

    glRotatef(a, 1, 0, 0);
    glRotatef(b, 0, 1, 0);
    glRotatef(c, 0, 0, 1);

    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHT1);
    glEnable(GL_LIGHTING);

    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

    glColor4f(1., 1., 1., 0.5);

    glCullFace(GL_FRONT);
    draw_cube();
    glCullFace(GL_BACK);
    draw_cube();

    a = fmod(a+0.1, 360.);
    b = fmod(b+0.5, 360.);
    c = fmod(c+0.25, 360.);

    glXSwapBuffers(Xdisplay, glX_window_handle);
}

int main(int argc, char *argv[])
{
    createTheWindow();
    createTheRenderContext();

    while (updateTheMessageQueue()) {
        redrawTheWindow();
    }

    return 0;
}

মূল কৌশলটি সঠিক এফবিসিফোনফিগ পাচ্ছে। আপনাকে একটি আলফা চ্যানেলের জন্য জিজ্ঞাসা করতে হবে এবংXRenderPictFormat একটি আলফা মাস্কের উপস্থিতির জন্য সম্পর্কিতটি পরীক্ষা করতে হবে ।


6
উউউউউউউউ! অবিশ্বাস্য! আমি এটিকে সংকলিত: g++ gl_transparent.cpp -o gl_transparent -lGL -lX11 -lXext -lXrender। এটি একটি সম্প্রদায়ের উইকি হয়ে উঠতে পারে, যদি আমরা আজও এই ধরণের জিনিসটি করি।
করলফিলিপ

@ কার্লফিলিপ: আমার গিথুব সংগ্রহশালায় আপনি একটি মেকফাইল পেয়েছেন। এবং এই ডেমোসের একটি বৈকল্পিক যা একটি তরঙ্গ প্রভাব যোগ করতে একটি খণ্ড শ্যাডার ব্যবহার করে - কেবল আইক্যান্ডির জন্য। দুর্ভাগ্যক্রমে "ব্যাকগ্রাউন্ড" শেডার এফেক্টে অন্তর্ভুক্ত করা সম্ভব নয়, কারণ সমস্ত উইন্ডো তাদের বিষয়বস্তু আঁকার পরে পুরো পটভূমিটি কেবলমাত্র কম্পোজিটার দ্বারা তৈরি করা হয়েছিল।
ডেটনল্ফ

আমি বুঝেছি. সতর্ক থাকুন জন্য ধন্যবাদ।
করলফিলিপ

4
@ ডাটেনওল্ফ আমি মূলত সহায়তা চেয়েছিলাম তবে আমি আপনার কোডটিকে আধুনিক ওপেনগিএলে রূপান্তর করতে সফল হয়েছি। ভবিষ্যতের রেফারেন্সের জন্য আমি আমার সমাধানটি এখানে কিছুটা পোস্ট করব।
syk435

4
টিউটোরিয়ালগুলির জন্য অনেক ধন্যবাদ। আমিও এটি বর্ডার ছাড়াই চাই। আমি ওপেনগেল ব্যবহার করে একটি রাবারব্যান্ড (পর্দায় আয়তক্ষেত্র অঙ্কন) তৈরি করতে চাই তবে এর কোনও উদাহরণ আমি পাইনি।
Kenn

30

আমি জানি উইন্ডোজ 7 এর মাধ্যমে এটি সম্ভব, পূর্ববর্তী সংস্করণ সম্পর্কে নিশ্চিত নয়।

উইন্ডো সীমানা থেকে মুক্তি পেতে আপনাকে WS_OVERLAPPEDWINDOWউইন্ডো থেকে স্টাইলটি সরিয়ে স্টাইলটি যুক্ত করতে হবে WS_POPUP:

DWORD style = ::GetWindowLong(hWnd, GWL_STYLE);
style &= ~WS_OVERLAPPEDWINDOW;
style |= WS_POPUP;
::SetWindowLong(hWnd, GWL_STYLE, style);

ওপেনএল উইন্ডোটির পটভূমি স্বচ্ছ করতে, আপনাকে এই DwmEnableBlurBehindWindowফাংশনটি ব্যবহার করতে হবে:

DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;
bb.hRgnBlur = NULL;
DwmEnableBlurBehindWindow(hWnd, &bb);

কল করার সময় আপনাকে আলফা মানটির জন্য 0 নির্দিষ্ট করতে হবে glClearColor

glClearColor(0.0f,0.0f,0.0f,0.0f);

এছাড়াও, আপনার ওপেনএল প্রসঙ্গটি তৈরি করার সময়, নিশ্চিত করুন যে আপনি একটি আলফা চ্যানেল বরাদ্দ করেছেন।

এখন আপনার ব্যাকগ্রাউন্ড সম্পূর্ণ স্বচ্ছ হওয়া উচিত। আপনি যদি উইন্ডো সজ্জা রাখেন, তবে ব্যাকগ্রাউন্ডটি এ্যারো ব্লার চেহারাটি ব্যবহার করবে এবং আপনি আলফা মানটি ব্যবহার করে স্বচ্ছতার স্তরটি সামঞ্জস্য করতে পারবেন glClearColor


5
ধন্যবাদ, তবে DwmEnableBlurBehindWindow () DWM এর একটি অংশ, যা Win32 API এর সাথে সম্পর্কিত নয়। এই সমাধানটি উইন্ডোজ ভিস্তা এবং তারপরের জন্য কাজ করে।
করলফিলিপ

@ কার্ফিলিপ: প্রাক-ভিস্তা উইন্ডোজ: এস-এর ডেস্কটপ কম্পোজিটিং নেই, তাই আমি নিশ্চিত না যে আপনি সেখানে এটি সুন্দরভাবে করতে পারবেন।
ম্যাক 16

@ কার্ফিলিপ দুঃখিত, আমি ব্যক্তিগতভাবে এক্সপির সাথে স্বচ্ছ ওপেনজিএল উইন্ডোজ অর্জন করতে পারি নি, তবে এটি সম্পর্কে ওপেনএল ফোরামে পোস্টগুলি মনে আছে। আরও তথ্যের জন্য নিম্নলিখিত অনুসন্ধান ফলাফলগুলি সন্ধানের চেষ্টা করছেন: google.com/…
ফ্ল্যাশ

4
এটি সত্যই সহায়ক ছিল, তবে আমি নিম্নলিখিতগুলি যুক্ত করতে চাই: আমার জন্য উপরের পদ্ধতিটি ডিফল্ট উইন 7 অস্পষ্ট এবং জাল আলো প্রতিচ্ছবি সহ সমস্ত পটভূমি রেন্ডার করেছে। দাগ পরিত্রাণ পেতে এবং completeley স্বচ্ছ উইন্ডোর সুবিধা পান করার জন্য, আমি সেট bb.hRgnBlurকরতে পরামিতি CreateRectRgn(0, 0, 1, 1);এবং bb.dwFlagsকরতে DWM_BB_ENABLE | DWM_BB_BLURREGION;। এটি হুবহু এক পিক্সেল অস্পষ্ট করবে এবং পুরো উইন্ডোটি (যেখানে গ্লক্লিয়ার দিয়ে পরিষ্কার করা হবে) সম্পূর্ণ স্বচ্ছ হিসাবে দেখায়।
pholz

আমি এটি চেষ্টা করার সময়, আমি পেতে identifier "DWM_BLURBEHIND" is undefined। আমি অন্তর্ভুক্ত করা প্রয়োজন একটি লাইব্রেরি আছে?
স্টিভোসিয়াক

24

এটি একটি পুরানো প্রশ্ন, তবে যেহেতু উইন্ডোজের নতুন সংস্করণগুলিতে ওপেনগলের জন্য ডেটনওয়াল্ফের ইঙ্গিত হিসাবে রচনা এবং সমর্থন রয়েছে, আমরা এটি সম্পাদন করার জন্য সেই বিশেষ কিছু সস ব্যবহার করতে পারি। যদিও এটি ডাইরেক্টএক্স (গো চিত্র ...) এর সাথেও তুচ্ছ, মাইক্রোসফ্ট ওপেনগল প্রসঙ্গগুলিতে মিশ্রকরণের ইঙ্গিতগুলি যুক্ত করেছিল। ইয়া অবিশ্বাসের ভয়!

সুতরাং একটি অকার্যকর অনুলিপি-থেকে-শারীরিক-মেমরি অ্যাকশনের পরিবর্তে, কমপোজিটিং ইঞ্জিনটি কীভাবে ওপেনগেল প্রসঙ্গটি ব্যবহার করতে হয় তা বুঝতে পারি।

সুতরাং, আপনাকে একটি পিক্সেলফর্মেটের সাথে একটি ওপেনগেল প্রসঙ্গ তৈরি করতে হবে যা একটি আলফা চ্যানেল নির্দিষ্ট করে এবং এটি রচনা (লাইন ৮২) ব্যবহার করা উচিত। তারপরে, আপনি পুরোপুরি অবৈধ অঞ্চল নির্দিষ্ট করে একটি অস্পষ্ট উইন্ডো (লাইন 179) সক্ষম করতে DwmApi.h রুটিন ব্যবহার করেন, যা কিছুই ঝাপসা করবে না এবং উইন্ডোটিকে স্বচ্ছ ছেড়ে দেবে। (উইন্ডো ক্লাসে আপনাকে একটি কালো + স্বচ্ছ ব্রাশ নির্দিষ্ট করা দরকার! অদ্ভুতভাবে!) তারপরে, আপনি আসলে ওপেনগেলটি ব্যবহার করার অভ্যস্ত হিসাবে ব্যবহার করেন। ইভেন্টের লুপে, প্রতিটি সুযোগ আপনি পাবেন, আপনি কেবল বাফারগুলি আঁকতে এবং অদলবদল করতে পারবেন (লাইন 201) এবং GL_BLEND সক্ষম করতে ভুলবেন না! :)

দয়া করে পর্যালোচনা করুন / কাঁটাচামড়া https://gist.github.com/3644466 বা পরিবর্তে এই কৌশলটি দিয়ে ওপি-র নিজস্ব উত্তরের ভিত্তিতে নিম্নলিখিত কোড স্নিপেটটি দেখুন (আপনি খালি প্রকল্পে এটি খাঁটি করতে পারেন):

#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <dwmapi.h>

#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")

#pragma comment (lib, "dwmapi.lib")

#include <assert.h>
#include <tchar.h>

#ifdef  assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif

const TCHAR szAppName[]=_T("TransparentGL");
const TCHAR wcWndName[]=_T("TransparentGL");

HDC hDC;            
HGLRC m_hrc;        
int w = 240;
int h = 240;

BOOL initSC() {
    glEnable(GL_ALPHA_TEST);        
    glEnable(GL_DEPTH_TEST);        
    glEnable(GL_COLOR_MATERIAL);

    glEnable(GL_LIGHTING);          
    glEnable(GL_LIGHT0);            

    glEnable(GL_BLEND);             
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0, 0, 0, 0);

    return 0;
}

void resizeSC(int width,int height) {
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW );
    glLoadIdentity();
}

BOOL renderSC() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glPushMatrix();

    glColor3f(0, 1, 1);
    glBegin(GL_TRIANGLES);                              // Drawing Using Triangles
        glColor3f(1.0f,0.0f,0.0f);                      // Set The Color To Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top
        glColor3f(0.0f,1.0f,0.0f);                      // Set The Color To Green
        glVertex3f(-1.0f,-1.0f, 0.0f);                  // Bottom Left
        glColor3f(0.0f,0.0f,1.0f);                      // Set The Color To Blue
        glVertex3f( 1.0f,-1.0f, 0.0f);                  // Bottom Right
    glEnd();

    glPopMatrix();
    glFlush();

    return 0;
}

BOOL CreateHGLRC(HWND hWnd) {
    PIXELFORMATDESCRIPTOR pfd = {
      sizeof(PIXELFORMATDESCRIPTOR),
      1,                                // Version Number
      PFD_DRAW_TO_WINDOW      |         // Format Must Support Window
      PFD_SUPPORT_OPENGL      |         // Format Must Support OpenGL
      PFD_SUPPORT_COMPOSITION |         // Format Must Support Composition
      PFD_DOUBLEBUFFER,                 // Must Support Double Buffering
      PFD_TYPE_RGBA,                    // Request An RGBA Format
      32,                               // Select Our Color Depth
      0, 0, 0, 0, 0, 0,                 // Color Bits Ignored
      8,                                // An Alpha Buffer
      0,                                // Shift Bit Ignored
      0,                                // No Accumulation Buffer
      0, 0, 0, 0,                       // Accumulation Bits Ignored
      24,                               // 16Bit Z-Buffer (Depth Buffer)
      8,                                // Some Stencil Buffer
      0,                                // No Auxiliary Buffer
      PFD_MAIN_PLANE,                   // Main Drawing Layer
      0,                                // Reserved
      0, 0, 0                           // Layer Masks Ignored
   };     

   HDC hdc = GetDC(hWnd);
   int PixelFormat = ChoosePixelFormat(hdc, &pfd);
   if (PixelFormat == 0) {
      assert(0);
      return FALSE ;
   }

   BOOL bResult = SetPixelFormat(hdc, PixelFormat, &pfd);
   if (bResult==FALSE) {
      assert(0);
      return FALSE ;
   }

   m_hrc = wglCreateContext(hdc);
   if (!m_hrc){
      assert(0);
      return FALSE;
   }

   ReleaseDC(hWnd, hdc);

   return TRUE;
}

LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam) {
    PAINTSTRUCT ps;

    switch(msg) {
        case WM_CREATE:
        break;

        case WM_DESTROY:
            if(m_hrc) {
                wglMakeCurrent(NULL, NULL);
                wglDeleteContext(m_hrc) ;
            }
            PostQuitMessage(0) ;
        break;

        default: 
            return DefWindowProc(hWnd,msg,wParam,lParam);
    }

    return 0;
}

int WINAPI _tWinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str,int nWinMode) {
    WNDCLASSEX wc;
    memset(&wc, 0, sizeof(wc));
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WindowFunc;
    wc.cbClsExtra  = 0;
    wc.cbWndExtra  = 0;
    wc.hInstance = hThisInst;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000);
    wc.lpszClassName = szAppName;

    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
        return FALSE;
    }

    HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW, szAppName, wcWndName,
                    WS_VISIBLE | WS_POPUP, 200, 150, w, h,
                    NULL, NULL, hThisInst, NULL);

    if(!hWnd) {
        MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
        return FALSE;
    }

    DWM_BLURBEHIND bb = {0};
    HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
    bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
    bb.hRgnBlur = hRgn;
    bb.fEnable = TRUE;
    DwmEnableBlurBehindWindow(hWnd, &bb);

    CreateHGLRC(hWnd);

    HDC hdc = GetDC(hWnd);
    wglMakeCurrent(hdc, m_hrc);
    initSC();
    resizeSC(w, h);
    ReleaseDC(hWnd, hdc);

    MSG msg;  
    while(1) {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else {
            HDC hdc = GetDC(hWnd);
            wglMakeCurrent(hdc, m_hrc);

            renderSC();

            SwapBuffers(hdc);
            ReleaseDC(hWnd, hdc);
        }
    } 

    return (FALSE); 
}

4
উইন on. এ দুর্দান্ত কাজ করে I আমি উইন্ডোটি স্ক্রিনের চেয়ে 1 পিক্সেল লম্বা করে তৈরি করতে সক্ষম window_x = 0, window_y = -1, window_width = screen_width, window_height = screen_height + 1হয়েছি, glViewport(0, 0, screen_width, screen_height)যেমন তৈরি উইন্ডোএক্সে পাস করা মান হিসাবে ব্যবহার করুন , তারপরে যথারীতি কল করুন ।
জন মেল্লার

জমকালো উত্তর! ঠিক আমার যা প্রয়োজন ছিল। অন্য সমস্ত উত্তরগুলি একটি অফস্ক্রিন বাফার এবং তারপরে বিটব্লট () এ অঙ্কন করার পদ্ধতিকে দেখায় যা এটি দৃশ্যমান অঙ্কনের প্রসঙ্গে দেখা যায় যা অতি ধীর এবং কোনও গুরুতর অ্যাপ্লিকেশনের জন্য কাজ করে না।
জুরলি

10

ওপেনজিএল উইন্ডোগুলিকে স্তরযুক্ত করার অনুমতি দেওয়া থাকলে এটি খুব সহজ হবে। তবে সেগুলি নয়, সুতরাং আপনাকে অন্য কোনও কিছুর জন্য যেতে হবে।

আপনি যা করতে পারেন তা হ'ল স্তরযুক্ত উইন্ডো (WS_EX_LAYERED + সেটলেয়ারড উইন্ডোঅ্যাট্রিবিউটস () - গুগল এম যদি আপনি তাদের না জানেন) এবং রেন্ডারিংয়ের জন্য একটি লুকানো ওপেনএল উইন্ডো তৈরি করুন। ওপেনজিএল দৃশ্যের একটি অফ-স্ক্রিন বাফারকে রেন্ডার করুন, এটি আবার পড়ুন এবং স্তরযুক্ত উইন্ডোটি দিয়ে ভাগ করুন, তারপরে বিটব্ল্ট (জিডিআই ফাংশন) এটি স্তরযুক্ত উইন্ডোতে।

এটি খুব জটিল স্টাফের জন্য খুব ধীর হতে পারে তবে উইন্ডোজ 2000 এবং ততোধিক সংস্করণে আপনি যে প্রভাবটি চেয়েছেন তা আপনাকে কার্যকরভাবে দেবে।

সম্পাদনা: আসল অফ-স্ক্রিন বাফারটি তৈরি করার ক্ষেত্রে ফ্রেমবফার অবজেক্টস (এফবিও) সম্ভবত আপনার সেরা বাজি bet আপনি কেবল লুকানো ওপেনলএল উইন্ডোতে আঁকতে পারেন, যদিও আমি মনে করি যে আমি পিক্সেলের মালিকানার কারণে এমন কাউকে সমস্যায় পড়ার বিষয়ে পোস্ট করা স্মরণ করি - এফবিও প্রস্তাবিত হয়। আপনি পিক্সেল বাফার (পুফারস) ব্যবহার করতে পারেন তবে এগুলি পুরানো (স্ট্যাম্পড "উত্তরাধিকার") এবং এফবিওগুলিকে এটি করার আধুনিক উপায় হিসাবে বিবেচনা করা হয়। এফবিওগুলিকে আপনাকে হার্ডওয়্যার ত্বরণ দেওয়া উচিত (যদি সমর্থিত হয়), এবং নিজেই আপনাকে কোনও নির্দিষ্ট ওপেনএল সংস্করণে সীমাবদ্ধ করে না। এটি ব্যবহারের জন্য আপনার একটি ওপেনলএল প্রসঙ্গের প্রয়োজন হবে, সুতরাং আপনাকে সেই লুকানো ওপেনজিএল উইন্ডোটি তৈরি করতে হবে এবং সেখান থেকে এফবিও সেট আপ করতে হবে।

এখানে এফবিওগুলির কিছু সংস্থান রয়েছে:
উইকিপিডিয়া
এফবিও
গেমদেব নিবন্ধ
গাইড (ম্যাকের জন্য, তবে সহায়ক হতে পারে)


এটি আমার পরামর্শের মতো। আপনার ওপেনএল দৃশ্যটি মেমোরিতে রেন্ডার করুন (FBO বা অনুরূপ) এবং তারপরে বিটম্যাপ অবজেক্টে সঞ্চয় করতে glReadPixels ব্যবহার করুন। তারপরে আপনি আপনার স্বচ্ছ রঙ চয়ন করতে এবং এটি জিডিআই ব্যবহার করে স্ক্রিনে বিটব্ল্ট করতে পারেন।
Giawa

7

উত্স সহ দুর্দান্ত গণতন্ত্র আপনাকে ধাপে ধাপে নিয়ে যাচ্ছেন:

http://www.dhpoware.com/demos/index.html


"যেমন OpenGL স্তরপূর্ণ উইন্ডোজ" ডেমো মূলত এটা করতে সবচেয়ে ভালো উপায়, একটি pbuffer অনেক দ্রুত একটি টাকাপয়সা directly.DIB মধ্যে রেন্ডারিং চেয়ে সাধারণত সফ্টওয়্যার রেন্ডারার যেখানে pbuffer ত্বরিত ব্যবহার করা হয়
ক্রিস্টোফার লয়েড

2

আমি জানি এটি পুরানো, তবে আমি Gtk + এর Xlib সমাধানটি পোর্ট করার চেষ্টা করছিলাম। অনেক অধ্যয়নের পরে অবশেষে আমি এটি তৈরি করেছিলাম তাই আমি প্রয়োজনের জন্য এখানে সত্যিই এটি ভাগ করতে চাই।

#include <gtk/gtk.h>
#include <gdk/gdkscreen.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtkgl.h>
#include <GL/gl.h>
#include <GL/glu.h>

static gboolean supports_alpha = FALSE;

/***
 *** Configure the OpenGL framebuffer.
***/
static GdkGLConfig* configure_gl(void)
{
    GdkGLConfig* glconfig;

    /* Try double-buffered visual */
    glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGBA |
        GDK_GL_MODE_ALPHA |
        GDK_GL_MODE_DEPTH |
        GDK_GL_MODE_DOUBLE);
    if (glconfig == NULL)
    {
        printf("Cannot find the double-buffered visual.\n");
        printf("No appropriate OpenGL-capable visual found.\n");
        exit(1);
    }
    printf("Find GLConfig with alpha channel.\n");
    return glconfig;
}

static void screen_changed(GtkWidget* widget, GdkScreen* old_screen, gpointer userdata)
{
    /* To check if the display supports alpha channels, get the colormap */
    GdkScreen* screen = gtk_widget_get_screen(widget);
    GdkColormap* colormap = gdk_screen_get_rgba_colormap(screen);

    if (!colormap)
    {
        printf("Your screen does not support alpha channels!\n");
        colormap = gdk_screen_get_rgb_colormap(screen);
        supports_alpha = FALSE;
    }
    else
    {
        printf("Your screen supports alpha channels!\n");
        supports_alpha = TRUE;
    }

    gtk_widget_set_colormap(widget, colormap);
}

static gboolean expose(GtkWidget* widget, GdkEventExpose* event, gpointer userdata)
{
    GdkGLContext* glcontext = gtk_widget_get_gl_context(widget);
    GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(widget);

    if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
    {
        return FALSE;
    }

    glDrawBuffer(GL_BACK);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glBegin(GL_QUADS);
    glColor4f(1.0f, 0.0f, 0.0f, 0.3f);
    glVertex3f(-0.5f, -0.5f, 0);
    glVertex3f(+0.5f, -0.5f, 0);
    glVertex3f(+0.5f, +0.5f, 0);
    glVertex3f(-0.5f, +0.5f, 0);
    glEnd();

    gdk_gl_drawable_swap_buffers(gldrawable);

    gdk_gl_drawable_gl_end(gldrawable);
    return TRUE;
}

int main(int argc, char** argv)
{
    gtk_init(&argc, &argv);

    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    /* Added to config GLConfig */
    GdkGLConfig* glconfig = configure_gl();
    gtk_widget_set_gl_capability(window,
        glconfig,
        NULL,
        TRUE,
        GDK_GL_RGBA_TYPE);

    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
    gtk_window_set_title(GTK_WINDOW(window), "Alpha Demo");
    g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL);

    gtk_widget_set_app_paintable(window, TRUE);

    g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(expose), NULL);
    g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL);

    screen_changed(window, NULL, NULL);

    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

সঙ্গে সংকলিত gcc main.c -o main `pkg-config --libs --cflags gtk+-2.0 gtkglext-1.0`। উবুন্টু 18.04 এ পরীক্ষিত (জিটিকে ছাড়াও, আপনাকে ইনস্টল করতে হবে libgtkglext1-dev)।

সম্পাদনা

আমি রেন্ডারিং কোডটি কেবল একটি glClearথেকে একটি আয়তক্ষেত্রে পরিবর্তন করেছি।

কোড থেকে একটি পরিবর্তিত সংস্করণ এই প্রশ্নের এবং এই প্রশ্নের

এখানে চিত্র বর্ণনা লিখুন


আকর্ষণীয়, আপনি যে লিঙ্কগুলি ভাগ করেছেন তার মধ্যে একটি আমার অন্য উত্তর থেকেও। সমস্ত কিছু নিশ্চিত করার জন্য নিশ্চিত করুন। আপনি যদি এই প্রোগ্রামটির স্ক্রিনশটটি চলমান থাকে তাই এটি দেখতে কেমন তা আমরা জানি তবে আমি এই উত্তরটি দিয়েছি।
করলফিলিপ

ওহ দুঃখিত, যদিও আমি স্ট্যাকওভারফ্লোটি প্রচুর পরিমাণে ব্যবহার করেছি (গুগল থেকে), আমি আমার পাসওয়ার্ডটি হারিয়েছি এবং দীর্ঘক্ষণ লগইন করেছি না। ভবিষ্যতে আমি তা করবো। অন্যান্য উত্তরের জন্যও ধন্যবাদ।
উ ঝেনওয়ে

এবং পরামর্শের জন্য ধন্যবাদ। আমি উন্নতি করতে একটি স্ক্রিনশট যুক্ত করার চেষ্টা করব তবে এটি ভোট দেওয়া উচিত বা না করা তা এখনও আপনার নিজের পছন্দ। @ কারলফিলিপ
উউ ঝেনওয়ে

এই স্ক্রিনশটটি আপনার উত্তরে অনেক মূল্য যুক্ত করবে।
করলফিলিপ

1

আপনি একটি পাবুফারটিতে 3 ডি দৃশ্যটি রেন্ডার করতে পারেন এবং একটি রঙ কী ব্যবহার করে স্ক্রিনে ব্লিট করতে পারেন।


1

ক্ল্যানলিব গেম এসডিকে এটি করে।

আপনার যদি কেবল স্থিতিশীল স্বচ্ছ সীমানার প্রয়োজন হয় তবে নিম্নলিখিত কৌশলটি ব্যবহার করুন:

5 টি উইন্ডো তৈরি করে

এএএএএএ

খ ### গ

খ ### গ

ডিডিডিডিডি

এ, বি, সি, ডি স্তরযুক্ত উইন্ডো

"#" হ'ল মূল উইন্ডো।

নীচের চিত্রগুলি দেখুন - http://clanlib.org/wiki/ClanLib_2.2.9_ দয়া করে_নোটস


4
ধন্যবাদ, তবে প্রশ্নটি কেবল উইন 32 এপিআই ব্যবহার করে এই প্রভাবটি কীভাবে করবেন তা বিশেষভাবে জিজ্ঞাসা করে ।
করলফিলিপ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.