Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Window - independent rendering contexts

  1. #1
    Intern Contributor
    Join Date
    Aug 2000
    Posts
    60

    Window - independent rendering contexts

    I am using OpenGL on Windows. How can I create a rendering context that is independent of a window? I do not want to render directly to a window, I would rather have OpenGL render directly to an offscreen surface such as a DIB, a block of RGB memory, or to an IDirectDrawSurface. How could I do this?

  2. #2
    Junior Member Regular Contributor
    Join Date
    Jun 2000
    Location
    Bucharest, Romania
    Posts
    113

    Re: Window - independent rendering contexts

    I don't think you can because when you create the window you have to specify the pixel format. Just now I'm studyind the same problem and please if you can make something from it say it on the forum because I'm interested.

    NewROmancer

  3. #3
    Member Regular Contributor
    Join Date
    Jul 2000
    Location
    Augsburg, Germany
    Posts
    415

    Re: Window - independent rendering contexts

    Look here:

    http://www.opengl.org/discussion_boa...ML/001072.html


    [This message has been edited by Kilam Malik (edited 08-14-2000).]

  4. #4
    Intern Contributor
    Join Date
    Aug 2000
    Posts
    60

    Re: Window - independent rendering contexts

    Thanks, this looks like it will work for me. I'll post a description of the results.

  5. #5
    Intern Contributor
    Join Date
    Aug 2000
    Posts
    60

    Re: Window - independent rendering contexts

    I used the code from post #8 on the forum you mentioned and it worked the very first time!! Thanks a million!!!

  6. #6
    Intern Contributor
    Join Date
    Aug 2000
    Posts
    60

    Re: Window - independent rendering contexts

    Here's my source code. It won't compile because it uses some of my own units but if you take out the unused stuff it will work. The program was written using Delphi 5.

    This is actually the beginnings of an OpenGL wrapper I have been working on for a few days. OpenGL programming is way easier than DirectDraw and Direct3DRM!!! Stuff actually does what it is suppose to do!

  7. #7
    Intern Contributor
    Join Date
    Aug 2000
    Posts
    60

    Re: Window - independent rendering contexts

    unit MainForm;

    interface
    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    OpenGL12, Oogle
    ;

    type
    TfrmMain = class(TForm)
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);

    public
    rc: IOogleRenderDest;

    end;

    var
    frmMain: TfrmMain;

    implementation
    {$R *.DFM}

    procedure TfrmMain.FormPaint(Sender: TObject);
    begin
    rc.Start;
    try
    glBegin(GL_TRIANGLES);
    glColor3F(1, 1, 1);
    glVertex3F(0, 0, 0);
    glVertex3F(0.9, 0, 0);
    glVertex3F(1, 1, 0);
    glEnd;
    finally
    rc.Finish;
    end;
    rc.BitBlt(Canvas.Handle, 0, 0);
    end;

    procedure TfrmMain.FormCreate(Sender: TObject);
    begin
    InitOpenGL;
    rc := TOogleRenderDestBitmap.Create(ClientWidth, ClientHeight);
    end;

    end.


    [This message has been edited by skippyj777 (edited 08-14-2000).]

    [This message has been edited by skippyj777 (edited 08-14-2000).]

  8. #8
    Intern Contributor
    Join Date
    Aug 2000
    Posts
    60

    Re: Window - independent rendering contexts

    unit MainForm;
    // This code was originally formatted with tabs and spacing.

    interface
    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    OpenGL12, Oogle
    ;

    type
    TfrmMain = class(TForm)
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);

    public
    ogl: IOogle;
    rc: IOogleRenderDest;

    end;

    var
    frmMain: TfrmMain;

    implementation
    {$R *.DFM}

    procedure TfrmMain.FormPaint(Sender: TObject);
    begin
    rc.Start;
    try
    glBegin(GL_TRIANGLES);
    glColor3F(1, 1, 1);
    glVertex3F(0, 0, 0);
    glVertex3F(0.9, 0, 0);
    glVertex3F(1, 1, 0);
    glEnd;
    finally
    rc.Finish;
    end;
    rc.BitBlt(Canvas.Handle, 0, 0);
    end;

    procedure TfrmMain.FormCreate(Sender: TObject);
    begin
    OogleCreate(ogl);
    rc := TOogleRenderDestBitmap.Create(ClientWidth, ClientHeight);
    end;

    end.

  9. #9
    Intern Contributor
    Join Date
    Aug 2000
    Posts
    60

    Re: Window - independent rendering contexts

    unit Oogle;
    {$Z+,B-}

    // Object-oriented Open GL wrapper. Copyright 2000 Potts Development.

    interface
    uses
    Windows, OpenGL12, Classes
    ;

    type
    IOogleObject = interface;
    IOogleRenderDest = interface;

    OOGLE_DESTROYCALLBACK = procedure(Sender: IOogleObject; Arg: Pointer) of object;
    pOOGLE_DESTROYCALLBACK_DATA = ^OOGLE_DESTROYCALLBACK_DATA;
    OOGLE_DESTROYCALLBACK_DATA = record
    Callback: OOGLE_DESTROYCALLBACK;
    Arg: Pointer;
    end;

    pOOGLE_APPDATA = ^OOGLE_APPDATA;
    OOGLE_APPDATA = record
    ID: TGUID;
    Data: Pointer;
    end;

    IOogleObject = interface(IUnknown)
    ['{D8866DE5-B56D-4A83-892E-07C17B18F49D}']
    function GetAppData(const ID: TGUID): Pointer;
    procedure SetAppData(const ID: TGUID; Value: Pointer);
    procedure AddDestroyCallback(cb: OOGLE_DESTROYCALLBACK; Arg: Pointer);
    function GetName: WideString;
    procedure SetName(Value: WideString);
    end;

    IOogleRenderDest = interface(IOogleObject)
    ['{17479C51-020C-40FE-85DC-F4CC2394DF66}']
    procedure Start;
    procedure Finish;
    procedure BitBlt(DestDC: HDC; DestX, DestY: Integer);
    end;

    TOogleObject = class(TInterfacedObject, IOogleObject)
    protected
    FDestroyCallbacks: TList;
    FAppData: TList;
    FName: WideString;

    procedure ClearAppData;

    public
    constructor Create; virtual;
    destructor Destroy; override;

    function GetAppData(const ID: TGUID): Pointer;
    procedure SetAppData(const ID: TGUID; Value: Pointer);
    procedure AddDestroyCallback(cb: OOGLE_DESTROYCALLBACK; Arg: Pointer);
    function GetName: WideString;
    procedure SetName(Value: WideString);

    end;

    TOogleRenderDest = class(TOogleObject, IOogleRenderDest)
    protected
    FRenderContext: HGLRC;
    FStartCount: DWORD;

    public
    constructor Create; override;
    destructor Destroy; override;

    procedure Start; virtual;
    procedure Finish; virtual;
    procedure BitBlt(DestDC: HDC; DestX, DestY: Integer); virtual; abstract;

    end;

    TOogleRenderDestBitmap = class(TOogleRenderDest)
    protected
    FRenderContext: HGLRC;
    FBitmapDC: HDC;

    //FMemoryDC: HDC;
    FBitDepth: Integer;
    FBitmap: HBITMAP;

    FBitmapInfo: BITMAP;

    FPixelFormat: PIXELFORMATDESCRIPTOR;
    FPixelFormatIndex: Integer;

    public
    constructor Create(w, h: Integer); reintroduce;
    destructor Destroy; override;
    procedure Start; override;
    procedure Finish; override;
    procedure BitBlt(DestDC: HDC; DestX, DestY: Integer); override;

    end;

    implementation
    uses
    SysUtils, Messages
    ;

    constructor TOogleObject.Create;
    begin
    FAppData := TList.Create;
    FDestroyCallbacks := TList.Create;
    end;

    destructor TOogleObject.Destroy;
    var
    i: Integer;
    dc: pOOGLE_DESTROYCALLBACK_DATA;
    begin
    try
    try
    for i := 0 to FDestroyCallbacks.Count - 1 do begin
    try
    dc := FDestroyCallbacks[i];
    dc.Callback(Self, dc.Arg);
    Dispose(dc);
    except
    // Ignore
    end;
    end;
    finally
    FDestroyCallbacks.Free;
    end;
    try
    ClearAppData;
    finally
    FAppData.Free;
    end;
    finally
    inherited;
    end;
    end;

    procedure TOogleObject.ClearAppData;
    var
    i: Integer;
    begin
    try
    for i := 0 to FAppData.Count - 1 do begin
    Dispose(FAppData[i]);
    end;
    finally
    FAppData.Clear;
    end;
    end;

    function TOogleObject.GetAppData(const ID: TGUID): Pointer;
    var
    i: Integer;
    ad: pOOGLE_APPDATA;
    begin
    for i := 0 to FAppData.Count - 1 do begin
    ad := FAppData[i];
    if PDCompareGUIDs(ID, ad^.ID) then begin
    Result := ad^.Data;
    Exit;
    end;
    end;
    Result := nil;
    end;

    procedure TOogleObject.SetAppData(const ID: TGUID; Value: Pointer);
    var
    i: Integer;
    ad: pOOGLE_APPDATA;
    begin
    for i := 0 to FAppData.Count - 1 do begin
    ad := FAppData[i];
    if PDCompareGUIDs(ID, ad^.ID) then begin
    ad^.Data := Value;
    Exit;
    end;
    end;
    New(ad);
    try
    ad^.ID := ID;
    ad^.Data := Value;
    FAppData.Add(ad);
    except
    Dispose(ad);
    raise;
    end;
    end;

    procedure TOogleObject.AddDestroyCallback(cb: OOGLE_DESTROYCALLBACK; Arg: Pointer);
    var
    dc: pOOGLE_DESTROYCALLBACK_DATA;
    begin
    New(dc);
    try
    dc^.Callback := cb;
    dc^.Arg := Arg;
    FDestroyCallbacks.Add(dc);
    except
    Dispose(dc);
    raise;
    end;
    end;

    function TOogleObject.GetName: WideString;
    begin
    Result := FName;
    end;

    procedure TOogleObject.SetName(Value: WideString);
    begin
    FName := Value;
    end;

    constructor TOogleRenderDest.Create;
    begin
    inherited;
    // Do nothing for now
    end;

    destructor TOogleRenderDest.Destroy;
    begin
    try
    wglDeleteContext(FRenderContext); // Automatically makes context noncurrent before deleting it
    finally
    inherited;
    end;
    end;

    procedure TOogleRenderDest.Start;
    begin
    Inc(FStartCount);
    end;

    procedure TOogleRenderDest.Finish;
    begin
    if FStartCount > 0 then Dec(FStartCount);
    end;

    constructor TOogleRenderDestBitmap.Create(w, h: Integer);
    var
    FMemoryDC: HDC;
    begin
    inherited Create;

    FMemoryDC := CreateCompatibleDC(0);
    FBitDepth := GetDeviceCaps(FMemoryDC, BITSPIXEL);
    FBitmap := CreateBitmap(w, h, 1, FBitDepth, nil);
    SelectObject(FMemoryDC, FBitmap);
    FBitmapDC := FMemoryDC;

    GetObject(FBitmap, SizeOf(BITMAP), @FBitmapInfo);

    FPixelFormat.nSize := SizeOf(FPixelFormat);
    FPixelFormat.nVersion := 1;
    FPixelFormat.dwFlags := PFD_DRAW_TO_BITMAP or PFD_SUPPORT_OPENGL or PFD_TYPE_RGBA;
    FPixelFormat.iPixelType := PFD_TYPE_RGBA;
    FPixelFormat.cColorBits := FBitmapInfo.bmBitsPixel;
    FPixelFormat.cDepthBits := 32; // 32-bit depth buffer
    FPixelFormat.iLayerType := PFD_MAIN_PLANE;

    FPixelFormatIndex := ChoosePixelFormat(FBitmapDC, @FPixelFormat);
    if not SetPixelFormat(FBitmapDC, FPixelFormatIndex, @FPixelFormat) then raise Exception.Create('Unable to set pixel format');

    FRenderContext := wglCreateContext(FBitmapDC);
    if FRenderContext = 0 then raise Exception.Create('Unable to create render context');
    end;

    destructor TOogleRenderDestBitmap.Destroy;
    begin
    try
    wglDeleteContext(FRenderContext);
    DeleteObject(FBitmap);
    DeleteDC(FBitmapDC);
    finally
    inherited;
    end;
    end;

    procedure TOogleRenderDestBitmap.Start;
    begin
    inherited;
    if FStartCount = 1 then wglMakeCurrent(FBitmapDC, FRenderContext);
    end;

    procedure TOogleRenderDestBitmap.Finish;
    begin
    if FStartCount = 1 then wglMakeCurrent(FBitmapDC, 0);
    inherited;
    end;

    procedure TOogleRenderDestBitmap.BitBlt(DestDC: HDC; DestX, DestY: Integer);
    begin
    if not Windows.BitBlt(DestDC, DestX, DestY, FBitmapInfo.bmWidth, FBitmapInfo.bmHeight, FBitmapDC, 0, 0, SRCCOPY) then raise Exception.Create('Windows.BitBlt() failed');
    end;

    end.


    [This message has been edited by skippyj777 (edited 08-14-2000).]

  10. #10
    Junior Member Regular Contributor
    Join Date
    Jun 2000
    Location
    Bucharest, Romania
    Posts
    113

    Re: Window - independent rendering contexts

    I'll try to look over your code. Thanks anyway.

    NewROmancer

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •