POV-Ray : Newsgroups : povray.off-topic : Tell me it isn't so! Server Time
11 Oct 2024 07:15:09 EDT (-0400)
  Tell me it isn't so! (Message 301 to 310 of 473)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Jim Henderson
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 00:35:06
Message: <4a6e7ffa$1@news.povray.org>
On Mon, 27 Jul 2009 20:51:25 -0500, David H. Burns wrote:

> Jim Henderson wrote:
> 
>>> I ought to apologize for my typos and irregular lines. The keyboard on
>>> this Timex Sinclair
>>> is rather small and my tail keeps getting in the way.
>> 
>> Ah, the ZX-81?  Had to use a rubber band to hold the 16 K expansion
>> pack on mine. ;-)
>> 
>> Jim
> 
> You go farther back than me. I wasn't lucky enough to get one of those.
> The Timex-Sinclair
> is a latter version.

*Now* I feel old. ;-)

The PET was the first computer I used, back in 1981 or so.  Unless you 
count the teletype terminal my dad would bring home from work 
occasionally and hook up to the phone with an acoustic coupler.

Jim


Post a reply to this message

From: clipka
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 00:50:04
Message: <web.4a6e826aac52dfd4813466d60@news.povray.org>
"David H. Burns" <dhb### [at] cherokeetelnet> wrote:
> >   What makes it ironic is that a large part of C/C++ programs out there are
> > heavily graphical (most prominently the computer games), and seems like
> > everybody just somehow manages to get the graphics done, but when you ask
> > for a simple way of getting graphics, they will usually shrug and say that
> > it's a bit complicated... (Because it *is* a bit complicated.)
>
> If it is (and I can't believe that it's all that complicated), why is it??

Legacy.

While nowadays computers would most likely have the memory to provide a frame
buffer for each application to write to, and display that as necessary - with
plenty of support from the graphics card - that wasn't the case when Windows
was initially designed. (It even wasn't the case when Windows 3.1 came out.)

Back then, in order to be able to display multiple overlapping application
windows at once, the solution was that whenever the position of a window would
change, all windows previously hidden below it but now visible would have to be
(partially) re-drawn by their respective applications.

This made it impossible to apply the classic straightforward approach of drawing
the window contents when the application saw fit. Applications to still use this
approach would now have to allocate a buffer to draw in, and upon request of the
operating system blit the appropriate portions of the buffer to the screen.

Things were made even more complicated by the application no longer having
control over which video mode to choose: That would be fixed for all
applications. And it could be anything, from 2-color 720x348 over 16-color
640x480 to, say, 256-color 1024x768 (which was an awful lot back then).
Limited, by the way, to a standard palette.

How was such data to be handled when an application would use its own buffer and
just copy portions of it? Memory and computing power were still valuable, and
all those potential candidates for a standard format were rather arbitrary
anyway (with non-palette-based 15/16-bit High- and 24-bit TrueColor modes
nowhere to be seen yet), so from that point of view it seems logical to me to
go for what would be known as "device-dependent bitmaps".

Some of those modes a user might have chosen posed another problem, in that they
were highly anisotropic (e.g. that 720x348 Hercules format intended to be
displayed on a 4:3 monitor), so it was also logical to compute the dimensions
and positions of applications' dialog elements not based on pixels, but some
other - necessarily somewhat arbitrary - distance unit.

I'm not sure if I get all these details right, but stuff along these lines added
up to make the Windows graphics interface somewhat complicated to use, and the
bane of backward compatibility has kept these complications alive to this day.


> Maybe, but why are the graphics for Windows itself so complicated? It's a
> single operating system running mainly on similar hardware.

Oh, if only it had always been that simple!

Yes, nowadays everyone is using 24-bit RGB graphics, and typically at 1:1 pixel
aspect ratio, but that's something PC-users could only dream of in the early
days of Windows.


> And again Pov-Ray does
> it for images at lease. How does it do it? So it's complicated, even
> *hard*, surely
> someone knows how it is done and can tell me, or tell me where to find
> out.

Let's see if we can shed *some* light on this, at least to the point where you
can start asking "stupid" questions about it; i'm not really familiar with
using the Windows API though, and typically relying on Microsoft frameworks
(MFC or the .NOT framework [duh, what a typo! I guess it deserves to be left in
here just for laughs :P]), but maybe... ah, we'll see.

I'm taking the POV-Ray 3.7 (beta 33) source for reference, because I have that
right at my fingertips; the file to look at there is "pvdisplay.cpp" in the
"windows" subdirectory, which defines a WinLegacyDisplay object (well, an
object class, to be precisely).

  WinLegacyDisplay::WinLegacyDisplay(...)
  WinLegacyDisplay::~WinLegacyDisplay()

These are a constructor and destructor, respectively, which don't do anything
exciting. Consider it some of the C++ overhead for object classes.

  bool WinLegacyDisplay::TakeOver(...)

This is just there to handle a special case where a window can be re-used from
one render to the next, so I leave that to you for later study.

  bool WinLegacyDisplay::CreateRenderWindow (void)

This is meat; I'll quote some of it:

  rect.right = GetWidth() ;
  rect.bottom = GetHeight() ;
  flags = WS_OVERLAPPEDWINDOW ;
  AdjustWindowRectEx (&rect, flags, false, 0) ;

This picks the desired "net" size (insert anything you like for GetWidth() and
GetHeight() respectively), chooses some window style (whether it has a title
bar, which title bar buttons can be seen, how thick the border is, etc.) and
has Windows calculate the "gross" size that would be required for such a
window.

What follows are computations to make sure the window is not larger than the
total desktop, and to decide where to place the window.

The m_Bitmap stuff sets up the rules for the drawing space to be used; you'll
want to pretend m_Depth8Bit=false. m_Bitmap.biBitCount = 24 will give you the
3x8 bits RGB you want. The m_Bitmap.m_BytesPerLine formula is designed to round
up the number of bytes required per line to a multiple of 4; I'm not sure
whether Windows actually needs that, so just keep it.

m_BitmapSurface is then set to point to newly allocated memory (in pure C, you'd
use malloc() here), and will serve as the actual drawing space, with bytes laid
out as RGBRGBRGB... per line; don't forget that the lines are padded to
multiples of 4.

Clear() just fills the drawing space with that grey-and-white pattern each
render starts with.

CreateWindowEx (...) is one of the uglier beasts. This actually requests Windows
to create a new window with the following properties:

- 0: matches parameter #4 in AdjustWindowRectEx
- PovLegacyRenderWinClass: a value allowing Windows to identify where to send
"events" pertaining to the window (e.g. user interaction, or requests to redraw
itself); we'll have to come back to this later.
- "POV-Ray"; the title text; choose anything you like.
- flags | renderwin_flags: matches parameter #2 in AdjustWindowRectEx, plus
whether the window is initially minimized, maximized or neither.
- renderwin_left, renderwin_top: position of the window
- width, height: "gross" size of the window
- RenderwinIsChild ? main_window : NULL: If you just want to pop up a window
from a command line tool, set this to NULL.
- NULL: this is for defining a menu bar; set this to NULL for simplicity.
- hInstance: You can leave this to NULL, at the cost of Win95/98/ME
compatibility.
- NULL: Looks like this last parameter is not needed either.

The result value will be NULL in case of failure, or a code uniquely identifying
"your" window.

SetWindowLongPtr (m_Handle, 0, LONG_PTR (this)); stores a reference to the
WinLegacyDisplay object; if you're not using C++, skip this one.

What follows looks like code to insert scroll bars if necessary, in some cases
give focus to the new window, and to request a non-standard cursor to be used
when over the window (the crosshairs); I guess you don't need these for
starters.

InvalidateRect (m_Handle, NULL, false) ; informs Windows that the whole window
needs to be redrawn (we haven't displayed the contents of our drawing area in
the window yet); Windows will subsequently request us to actually redraw the
window (or portions thereof) as soon as it gets visible.

  void WinLegacyDisplay::Initialise()

This seems to be some POV-Ray internal thing, and I guess you don't need any of
this.

  void WinLegacyDisplay::Close()

This rolls back all the stuff from WinLegacyDisplay::CreateRenderWindow.

SendMessage (main_window, WM_COMMAND, CM_RENDERDESTROY, (LPARAM) m_Handle); is
some POV-Ray internal stuff again, ultimately leading to a call to
"DestroyWindow ((HWND) lParam)"; you want to substitute "DestroyWindow
(m_Handle)" here, which will discard the window.

m_BitmapSurface memory is released (in pure C you'd use free() instead of
delete)

Not sure what the m_ErrorBitmap is about. I guess some "can't display this, it's
too large" fallback image.

Never mind the PVEnableMenuItem stuff.

  void WinLegacyDisplay::Show()
  void WinLegacyDisplay::Hide()

These demonstrate how to show or hide a window without really killing it. The
meat is in the "ShowWindow (m_Handle, ...) ;", never mind the rest.

  inline void WinLegacyDisplay::SetPixel (...)

This is meat that demonstrates how to actually use the drawing area. Note
however that it doesn't actually draw to the window, it just draws to the
buffer. It seems that for performance reason Windows is not informed that part
of the image is now in need of being redrawn; that's done somewhere else.

  void WinLegacyDisplay::DrawPixel(...)
  void WinLegacyDisplay::DrawRectangleFrame(...)
  void WinLegacyDisplay::DrawFilledRectangle(...)
  void WinLegacyDisplay::DrawPixelBlock(...)

These are some helper functions; not any particular meat in there (there is some
in DrawPixelBlock(), but that's for some specialty here).

  void WinLegacyDisplay::InvalidatePixelBlock(...)

This code is called whenever a significant portion of our drawing area has been
updated, and tells Windows via InvalidateRect (m_Handle, &rect, false) ; that
the particular region needs re-drawing; the code before that deals with
converting picture coordinates to the coordinate system Windows expects here -
which may be a bit complicated if the window is maximized (IsZoomed
(m_Handle)), but that's application choice; for starters you may want to always
display your drawings at 100% size.

  void WinLegacyDisplay::Clear()

This just draws the already mentioned grey-white checkerboard pattern to our
drawing area.

  void WinLegacyDisplay::SetRenderState(bool IsRendering)

This just picks a different cursor, depending on whether POV-Ray is currently
rendering or has finished.

  LRESULT WinLegacyDisplay::WindowProc (...)
  LRESULT CALLBACK WinLegacyDisplay::StaticWindowProc (...)

Pure Meat! This is called by Windows when something special happens. We've yet
to see how Windows knows that this is the thing to call.

You definitely want to implement some reactions for the cases WM_CLOSE (which is
passed to this function when the user requests to close the window) and WM_PAINT
(which is called when Windows requests to re-draw portions of the window; this
is where we actually make the drawing area visible. You should also hndle
WM_DESTROY, as it will tell you when for some reason the window is destroyed.

return (DefWindowProc (m_Handle, message, wParam, lParam)) ; should be called
for all other events, telling Windows that we don't consider it any of our
bloody business.

In a pure C environment, you can combine the two functions into a single one;
WinLegacyDisplay::StaticWindowProc() is just there to call the other one.

  HPALETTE WinLegacyDisplay::CreatePalette (...)

This seems to be irrelevant for 24-bit RGB operation.


The pvdisplay.cpp leaves us with a few loose ends; if I'm not mistaken, the
following code from the register_classes function in pvengine.cpp should tie
them up:

  WNDCLASSEX  wc ;
  ...
  wc.cbSize        = sizeof (wc) ;
  wc.hIconSm       = NULL ;
  wc.cbClsExtra    = 0 ;
  wc.cbWndExtra    = 0 ;
  wc.hInstance     = hInstance ;
  wc.lpszMenuName  = NULL ;
  wc.hbrBackground = NULL ;
  ...
  wc.style         = CS_BYTEALIGNCLIENT ;
  wc.lpfnWndProc   = WinLegacyDisplay::StaticWindowProc ;
  wc.hIcon         = renderIcon ;
  wc.hCursor       = LoadCursor (NULL, IDC_CROSS) ;
  wc.hbrBackground = NULL ;
  wc.lpszClassName = PovLegacyRenderWinClass ;
  wc.cbWndExtra    = 8 ;
  if (RegisterClassEx (&wc) == false)
    return (false) ;

This must be executed prior to the stuff in pvdisplay.cpp.

We haven't tackled renderIcon yet, but you can leave that to NULL for starters.

I'm not sure whether you can leave hInstance set to NULL as well, but I guess
not; we'll most likely need yet another function defined in pvengine.cpp, which
is actually the official entry point for a full-fledged Windows application
(instead of main()):

  int PASCAL WinMain (...)

There's a lot in there though that we'll not need, and I guess I'll leave this
up to later to sift through this. Suffice it to say here that the only stuff I
expect to be of relevance is in the while (!exit_loop) very near the end - you
need to run this after you have set up everything as outlined above; it's
basically the code that "does everything", including an occasional check for
inbound events (the while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) loop).

For comparison, here's some sample code from the Windows documentation from
Visual Studio:

------------------
HINSTANCE hinst;
HWND hwndMain;

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine, int nCmdShow)
{
    MSG msg;
    BOOL bRet;
    WNDCLASS wc;
    UNREFERENCED_PARAMETER(lpszCmdLine);

    // Register the window class for the main window.

    if (!hPrevInstance)
    {
        wc.style = 0;
        wc.lpfnWndProc = (WNDPROC) WndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon((HINSTANCE) NULL,
            IDI_APPLICATION);
        wc.hCursor = LoadCursor((HINSTANCE) NULL,
            IDC_ARROW);
        wc.hbrBackground = GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName =  "MainMenu";
        wc.lpszClassName = "MainWndClass";

        if (!RegisterClass(&wc))
            return FALSE;
    }

    hinst = hInstance;  // save instance handle

    // Create the main window.

    hwndMain = CreateWindow("MainWndClass", "Sample",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL,
        (HMENU) NULL, hinst, (LPVOID) NULL);

    // If the main window cannot be created, terminate
    // the application.

    if (!hwndMain)
        return FALSE;

    // Show the window and paint its contents.

    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);

    // Start the message loop.

    while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
    {
        if (bRet == -1)
        {
            // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    // Return the exit code to the system.

    return msg.wParam;
}
------------------


Post a reply to this message

From: clipka
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 01:15:05
Message: <web.4a6e892dac52dfd4813466d60@news.povray.org>
"David H. Burns" <dhb### [at] cherokeetelnet> wrote:
> A peek function would still be useful, but a poke function on a multi
> tasking system where
> the operating system is in RAM ... well at best, you might reboot a lot.

Would be very boring these days: At worst, poking around would get that
particular app jam itself, and you'd have to kill it via the task manager.

The operating system (with lots of hardware support from the CPU) does a good
job at not allowing any app to peek or poke around in memory allocated to other
programs or the OS. Applications even typically get to see different sections of
physical memory at any particular address.

BTW, in C you can actually peek & poke around as you like on virtually all
platforms, simply by assigning an arbitrary integer value to a pointer and then
accessing the memory location pointed to.

May result in the application getting terminated for an access violation though,
courtesy of Intel's "protected mode" and paging mechanisms, which can be used to
automatically trigger a hardware interrupt when certain memory address ranges
are accessed, so that the OS can take over and handle the access accordingly
(killing a misbehaving program, swapping virtual memory back in, or the like).


Post a reply to this message

From: clipka
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 01:25:03
Message: <web.4a6e8b28ac52dfd4813466d60@news.povray.org>
"David H. Burns" <dhb### [at] cherokeetelnet> wrote:
> > "Jesus was a capricorn"
> >
> > (Identified from memory... man, it's been ages since I've last heard that song.)
> >
> >
> Me too. I have it somewhere on a reel to reel tape. I wonder how long it
> would take
> me to find it.:)

I gotta ask my dad to copy that vinyl record to mp3... I didn't really like
"Jesus was a Capricorn", but I guess one or two other songs from the album were
ok, though the only other one I recall was "Jesse Younger" (which I quite
liked).


Post a reply to this message

From: clipka
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 01:30:03
Message: <web.4a6e8c4eac52dfd4813466d60@news.povray.org>
"David H. Burns" <dhb### [at] cherokeetelnet> wrote:
> I ought to apologize for my typos and irregular lines. The keyboard on
> this Timex Sinclair
> is rather small and my tail keeps getting in the way.

Ook!

(Or was that some other thread? ;))


Post a reply to this message

From: clipka
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 01:40:04
Message: <web.4a6e8e99ac52dfd4813466d60@news.povray.org>
"David H. Burns" <dhb### [at] cherokeetelnet> wrote:
> >> The graphics routines in John Beales wonderful
> >> heightfield programs don't work, though the rest of the program does.
> >
> > The name doesn't ring a bell.
> >
>
> You took me aback! I had to call up Pov-Ray links to make sure had had
> the name right.
> Have you every played with heightfields? I can't imagine anyone who has
> not being familiar
> with John Beale's "Gforge".

Indeed I haven't done much heightfield stuff.


Post a reply to this message

From: Chambers
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 01:58:58
Message: <4a6e93a2$1@news.povray.org>
Jim Henderson wrote:
> Oh, there have been much longer threads in here.... :-)

So... is religion good or bad? :)

<ducks>

-- 
Chambers


Post a reply to this message

From: David H  Burns
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 02:04:04
Message: <4a6e94d4$1@news.povray.org>
Chambers wrote:
> David H. Burns wrote:
>> You took me aback! I had to call up Pov-Ray links to make sure had had 
>> the name right.
>> Have you every played with heightfields? I can't imagine anyone who 
>> has not being familiar
>> with John Beale's "Gforge".
> 
> (Warning!  Thread is becoming dangerously on-topic! :) ).
> 
> I'm aware of it, but I never used it.  I prefer making my height fields 
> with POV-Ray instead :)
> 
Gforge has a lot of tools for modifying  the basic heightfield. It's fun 
to play with
in itself. It has its own display routine (16 bit) but this fails on XP 
and maybe on 98 and
2000 -- I can't remember.

David :)


Post a reply to this message

From: David H  Burns
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 02:48:07
Message: <4a6e9f27@news.povray.org>
clipka wrote:
> the file to look at there is "pvdisplay.cpp" in the
> "windows" subdirectory, which defines a WinLegacyDisplay object (well, an
> object class, to be precisely).

Well, it *is* complicated. I'm still not convinced that, even with 
legacy considered,
that it need be so. But since it is, that's what I'll have to work with.

The 3.6 code that I have doesn't have "pvdisplay.ccp"
but I take it that the code wherever it is (pvengine, I suspect) is 
similar. It looks like
I am going to have to delve into the mysteries of WINAPI (which I have 
already looked
into a little.) Your post should help. Unfortunately Microsoft 
documentation is rather obscure
too me, and I don't read well for very long on a computer screen. It's 
gonna be a long learning curve, the
question is, is it worth it? I'm beginning to think not. But, then, when 
once mastered, I should be
able to write routines that could with relative ease be adapted to about 
any language. I need
not fear that they won't work on future Windows versions, because unless 
I go completely senile,
I will *never* purchase another Windows machine! Even now I'm wondering 
if graphic programming
with a Mac is this complicated.

Thanks a lot. I will study this and will no doubt have "stupid" 
questions. :)

David :) :)


Post a reply to this message

From: David H  Burns
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 03:02:40
Message: <4a6ea290$1@news.povray.org>
clipka wrote:

> BTW, in C you can actually peek & poke around as you like on virtually all
> platforms, simply by assigning an arbitrary integer value to a pointer and then
> accessing the memory location pointed to.

I didn't know that, if I ever did, I had forgotten it. Thanks :)
> 
> May result in the application getting terminated for an access violation though,
> courtesy of Intel's "protected mode" and paging mechanisms, which can be used to
> automatically trigger a hardware interrupt when certain memory address ranges
> are accessed, so that the OS can take over and handle the access accordingly
> (killing a misbehaving program, swapping virtual memory back in, or the like).
> 

I blamed those "access violations" that occasionally show up on Windows. So
their really due to a "safety" feature in Intel's hardware. Is that why 
machines with
AMD processor's (reportedly) crash and hangup less frequently?

David :)


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.