POV-Ray : Newsgroups : povray.off-topic : Tell me it isn't so! Server Time
10 Oct 2024 03:17:22 EDT (-0400)
  Tell me it isn't so! (Message 294 to 303 of 473)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Jim Henderson
Subject: Re: Tell me it isn't so!
Date: 27 Jul 2009 21:35:56
Message: <4a6e55fc$1@news.povray.org>
On Mon, 27 Jul 2009 19:54:32 -0500, David H. Burns wrote:

> Wow! I actually took those numbers from my TRS 80 Model III. They did a
> lot with a little
> memory in those days. The PET I had had a full-sized normal keyboard,
> IIRC

Yeah, the later models of PET used a full-sized keyboard - the 8K model I 
remember certainly did, as did some variants of the 4K model IIRC.

That really takes me back, though....

Jim


Post a reply to this message

From: Jim Henderson
Subject: Re: Tell me it isn't so!
Date: 27 Jul 2009 21:36:44
Message: <4a6e562c$1@news.povray.org>
On Mon, 27 Jul 2009 20:00:10 -0400, clipka wrote:

> "Jesus was a capricorn"

Jesus was Jewish! -- Avenue Q Soundtrack

Jim


Post a reply to this message

From: Jim Henderson
Subject: Re: Tell me it isn't so!
Date: 27 Jul 2009 21:37:45
Message: <4a6e5669$1@news.povray.org>
On Mon, 27 Jul 2009 19:47:14 -0500, David H. Burns wrote:

> Jim Henderson wrote:
>> On Mon, 27 Jul 2009 18:27:19 -0400, Warp wrote:
>> 
>>>  That kind of mocking attitude isn't really helpful.
>> 
>> Nor is it particularly helpful to mock the abilities of someone you've
>> only just met.
>> 
>> This thread needs a whole lot of "lighten up, folks!".  Seriously.
>> 
>> Jim
> I *thought* my monkey comment was light. Maybe we have just harped on
> this same,
> rather tangled, thread to long. :)

Oh, there have been much longer threads in here.... :-)

> 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


Post a reply to this message

From: David H  Burns
Subject: Re: Tell me it isn't so!
Date: 27 Jul 2009 21:45:39
Message: <4a6e5843$1@news.povray.org>
clipka wrote:

> XP (for good reason) doesn't allow you to access the graphics card directly
> (just guess what happened if every application you have running on your
> computer - say, browser, calculator, Windows Explorer and your own home-brewn
> program - would try to poke around at the graphics hardware, maybe even trying
> to run in different modes... perfect chaos.
> 
> But a suitable driver might provide a frame buffer of, say, 640x480 pixels for
> you to use freely, and do the interfacing to Windows (including event handling)
> for you, instead of directly accessing real hardware. 
>
I can appreciate that it might be wise to restrict access to the video 
card. But it is possible to
display images somehow. Pov-Ray does it and in a whole host of 
resolutions. Maybe displaying
graphics is very hard but it can't be impossible!!

> 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".

David


Post a reply to this message

From: David H  Burns
Subject: Re: Tell me it isn't so!
Date: 27 Jul 2009 21:51:20
Message: <4a6e5998$1@news.povray.org>
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.

David


Post a reply to this message

From: Darren New
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 00:11:18
Message: <4a6e7a66$1@news.povray.org>
Warp wrote:
>   Immediately when you started having different users with different
> hardware setups, the whole graphics programming stumbled on a huge problem.

I don't think it's really even just graphics, altho graphics are the main 
source of problems.

I think having libraries (or, more particularly, "components") is a 
difficult thing to do efficiently.  I've been looking at bunches of code for 
high-efficiency programming lately, and I've started remembering what I hate 
about C and C++ and the ilk.

The problem with all the low-level languages like C and C++ and such is that 
they don't really come with the libraries you need to do modern stuff. 
There's nothing built in for threading, graphics, sound, IPC, etc. That's 
all left to libraries developed well after the language was standardized.

With C it isn't too bad, but C doesn't support things at a high-enough level 
that I can take (say) an MPEG decoder library or a media streaming library 
and just use it. Most of the time the author either invents a whole bunch of 
routines to handle logging, strings, async I/O, header parsing, etc. Nobody 
really writes a sophisticated library relying on a minimum of outside 
non-standard libraries any more. *Most* systems have their own names for 
integers, strings, whole complex hierarchies of header files, etc. There's 
nothing even coming close to UNIX pipes or something where you plug things 
together without having to fix a bunch of stuff inside. For example, 
everyone has different logging libraries, instead of just writing to stderr 
like the libraries were originally designed to handle. If you want to use an 
XML parser, an HTTP client, a multimedia stream receiver, and a graphics 
framebuffer library, you're going to wind up with four different logging 
mechanisms probably more than one resource manager.

C++ is a lot better, in that at least people seem to avoid rewriting 
malloc() and such, and Boost (if you use it) has a bunch of handy libraries 
handling stuff everyone needs but everyone reinvents. Which is great if all 
the projects use the same version, and all your code is in C++. But just try 
to (say) use Qt from a language other than C++, and watch the pain-fest 
begin. If you can do everything from scratch in C++, you're in good shape, 
but if you're putting together a bunch of third-party stuff, you're pretty 
well screwed unless you can cut it into separate processes.

High-level languages designed to solve this problem (like C#, say) have the 
problem that they solve it by giving you huge libraries, so if not all your 
code is .NET, you're basically screwed again. At least you can go out and 
buy the components you want. The problem here seems to be that building such 
a framework properly requires a whole bunch of design on a huge library and 
runtime system, but people don't want to pay for that. Plus, if it doesn't 
come from someone that's essentially already a monopoly, getting everyone to 
use it is problematic. It doesn't matter how complete .NET's libraries are 
if you can't find the piece of code you're looking for except in some 
baroque conglomeration of twisty C++ classes. And it doesn't matter how 
complete .NET's libraries are if you can't use them on the machine you 
happen to be programming.

Sadly, I don't really see this getting better. Either your language is 
sufficiently low-level that it works everywhere you need it, or it is 
powerful enough that it has bunches of good code already developed for it 
(either as standard libraries or built into the language) that you can just 
plug in and use.

I don't think we're quite there yet, but I think the fact that languages 
evolve much more slowly than hardware does might make this less of a problem 
in the future.

-- 
   Darren New, San Diego CA, USA (PST)
   "We'd like you to back-port all the changes in 2.0
    back to version 1.0."
   "We've done that already. We call it 2.0."


Post a reply to this message

From: Chambers
Subject: Re: Tell me it isn't so!
Date: 28 Jul 2009 00:17:31
Message: <4a6e7bdb$1@news.povray.org>
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 :)

-- 
Chambers


Post a reply to this message

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

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

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