SetPixel equivalent on mac? - c

I'm currently writing a software renderer and after i got it to kind of work on windows I began thinking about porting it to Mac.
My Question therefore is: What's the equivalent to the Win32 GDI SetPixel function?
All I need to be able to do is plot a pixel at (x,y).
I'm new to mac development and the closest thing I found resembling an answer was to use an OpenGL Texture to which one would draw to. But that kind of defeats the point of having software rendering if i have to use OpenGL...
Is it even possible to plot single pixels in osx?

Short answer
Just use LibSDL (preferably version 2.0).
Long answer
You have to get your pixel data from system memory to graphics memory anyway. One way to do that is with OpenGL. You can think of OpenGL as a fancy API which lets you push data from system memory to graphics memory. Since that's exactly what you want to do, it makes sense to use OpenGL.
But that kind of defeats the point of having software rendering if i have to use OpenGL...
The graphics card is going to do the work of compositing your pixels on the screen whether you like it or not so you don't get any particular portability advantages by avoiding OpenGL. Back in the 90s you could just get a pointer to the framebuffer and push pixels there, but those days are gone.
LibSDL is nice because it gives you an API which lets you push pixels to a buffer, and then LibSDL takes care of putting the buffer on screen.
SetPixel() is horribly slow anyway, so you should be using LibSDL on Windows too.

Related

Switching to a higher resolution

Recently, I started developing an operating system in NASM and C. I have already made a boot loader, kernel, filesystem, etc. So far I used the VGA text mode directly in order to write to the address 0x000B8000. So, I decided to switch to video mode instead of text mode. I chose maximal display resolution 320x200, but then I realised that there are three problems. Firstly, there are only 256 different colors. Secondly, the resolution is too small. Thirdly, writing to the address 0x000A0000 is too slow. I tried to do some animations, but it is very laggy and sometimes it waits more than one second before the next frame.
I have searched on the internet for some explanations on how to switch to higher resolutions such as 1920x1080 and how to use 256*256*256 colors instead of just 256. Everything I found said that it is very hard to use higher resolutions because you must develop drivers for all the different types of graphics cards and for some cards there are no documentations, so we must use reverse engineering.
I really want to introduce high-resolution graphics to my operating system. Is it really hard or is there any easy method? Any suggestions on how I can solve this?
Nearly every graphics adapter supports VESA framebuffer semantics, you can configure almost every video mode with that. The drawback is that you cannot use vendor specific features (accelerated graphics etc.)
The VESA-Xserver for example works with almost any graphics adapter (but the model specific ones are considerably faster)
See also: https://en.wikipedia.org/wiki/VESA_BIOS_Extensions
You can do high res VESA graphics in assembly and it should be fast enough (in the beginning phase when you are learning and not doing very fancy 3d stuff, especially).
First of all, make sure you are using a good emulator/virtual machine for testing. I was using QEMU and it was way to slow to do any graphics at only 640x480x24bpp. I switched to VirtualBox and though it starts up quite slowly, I have never looked back.
As for the programming part, I encourage you to look at a project called Pure64. You can find it on GitHub. Go to src/init/isa.asm and look at the end of the file - there is some code to do VESA initializations. I am actually using Pure64 to set up a clean 64bit environment and I am doing VESA graphics so I can say that it works fine.
The VESA init consists of two parts - getting mode info and setting the video mode. Once you get the mode info, you get a Video Base Pointer to a region of memory which is continuous and where you can write your pixels without switching banks and doing complicated stuff. At least in 64-bit mode.
The only problem I had with this is that I could not make 32bpp mode working. I can do 24bpp, which is RRGGBB - 3 bytes per pixel (exactly like HTML/CSS color codes). As with everything that comprises of 3 bytes on a binary computer, this makes some things a bit more complex (at least for a beginner). Getting 4 bytes per pixel to work still eludes me. Maybe this is a limitation of VirtualBox or something.
This all means that for basic hi-res graphics there is no need to do a lot of hardware-specific things. If you are on a mildly current hardware, you should do fine.

Changing display modes from the command line

Way way back in the day Itried to learn C from a game programming book. If I recall correctly, one of the first things your game "engine" would do would be to switch display modes to render. This involved a bit of asm to switch to a 640x480 display mode (mode 13 maybe?) so you could draw directly to the screen. Something like that.
My question is, what is the modern equivalent of this? I'm interested in writing a command line program that does something similar; drops into some kind of raster mode for me to draw to, but, I do not assume that my program would be running under some kind of window manager like kde, unity,Aqua etc.
Would this be something that OpenGL could provide (or does OpenGL assume a window manager too). My proposed program isn't a game, but would ideally start with a basic clear screen that I can draw primitives (2d lines, circles rects etc)
Cheers!
Modern operating systems don't give programmers as convenient access to low-level graphics routines as they used to. Partially, this is due to the advent of the GPU, which makes utilizing the graphics hardware a much more significant challenge than if you only had a CPU. The other reason is as window managers have gotten more and more complex, the graphical sandbox each operating system gives a programmer is more constrained.
That being said, OpenGL is definitely worth looking at. Its cross-platform, versatile, and automatically utilizes any hardware available (including the graphics card). OpenGL itself doesn't directly provide access to a windowing context, but you can easily create that with the OpenGL utility library (GLUT). OpenGL is however very low-level, you'll have to deal with frame buffers and flushing and bit masks and all sorts of low-level nonsense that can make OpenGL development a nightmare if you haven't done it before.
If I were starting a project, I would probably want a more robust graphics environment that provides drawing functions and windowing out of the box. Both SDL and SFML provide low-level graphics APIs that will be a little more friendly to start with. They are both implemented on top of OpenGL so you can use any of the OpenGL features when you want to, but you don't have to worry about some of the more tedious details.
As a side note, C might not be the best language to get started with graphics programming these days. If you want a really simple graphics environment that is becoming more relevant every day, you might want to check out what the web has to provide. JavaScript and the HTML5Canvas provide a very simple interface for drawing primitives, images, etc.

Windows Screenshot into graphics memory

I am sorry if it appears this question has been done to death. I've done plenty of research however, and it seems there is no well known solution to what seems a simple problem: take a screenshot in windows.
There's a catch of course - the screenshot is to be manipulated in some way (gpu side, with shaders/etc), so there is no option of a slow copy to system memory. Instead the copy must somehow stay in graphics memory. GetFrontBuffer and the like a limited in this sense (they don't work full stop, I've checked).
I am aware of several closed questions on the stack exchange network ("Don't bother, not possible") and 2 with open bounties that amount to solving this problem.
Windows 7 introduces some changes to the graphics system, so now there is a compositing window manager,etc. Apparently GDI is also now 'hardware accelerated' so I was hoping this would have exposed a simple path for a possible solution:
gdi desktop window device context (in gpu memory) -> some direct2d or direct3d surface
In my particular case, just getting the DC in gpu memory is sufficient, but I am looking for a general solution.
So, how does one screnshot gpu side in Windows?

Visualizing Molecular Dynamics Simulations in 3D

I've been working with some legacy C Molecular Dynamics code, and it came with it's own home-grown visualization routines. I am wondering if there isn't something better and more flexible that I can use, since I am reaching the limitations of the current approach.
The current routines are all using OpenGL, and then drawn via X11 (I'm on a mac most of the time). There is a problem related to this where I can display the simulations while they are running on linux, but capturing them returns a black screen.
My basic problems with this are that:
I don't have any experience with OpenGL or X11, or even graphics for that matter.
Adding in new objects to draw is hard.
So my options are to learn OpenGL and X11, and figure out what is going on, or try something else. I do write out the information that the movies duplicate into a binary file as the sims run, and I can always read that in and create the movies later.
What I need is the ability to:
Create various basic geometric objects in 3D
Having the ability for them to change color based on orientation, etc, would be nice
Be able to generate the movies in .mov format (I use ffmpeg on .bmp files right now)
Be able to manipulate the perspective for either 3D (be able to rotate the image), or to be able to have multiple perspectives simultaneously (polar projection, side view, etc)
I see that some of this was covered here, which I am going to take a look at, but I really want something that I could use real-time as the sims run to inspect what is going on for bugs, etc.

Is there a non-deprecated raster graphics framework for Mac OS X?

I am looking for a raster graphics framework for Mac OS X. Specifically, I want some kind of view that I can manipulate (at least conceptually) like a matrix of pixels. My program will generate the pixel data programmatically.
QuickDraw fits that description nicely, but is deprecated. As far as I can tell, there is nothing equivalent in Core Graphics. Am I missing something?
A plain C framework would be preferable to an Objective-C one, but I'm not too fussy.
QD was deprecated because there is no way to do implement it efficiently with the the current generation of fully composited UIs and GPU HW. For that reason there is nothing quite like QD on the system, and there won't be. Allowing direct access to the backing store forces at best forces a lot more bus transactions to and from the GPU, and at worst may prevent a texture from being loaded on to the card itself, and some cases may cause software fallbacks.
It is clear there are sometimes reasons people need pixel level access to a backing store, so there are some mechanisms to do it, but there are no real convenience methods and if you can find some way to avoid it you should. If you can't avoid it you can use CoreGraphics to create a bitmap context using CGBitmapContextCreate where you have access to the backing store and can manipulate the backing store directly. It is not simple to work with, and it is slow.
What about dividing the width and height of the view by itself, then draw width x height squares? You could just use an NSPoint and increase it by one until it hits width x height.
The Simple Directmedia Layer has pixel access. It may be over kill as it is a porting library, but the entire API is in plain C. I do not know what it uses as an underlying MacOS API uses. Best to check the website to see if it is suitable for your purposes.
Alternatively, you could use OpenGL textures.
The best way to do this is Core Image. It's designed for working with pixels, and it's very fast because it lets you do the work on the graphics card.

Resources