0,0 is relative to the windows 0,0 and not the desktop. If you didn't know that already, I suggest you just start diving in to opengl. You don't need scissoring for the viewport. If you simply started opengl you would figure that out almost immediately. Not sure what centered on the screen means.
You have a texture that is 12000x12000? ..........sigh
Kill whoever built it. max texture size is 8192x8192 unless it got bumped up even more that I dont know of. But that doesnt matter, no texture for an object needs to be that big.
Downsampling will work but im looking to get really good detail out of the object
I've seen plenty of detail out of 2048 textures, most of the time not needed 4096 textures. I would post a pic because that doesnt make any sense. Unless you plan to in game hold a microscope and zoom it in 10x.
If for say a gigantic spaceship, then this should have been built with multiple uv textures/uv coordinate sets. So each section would be a separate model/texture. If you need tiny detail, multiply a tiled black and white detail map and blend that with the other lower res textures. Or do the same: tile a detail normal map over the object.
If you hold your hand 45 degrees like the image and put it far left of your head and them move it towards the right, you will see the same thing. On the left your hand is facing you, on the right it is facing away from you and distorted because you are looking down the side of the hand and cant see the front anymore.
The only reason I haven't posted anything, is your pictures are ridiculous. I have no what I am looking at. I know its some terrain but its insane. Get rid of the texturing/tiles if you are just work on the lighting alone.
Does your lighting shader work on other objects like a sphere?
Make a function called Cross product that takes two vectors instead of this.
Result.X = ( A.Y * B.Z ) - ( A.Z * B.Y );
Result.Y = ( A.Z * B.X ) - ( A.X * B.Z );
Result.Z = ( A.X * B.Y ) - ( A.Y * B.X );
It looks like you are only doing face normals instead of blended vertex normals.
For direct cell shading control use a 1D texture of all the tones you want. Since dot product is in range 0 to 1, use that as a 1D UV coord into the texture. You can then at any time change from 2 tones to 4,8....and so on.
For outlines it depends how specific you want to outline. There is a case where say a camera is in front of you and you have your hand over your chest. You either want just the silhouette of the entire body, you want to draw outlines around the hand. (The hand is inside the silhoutte of the chest/body).
For just silhouette, draw your model 2x, once with GL_LINES and changing the GL_LINE_WIDTH bigger depending on your outline thickness.
For the second case of all outlines, just take the normal relative to the eye/screen. As it approaches 0, that means the normal is starting to point away from you.
if( dot(normal, vec3(0,0,1) < VALUE)
gl_FragColor = black;
Where value would be between 0 and maybe .3 depeding on how thick you want it to be.
Simple way without using a line drawing algorithm like Bresenham:
Create a 2D vector between start and end brush.
Find the length in pixels of that line using pythagorean theorem.
float timeStep = 1.0/length in pixels
float time = 0;
for(int i = 0; i < length in pixels; i++)
Vec2 fillPos = start + time*brushvector;
time += timeStep;
When time = 1, the fill pos is the endpoint
When time = .5, the fill pos is halfway to the endpoint
Based on your drawing you are trying to fill the points between the last brush position and the current. So you know where the user is drawing.
The only way to fix this is to draw a brush for each pixel in between the circles. If you use a distance bigger than that you won't get a brush stroke, you will get more of a caterpillar looking brush, like the medium drawing you posted.