Archived

This topic is now archived and is closed to further replies.

Object Oriented Bitmap

This topic is 5570 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello guys & gals, Like most people, i''ve been following the Object Oriented paradigm, but it seems like I still cannot get the hang of it. I''ve ordered a few books now which are on the way, and I''ll have some new stuff to read for quite a while after I get those. Anyways, I still don''t have the books, and I''m stuck on a problem where I''m trying to decide HOW I want to design the interfaces of my CBitmap and CDirectDraw classes. Here are some questions I have that would make it easier for you to understand where I''m coming from: Should I create a CImage and derive CBitmap (in future maybe CJPG, CGIF, etc...) from or do I have to make CBitmap definition on its own. If I do use a CImage from which to derive other image classes, what data members should I define in there. Where do I put the draw method in the CBitmap or CDirectDraw object? In order to make it more abstract, (i.e. let''s say I decide to add another image class CJPG to the draw function) how should I build it so it knows what it''s supposed to draw? I''m sure by now you understand I''m quite lost in the whole OO design process, so if someone is kind enough to give me a hand I''ll appreciate it greatly. TIA -G|aD-

Share this post


Link to post
Share on other sites
Object Oriented Programming is very useful and belongs in many places, but not everywhere. What intrinsic entity are you trying to model? Why is an object hierarchy the best way to model it?

Fundamentally, all bitmapped images are simply a rectangular grid of pixel values (and even vector images are eventually rasterized). Does it make more sense to have a representation for this grid and different functions that load different types of files, populating the grid with the appropriate pixel values?

OO for OO''s sake is a disservice to everyone.

Share this post


Link to post
Share on other sites
I''m no expert, and be warned I program in VB, but I''ll give a shot at answering this.

You''d put the in your CImage class everything that is common to all of the CBitmap, CJPG, CGIF etc classes. Examples - GetWidth(), GetHeight(), GetFileSize(), LoadFromFile(), Draw(). But if something is only possible with a CJPG but not with a CBitmap, then you don''t put it in the CImage, you just put it in the CJPG. For example, CompressThisMuch()

Now lets take the Draw() example. In your CImage class, Draw() does nothing, or maybe it does something simple that you may like to do first such as clear the background, but it doesn''t draw your image. But the Draw() function in the CBitmap class actually handles getting a bitmap on the screen. And the same with the CJPG class, that handles how to get a JPG on the screen.

You COULD have a DrawImage() function in your CDirectDraw class if you liked, which takes a pointer to ANY type of CImage object as input (so you could feed it a CBMP or a CJPG) and the CDirectDraw class would simply call the Draw() function of the object that was fed in.

I hope that was of some little help.

Share this post


Link to post
Share on other sites
This is the time to learn OO, and since I''m starting a new project I would like to re-write everything in OO matter to understand how it works and understand its uses.

Thanks!

-G|aD-

Share this post


Link to post
Share on other sites
bazee, thanks that''s very helpful. Even though I had some idea how to do it I just wanted to make sure I was on the right path of doing it.

On to the draw() function. The current problem that I''m having is that CBitmap requires a pointer to a CDirectDraw object in order to draw it. Is there a way to call the CBitmap::draw() function without passing the CDirectDraw object to the function? Maybe a different way of designing both classes? Anyone with experience in this area?

Let''s say everything was working fine, and I wanted to have a drawImage() function in my direct draw manager, right? Now the DDManager would call the image''s draw() function, but I''m wondering if I should make the draw() function in CImage public/private/protected or a friend to the DDManager class.

All ideas/suggestions are welcome.

Thanks!

-G|aD-

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
It seems to me that you would want to separate the loading of bitmaps from bitmaps themselves. This way you could create many different bitmap "loaders" (PNG,GIF,JPEG etc...) without affecting your bitmap class or subclasses (though with this model I''m not sure if you''d have bitmap subclasses at all?).

Share this post


Link to post
Share on other sites
Well now your question is more C++ specific, and I'm very much a newbie in that language. However OOP concepts spread across many languages.

quote:

I'm wondering if I should make the draw() function in CImage public/private/protected or a friend



I would suggest that the Draw() function is public because I don't see any reason to hide it. Otherwise how will you program ever call it? You should only hide the function (by making it private) if it's never going to be used outside of the class, or if it would be invalid to use it outside the class (like it may have a bad side effect). For example (this very inefficient in reality, but it's the first thing that came to mind which shows my point) - lets say you have a function called SetPixel(), a function called Lock() and a function called Unlock(). To set a pixel, you must first lock, and the afterwards you might want to unlock. The SetPixel function would look like this:

Function SetPixel()
{
Lock();
WriteThePixel();
Unlock();
}

Now what you could do is make the Lock() and Unlock() functions private, because the outside program doesn't need to know about them anymore. Also, if the outside program did actually accidentily call the Lock() and Unlock() functions, it may cause problems.

quote:

The current problem that I'm having is that CBitmap requires a pointer to a CDirectDraw object in order to draw it.



I'm sorry I can't help answer that question, because in my graphics engine, I really do give my CBitmap class (the VB equivalent of) a pointer to the CDirectDraw class! Anyone have any better ideas?

[edited by - bazee on September 9, 2002 11:40:11 PM]

Share this post


Link to post
Share on other sites
Awesome! Thanks so far!

If anyone has suggestions from personal experience of implementing this kind of thing, or ideas on how to do it that would be valid, I''ll be glad to hear it.

Also, any recommendations on learning Object Oriented programming would be great and much appreciated!


Thank you all,
-G|aD-

Share this post


Link to post
Share on other sites
I''ve already done that and even though there are some nice classes out there, they don''t take into consideration other objects they have contact to (like my bitmap has contact with directdraw manager and vice versa). Also, I''d like to hear some ideas from people not just plain code.

Thanks though



-G|aD-

Share this post


Link to post
Share on other sites
Paintings don''t paint themselves. Artists paint paintings.

So my images don''t have a ''draw'' function. My renderer has a draw function and you pass it the image.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

Share this post


Link to post
Share on other sites
That's all I'm asking for guys. That's an excellent idea and great new info to me.

Kylotian, your reply has raised a few questions in me. How would the renderer know what to draw and which method to use (bmp, jpg, gif, etc.)

Let's say I have this:


    
class IImage
{

protected:

int m_iWidth;

int m_iHeight;

public:

IImage( ) : m_iWidth(0), m_iHeight(0) { };

virtual ~IImage( );

};

class CBitmap : public IImage
{

DirectDrawSurface pSurface;

public:

BOOL load( std::string strFileName ) {...};

void release( void ) {...};

};

class CDirectDraw
{

public:

void drawImage( const IImage &srcImage ); // **


};



Ok, how do I make DDraw manager recognize which type of image it has to draw? Can you help me with some code snippets of the class interfaces and important implementation details?

I'm thinking of having a draw() method for each IImage derived class, make the method private, and define it as a friend to the DDraw manager. This way the manager will call the according method but it will still be private in the image object.

Please give me more suggestions/ideas/code snippets!

Thanks!

[edited by - Gladiator on September 10, 2002 9:22:23 PM]

Share this post


Link to post
Share on other sites
What your failing to understand, that it doesnt matter what the image format is... once loaded into memeory they are all *bitmaps*... or just a raw array of pixel info...

if you want to keep with your class for each image type, what it should be used for is loading and saving of the data.

so your CJPG class will know how to load a JPG file and convert it into a bitmap in memory, or however else you require image data in memory.

CBitmap will do the same as CJPG, but it will convert the BMP fileformat into a bitmap in memory.

then you just need a public method/variable that is a handle to your pixels in memory, (in windows either a HDC/HBITMAP).

then your rasterizer (your CDirectDraw) will have a Draw function, that when called, will call/grab the handle to the image data from your CImage classes... and from that handle it can call the API draw methods to put that image on the screen.

Share this post


Link to post
Share on other sites
shadwdrake, Thanks for the reply.

I understand what you are saying and the way that works. I guess I''m too deep into this OO thing and I''m having a hard time trying to make the classes as abstract as possible.

More replies please

I''m a newbie when it comes to object oriented design and architecture so anything that you say in that area is most likely new to me and will help me learn more.

Thanks!



-G|aD-

Share this post


Link to post
Share on other sites
I would design such an image loader like this:

CImageLoader
virtual bool CanLoad() = 0
virtual bool LoadImage() = 0

CImageServer
RegisterLoader()
UnregisterLoader()

CImage *NewImage()
CImage *LoadImage()

CImage
Width()
Height()
Format()

CBitmapImageLoder : CImageLoader
bool CanLoad()
CImage *LoadImage()

CJPGImageLoader : CImageLoader
bool CanLoad()
CImage *LoadImage()


You''ve got an CImageServer which manages image creation (either from file or a new image). Registered to the CImageServer are any number of CImageLoader-derived classes which are used to load various image formats from file.
Additional loaders can be added at any time, even after the library has been compiled by simply using the CImageServer::RegisterLoader() method.

CImage is then created by those loader, but does itself not know a thing about which file format it was loaded from. Why duplicate Width(), Height() and all that when it has nothing to do with the file on disc ?

I would strongly suggest not to put a Load() method into the image and not to derive CImage itself for different image formats, because you will be copy&pasting lots of code resulting in poor design.


You can find an object oriented C++ image loading library at http://www.paintlib.de

-Markus-

Share this post


Link to post
Share on other sites
Markus, that''s the type of thing I want to see more often :-)

Your design is very enlightening and I''m getting lots of ideas at this moment. THANKS!

What books should I look into to configure my mindset to think in terms of objects and not functions (i.e. object oriented programming) when designing a program? Markus? Anyone else?

Thanks to all who replied. Keep the replies pouring in...



-G|aD-

Share this post


Link to post
Share on other sites
quote:
Original post by Gladiator
What books should I look into to configure my mindset to think in terms of objects and not functions (i.e. object oriented programming) when designing a program?

This is what scares me. There are times when functions are the more appropriate solution. What you want is to think in terms of the appropriate technology, not exclusively one or another.

Anyway, I''d have an Image class and a number of Load<Format>Image methods at global scope (not a part of the class).

class Image
{
public:
void allocate( unsigned long w, unsigned long h );
void set_fmt( ImageFormatDescriptor fmt );
// whatever
 
private:
unsigned long * bits;
unsigned long width, height;
};
 
bool LoadBMPImage( const std::string & filename, Image & img )
{
// obtain BMP file dimensions (w, h)
// obtain image format (fmt)
img.allocate( width, height );
img.set_format( fmt );
 
// and so forth
return true;
}

You could also switch up the Load* interfaces so that they can be used as Image img = LoadBMPImage( "image.bmp" ); This clearly separates an image''s definition from implementations of algorithms that operate on the image, either loading, drawing, copying or otherwise manipulating it. Save class members for alterations of/access to intrinsic properties, allowing you to add more "external" operations without modifying the class definition.

Share this post


Link to post
Share on other sites
Oluyseyi, I've had plenty of experience with functions and I know when they are appropriate. I'm trying to learn OOP now, and the whole point behind the project I'm currently working on is to get some design concepts into my programming so I know WHEN it is appropriate and HOW to design an object. Right now I don't know neither of the two in OOP, and only in modular which is not what I'm going after at this moment.

Edit: By the way, thanks for the design idea but as I said global functions are out of the question for this project

[edited by - Gladiator on September 11, 2002 2:34:02 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Gladiator
[...]
I''m currently working on is to get some design concepts into my programming so I know WHEN it is appropriate and HOW to design an object
[...]
Edit: By the way, thanks for the design idea but as I said global functions are out of the question for this project
You said you wanted to learn when it''s appropriate to use objects and when not. Well, here''s a situation when objects are not the best solution

I used to be pretty strict about not using globals, but now I have to rephrase myself: Most things that don''t have a state , should be globally accessible. By globally accessible, I mean you should put it within a namespace or within a singleton (search Google for singleton design pattern). Maybe as a static member function occasionally..

Loading images is (usually) a stateless operation and should be possible anywhere in your project. So Oluseyi''s design was good, but I prefer the Image img = LoadBMPImage( "image.bmp" ); way

Share this post


Link to post
Share on other sites
I think Oluseyi is quite right here.
You could make the LoadBMP() function a static member of CImage, but that would break up encapsulation imho (you need to modify CImage to add a new file format).

My example is about the same, with CImageServer being a singleton object (an object that exists only once in the application). It just nicely avoids the global load() function and provides further flexibility (add file format loaders at runtime).


I don''t know of any good books on the subject. I really like [URL="http://www.aw.com/catalog/academic/product/1,4096,0201633612,00.html"]Design Patterns - Reusable Elements Of Object Oriented Software[/URL], but I don''t think it''s good for learning OO programming.

-Markus-

Share this post


Link to post
Share on other sites
quote:
Original post by Cygon
I really like Design Patterns - Reusable Elements Of Object Oriented Software, but I don''t think it''s good for learning OO programming.
Why not? I thought it was a very good book about fundamental OO concepts. Most C++ books only show you what classes are and some simple class hierarchies. They usually overemphazise inheritance, even though aggregation would be better solution in many cases. Design Patterns shows how to use classes well.

Share this post


Link to post
Share on other sites
Hello guys,

Let me take a minute and thank you for your input! Much appreciated!

quote:

You said you wanted to learn when it''s appropriate to use objects and when not. Well, here''s a situation when objects are not the best solution



What I really want is to learn OOP and THEN I''ll be able to decide on my own the better choice for a specific situation. Since I don''t know OOP I can''t even use it where I might think it fits the situation, so I can''t decide what''s a better way to do it. The only way I know now is procedural programming, and how to encapsulate certain data members/functions in an object, which is not the same as OO design and that''s what I''m striving for.

Thanks guys, keep it flowing...

Share this post


Link to post
Share on other sites
Can someone at least suggest some good books on OOP & OOD. The language explored doesn''t make a big difference, but C++/VB/Java is prefered.

If you have suggestions or would like to showoff your own bitmap loader please reply as well...

Thanks!

-Viktor

Share this post


Link to post
Share on other sites