Page 2 of 2 FirstFirst 12
Results 11 to 19 of 19

Thread: OpenGL: Silly texturing problem

  1. #11

    OpenGL: Silly texturing problem

    This is just a stab in the dark, and will probably have no effect whatsoever, but why not try removing the () from the parameterless function calls, like glEnd, glGetError, etc.
    [size=10px]"In science one tries to tell people, in such a way as to be understood by everyone, something that no one ever knew before. But in poetry, it's the exact opposite." -- Paul Dirac[/size]

  2. #12

    OpenGL: Silly texturing problem

    Nope, that's not it. Parentheses or not, still the same error...
    If you develop an idiot proof system, the nature develops better idiots.

  3. #13

    OpenGL: Silly texturing problem

    Quote Originally Posted by vgo
    Here's the simplified rendering code that still produces the error.
    ...
    Hmm. That's really strange. Your code is perfectly fine, shouldn't cause any OpenGL errors. I even created a simple program, copy&pasted your code into Init and Draw, and (after changing FCamera references to compile) everything runs OK. No OpenGL error.

    (Note that I used FPC 2.0.2 on Linux with NVidia card, so my environment was quite different than yours. But your sample OpenGL code should work the same.)

    Moreover, you say that rendering works good. Which is another proof that things between glBegin...glEnd are correct. If something would be incorrect between glBegin...glEnd, rendering results would be incorrect also.

    So, basically, your code is good. The error must be somewhere else. Inside dglOpenGL bindings ? Something specific to Borland Arch 2006 ? Something specific to Radeon ? All these causes are very very very unlikely.

    Are you sure that you don't have another thread running in your program that does some OpenGL calls ?

    Otherwise, I'm afraid you'll have to send/show somewhere the complete program code to reproduce the bug. I don't have Borland Arch 2006 or Radeon, but I can try to test with Delphi 7 on NVidia. Maybe someone else will have Borland Arch 2006 and Radeon. This will allow us to test exactly your program, and maybe this way we'll discover something.

  4. #14

    OpenGL: Silly texturing problem

    I tried to duplicate the error with a simple pure Windows API program, can't do it. Everything works like a charm...

    Maybe it has something to do with the custom OpenGL panel that I'm using?

    Here's code for the OpenGL panel component:
    [pascal]
    unit glWindow;

    interface

    uses
    Windows, Classes, Graphics, Forms, dglOpenGL, extctrls;

    type
    // Types for OpenGL window settings
    TWindowOption = (wfDrawToWindow, wfDrawToBitmap, wfSupportGDI,
    wfSupportOpenGL, wfGenericAccelerated, wfDoubleBuffer);
    TWindowOptions = set of TWindowOption;

    TDepthBits = (c16bits, c32bits);

    TResizeEvent = procedure(Sender : TObject) of object;
    TDrawEvent = procedure(Sender : TObject) of object;
    TInitEvent = procedure(Sender : TObject) of object;

    TglWindow = class(TCustomPanel)
    private
    h_RC : HGLRC; // Rendering context
    Init : Boolean; // Whether panel has been initalized yet
    FColorDepth : Integer; // Color depth
    FDepthBits : Integer; // Depth buffer depth
    FDepthEnabled : Boolean; // Enables the depth buffer
    FStencBits : Integer; // Stencil buffer depth
    FStencEnabled : Boolean; // Enables the stencil buffer
    FAccumBits : Integer; // Accumulation buffer depth
    FAccumBufferEnabled : Boolean; // Enables the accumulation buffer
    FWindowFlags : TWindowOptions; // OpenGL window properties
    FOnResize : TResizeEvent; // OpenGL resize function
    FOnDraw : TDrawEvent; // OpenGL draw function
    FOnInit : TInitEvent; // OpenGL initialization function
    OldClose : TNotifyEvent; // Saves old close event from form
    flags : Word; // OpenGL window flags
    rot : Integer; // rotation amount for cube in default
    // drawing code

    procedure Close(Sender: TObject);
    function GetColorDepth() : TDepthBits;
    procedure SetColorDepth(depth : TDepthBits);
    function GetDepthBufferDepth() : TDepthBits;
    procedure SetDepthBufferDepth(depth : TDepthBits);
    function GetStencBufferDepth() : TDepthBits;
    procedure SetStencBufferDepth(depth : TDepthBits);
    function GetAccumBufferDepth() : TDepthBits;
    procedure SetAccumBufferDepth(depth : TDepthBits);
    procedure defResize(Sender : TOBject);
    procedure defDraw(Sender : TObject);
    procedure defInit(Sender : TObject);
    procedure SetWindowFlags();
    public
    h_DC : HDC; // Device context
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Loaded; override;
    procedure Paint; override;
    procedure ReDraw();
    procedure Swap; // Swaps the buffer's if display is double buffered
    procedure Resize; override;
    published
    property Align;
    property Visible;
    property OnClick;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnDblClick;
    property ColorDepth : TDepthBits read GetColorDepth write SetColorDepth;
    property DepthBits : TDepthBits read GetDepthBufferDepth write SetDepthBufferDepth;
    property DepthBufferEnabled : Boolean read FDepthEnabled write FDepthEnabled;
    property StencBits : TDepthBits read GetStencBufferDepth write SetStencBufferDepth;
    property StencBufferEnabled : Boolean read FStencEnabled write FStencEnabled;
    property AccumBits : TDepthBits read GetAccumBufferDepth write SetAccumBufferDepth;
    property AccumBufferEnabled : Boolean read FAccumBufferEnabled write FAccumBufferEnabled;
    property WindowFlags : TWindowOptions read FWindowFlags write FWindowFlags;
    property OnResize : TResizeEvent read FOnResize write FOnResize;
    property OnDraw : TDrawEvent read FOnDraw write FOnDraw;
    property OnInit : TInitEvent read FOnInit write FOnInit;
    end;

    procedure Register;

    implementation

    procedure Register;
    begin
    // Register glWindow component so its displayed in the Tool Palette
    RegisterComponents('OpenGL', [TGLWindow]);
    end;

    { TGLWindow }

    // Name : Create
    // Purpose : Creates the glWindow component
    // Parameters : Owner of the component
    constructor TGLWindow.Create(AOwner: TComponent);
    var
    frm : TForm;
    begin
    inherited Create(AOwner);
    InitOpenGL;
    // Set background color and pen and brush colors
    Color := clBlack;
    Canvas.Brush.Color := clBlack;
    Canvas.Pen.Color := clBlack;

    if csDesigning in ComponentState then begin
    // Set default width and height
    Width := 65;
    Height := 65;

    // Set up initial rendering settings
    {$IFDEF FPC}
    {$ELSE}
    FDoubleBuffered := True;
    {$ENDIF}
    FColorDepth := 16;
    FDepthBits := 16;
    FDepthEnabled := True;
    FStencBits := 16;
    FStencEnabled := False;
    FAccumBits := 16;
    FAccumBufferEnabled := False;
    FWindowFlags := [wfDrawToWindow, wfSupportOpenGL, wfDoubleBuffer];
    end else begin

    // component hasn't been initialized yet (no rendering context, etc...)
    Init := False;

    // Get a handle on the form that the component is on
    frm := TForm(AOwner);

    // Set this component to be destroyed when the form is destroyed
    if Assigned(frm.OnDestroy) then
    OldClose := frm.OnDestroy;
    {$IFDEF FPC}
    frm.OnDestroy := @Close;
    {$ELSE}
    frm.OnDestroy := Close;
    {$ENDIF}


    // Set default OpenGL routines, if no draw/resize/or init routines are
    // specified then the default ones are used, the default drawing routine
    // simply draws a rotating cube
    {$IFDEF FPC}
    OnResize := @defResize;
    OnDraw := @defDraw;
    OnInit := @defInit;
    {$ELSE}
    OnResize := defResize;
    OnDraw := defDraw;
    OnInit := defInit;
    {$ENDIF}

    end;
    end;

    // Name : defInit
    // Purpose : default OpenGL initialization
    procedure TGLWindow.defInit(Sender: TObject);
    begin
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    end;

    // Name : defResize
    // Purpose : Default resize routine
    procedure TGLWindow.defResize(Sender: TOBject);
    var
    fAspect : GLfloat;
    begin
    // Make sure that we don't get a divide by zero exception
    if (Height = 0) then
    Height := 1;

    // Set the viewport for the OpenGL window
    glViewport(0, 0, Width, Height);

    // Calculate the aspect ratio of the window
    fAspect := (Width / Height);

    // Go to the projection matrix, this gets modified by the perspective
    // calulations
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // Do the perspective calculations
    gluPerspective(45.0, fAspect, 1.0, 1000.0);

    // Return to the modelview matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    end;

    // Name : defDraw
    // Purpose : Default drawing routine, draws spinning cube
    procedure TGLWindow.defDraw(Sender: TObject);
    begin
    // Clear the color and depth buffers
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

    // Replaces the current matrix with the identity matrix
    glLoadIdentity();

    // Go to the model view matrix mode
    glMatrixMode(GL_MODELVIEW);

    // Sample drawing code, draw's a rotating cube onscreen
    glTranslatef(0.0, 0.0, -5.0);
    glRotatef(rot, 1.0, 1.0, 0.0); // Rotates around the x and y axis

    glBegin(GL_QUADS);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f( 1.0, 1.0,-1.0);
    glVertex3f(-1.0, 1.0,-1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glVertex3f( 1.0, 1.0, 1.0);

    glColor3f(1.0, 0.5, 0.0);
    glVertex3f( 1.0,-1.0, 1.0);
    glVertex3f(-1.0,-1.0, 1.0);
    glVertex3f(-1.0,-1.0,-1.0);
    glVertex3f( 1.0,-1.0,-1.0);

    glColor3f(1.0, 0.0, 0.0);
    glVertex3f( 1.0, 1.0, 1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glVertex3f(-1.0,-1.0, 1.0);
    glVertex3f( 1.0,-1.0, 1.0);

    glColor3f(1.0, 1.0, 0.0);
    glVertex3f( 1.0,-1.0,-1.0);
    glVertex3f(-1.0,-1.0,-1.0);
    glVertex3f(-1.0, 1.0,-1.0);
    glVertex3f( 1.0, 1.0,-1.0);

    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glVertex3f(-1.0, 1.0,-1.0);
    glVertex3f(-1.0,-1.0,-1.0);
    glVertex3f(-1.0,-1.0, 1.0);

    glColor3f(1.0, 0.0, 1.0);
    glVertex3f( 1.0, 1.0,-1.0);
    glVertex3f( 1.0, 1.0, 1.0);
    glVertex3f( 1.0,-1.0, 1.0);
    glVertex3f( 1.0,-1.0,-1.0);
    glEnd();

    Inc(rot); // Increment the current cube rotation amount
    end;

    destructor TGLWindow.Destroy;
    begin
    inherited Destroy;
    end;

    // Name : GetAccumBufferDepth
    // Purpose : Gets the current accumulation buffer depth
    // Returns : Current accumulation buffer depth
    function TGLWindow.GetAccumBufferDepth() : TDepthBits;
    begin
    case FAccumBits of
    16 : Result := c16bits;
    32 : Result := c32bits;
    else Result := c16bits;
    end;
    end;

    // Name : GetColorDepth
    // Purpose : Gets the current OpenGL color depth
    // Returns : Current OpenGL color depth
    function TGLWindow.GetColorDepth() : TDepthBits;
    begin
    case FColorDepth of
    16 : Result := c16bits;
    32 : Result := c32bits;
    else Result := c16bits;
    end;
    end;

    // Name : GetDepthBufferDepth
    // Purpose : Gets the current depth of the depth buffer
    // Returns : The current depth of the depth buffer
    function TGLWindow.GetDepthBufferDepth() : TDepthBits;
    begin
    case FDepthBits of
    16 : Result := c16bits;
    32 : Result := c32bits;
    else Result := c16bits;
    end;
    end;

    // Name : GetStencBufferDepth
    // Purpose : Gets the stencil buffer depth
    // Returns : Current stencil buffer depth
    function TGLWindow.GetStencBufferDepth() : TDepthBits;
    begin
    case FStencBits of
    16 : Result := c16bits;
    32 : Result := c32bits;
    else Result := c16bits;
    end;
    end;

    // Name : Paint
    // Purpose : Paints the OpenGL component black when its first put on the form
    procedure TGLWindow.Paint;
    begin
    if csDesigning in ComponentState then
    Canvas.Rectangle(0, 0, Width, Height)
    else
    ReDraw;
    end;

    // Name : SetAccumBufferDepth
    // Purpose : Sets the accumulation buffer depth
    // Parameters :
    // depth - new depth for accumulation buffer
    procedure TGLWindow.SetAccumBufferDepth(depth : TDepthBits);
    begin
    case depth of
    c16bits : FAccumBits := 16;
    c32bits : FAccumBits := 32;
    end;
    end;

    // Name : SetColorDepth
    // Purpose : Sets the window color depth
    // Parameters :
    // depth - new color depth for the window
    procedure TGLWindow.SetColorDepth(depth : TDepthBits);
    begin
    case depth of
    c16bits : FColorDepth := 16;
    c32bits : FColorDepth := 32;
    end;
    end;

    // Name : SetDepthBufferDepth
    // Purpose : Sets the depth of the depth buffer
    // Parameters :
    // depth - new depth for the depth buffer
    procedure TGLWindow.SetDepthBufferDepth(depth : TDepthBits);
    begin
    case depth of
    c16bits : FDepthBits := 16;
    c32bits : FDepthBits := 32;
    end;
    end;

    // Name : SetStencBufferDepth
    // Purpose : Sets the stencil buffer depth
    // Parameters :
    // depth - New depth for the stencil buffer
    procedure TGLWindow.SetStencBufferDepth(depth : TDepthBits);
    begin
    case depth of
    c16bits : FStencBits := 16;
    c32bits : FStencBits := 32;
    end;
    end;

    // Name : Resize
    // Purpose : Called when the width or height of the component changes, in
    // turn it calls the resize procedure assigned to the component
    procedure TGLWindow.Resize;
    begin
    // Make this components rendering context current
    wglMakeCurrent(h_DC, h_RC);

    // Call assigned resize event if component has been initialized
    if (Assigned(OnResize) and (Init))
    then OnResize(self);
    end;

    // Name : ReDraw
    // Purpose : Called when owner want's opengl window to be updated, in turn
    // it calls the draw function assigned to the component
    procedure TGLWindow.ReDraw;
    begin
    // Make this components rendering context current
    wglMakeCurrent(h_DC, h_RC);

    // Call assigned drawing routine, updating the OpenGL scene
    if Assigned(OnDraw) then OnDraw(self);

    // Swap the buffers if needed
    Swap;
    end;

    // Name : Swap
    // Purpose : Swaps the OpenGL buffers if display is double buffered
    procedure TGLWindow.Swap;
    begin
    if wfDoubleBuffer in FWindowFlags then SwapBuffers(h_DC);
    end;

    // Name : Loaded
    // Purpose : Sets the pixel format and attaches a rendering context to the
    // components device context
    procedure TGLWindow.Loaded;
    var
    PixelFormat : Integer;
    pfd : PIXELFORMATDESCRIPTOR;
    begin
    inherited;

    // Update the window flags
    SetWindowFlags();

    // Set all fields in the pixelformatdescriptor to zero
    ZeroMemory(@pfd, SizeOf(pfd));

    // Initialize only the fields we need
    pfd.nSize := SizeOf(PIXELFORMATDESCRIPTOR); // Size Of This Pixel Format Descriptor
    pfd.nVersion := 1; // The version of this data structure
    pfd.dwFlags := flags; // Set the window flags
    // (set in property editor)
    pfd.iPixelType := PFD_TYPE_RGBA; // Set OpenGL pixel data type
    pfd.cColorBits := FColorDepth; // OpenGL color depth
    pfd.cDepthBits := FDepthBits; // Specifies the depth of the depth buffer

    // If component's settings specifies that the accumulation buffer is enabled
    // then set its depth (which enables it)
    if FAccumBufferEnabled then
    pfd.cAccumBits := FAccumBits;

    // If component's settings specifies that the stencil buffer is enabled
    // then set its depth (which enables it)
    if FStencEnabled then
    pfd.cStencilBits := FStencBits;

    h_DC := GetDC(Handle);

    // Attempts to find the pixel format supported by a device context that is the
    // best match to a given pixel format specification.
    PixelFormat := ChoosePixelFormat(h_DC, @pfd);
    if (PixelFormat = 0) then begin
    Close(self);
    MessageBox(0, 'Unable to find a suitable pixel format', 'Error', MB_OK or MB_ICONERROR);
    Exit;
    end;

    // Sets the specified device context's pixel format to the format specified by
    // the PixelFormat.
    if (not SetPixelFormat(h_DC, PixelFormat, @pfd)) then begin
    Close(self);
    MessageBox(0, 'Unable to set the pixel format', 'Error', MB_OK or MB_ICONERROR);
    Exit;
    end;

    // Create a OpenGL rendering context
    h_RC := wglCreateContext(h_DC);
    if (h_RC = 0) then begin
    Close(self);
    MessageBox(0, 'Unable to create an OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR);
    Exit;
    end;

    // Makes the specified OpenGL rendering context the calling thread's current
    // rendering context
    if (not wglMakeCurrent(h_DC, h_RC)) then begin
    Close(self);
    MessageBox(0, 'Unable to activate OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR);
    Exit;
    end;

    // Component has a rendering context
    Init := True;

    // Call assinged initialization routine and resize routine
    if Assigned(OnInit) then OnInit(self);
    if Assigned(OnResize) then OnResize(self);

    // Updates the OpenGL scene
    ReDraw;
    end;

    // Name : Close
    // Purpose : Removes and deletes the components rendering context
    procedure TglWindow.Close(Sender : TObject);
    begin
    // Makes current rendering context not current, and releases the device
    // context that is used by the rendering context.
    wglMakeCurrent(h_DC, 0);

    // Attempts to delete the rendering context
    wglDeleteContext(h_RC);

    // Release the device context (return the memory)
    ReleaseDC(Handle, h_DC);

    Init := False;

    // If old close event was saved, call it
    if Assigned(OldClose) then OldClose(Sender);
    end;


    // Name : SetWindowFlags
    // Purpose : Sets the OpenGL window flags depending on the values specified
    // in the property editor for the component
    procedure TglWindow.SetWindowFlags;
    begin
    if wfDrawToWindow in FWindowFlags then flags := flags or PFD_DRAW_TO_WINDOW;
    if wfDrawToBitmap in FWindowFlags then flags := flags or PFD_DRAW_TO_BITMAP;
    if wfSupportOpenGL in FWindowFlags then flags := flags or PFD_SUPPORT_OPENGL;
    if wfGenericAccelerated in FWindowFlags then flags := flags or PFD_GENERIC_ACCELERATED;

    // A window can't have both double buffering and gdi support in Microsoft's
    // OpenGL implementation. So support double buffering if requested and only
    // if it isn't do we support GDI operations
    if wfDoubleBuffer in FWindowFlags then
    flags := flags or PFD_DOUBLEBUFFER
    else if wfSupportGDI in FWindowFlags then
    flags := flags or PFD_SUPPORT_GDI;

    end;

    end.
    [/pascal]
    If you develop an idiot proof system, the nature develops better idiots.

  5. #15

    OpenGL: Silly texturing problem

    Ok, this gets more bizarre every day...

    I made a simple test app with Lazarus and guess what? YES! The same ****ing error message!!! This is getting ridiculous... It's different from Delphi tho, NOTHING seem to get rendered...

    I reinstalled the display drivers and left out the stupid Catalyst control center too, but it doesn't make any difference...

    EDIT: Now it seems to work. Haven't got it to render anything yet, but at least there's no errors.
    If you develop an idiot proof system, the nature develops better idiots.

  6. #16

    OpenGL: Silly texturing problem

    Quote Originally Posted by vgo
    Quote Originally Posted by Clootie
    Try GLexpert
    What's that?
    It's developer tool made by NVIDIA for catching "wrong" usage of OpenGL API (something like debug layer of DirectX).
    Presentation: NVIDIA developer tools on GDC-2006.

    Hm... Seems it's still unavailable for download from NVIDIA site - it's only on these DVD's with SDK.
    There are only 10 types of people in this world; those who understand binary and those who don't.

  7. #17

    OpenGL: Silly texturing problem

    Quote Originally Posted by vgo
    Here's code for the OpenGL panel component:
    ...
    OK, I was finally able to reproduce your problem.

    1. I took glWindow unit your submitted
    2. I downloaded dglOpenGL
    3. I placed your glBegin(GL_QUADS); ... glEnd(); glCheckForError(); snippet in OnDraw

    ...and now I get GL_INVALID_OPERATION. This is with Delphi 7, on NVidia, Windows 2000 Prof.

    The problem seems to be inside dglOpenGL unit related to the STUB_xxx tricks they are doing. When I avoid relaying on STUB_xxx tricks, things suddenly work OK.

    Two solutions that work for me:
    1. Call ReadOpenGLCore right after InitOpenGL inside TGLPanel.Create
    2. Or use other Delphi header than dglOpenGL header. E.g. when using standard Delphi OpenGL unit with the same code, problem disappears.

  8. #18

    OpenGL: Silly texturing problem

    I tracked it down to dglOpenGL too, but didn't catch the specific reason.

    I had the same problem on my Lazarus test program, but as soon as I started using the TOpenGLControl and the supplied GL/GLU units I got rid off that error.

    Good thing is that this episode really forced me to look more into Lazarus and as a result of that my game engine is now cross-platform.
    It's far from a full blown commercial game engine, but that's not the point, I'm doing this for the fun of it.

    Which sort of brings up another OpenGL question... Are the display lists obsolete, is there any performance gain from using them? Back in the day they were very useful along with the vertex arrays, now there seems to be vertex buffer objects too...
    If you develop an idiot proof system, the nature develops better idiots.

  9. #19

    OpenGL: Silly texturing problem

    I don't think display lists are obsolete. They still give the driver the chance to cache and optimize data. Admittedly they are not a quick are vertex arrays or vertex buffers, but they are very flexable and easy to use.
    <A HREF="http://www.myhpf.co.uk/banner.asp?friend=139328">
    <br /><IMG SRC="http://www.myhpf.co.uk/banners/60x468.gif" BORDER="0">
    <br /></A>

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

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