I understand the from the terms that RCR would rotate the bit from the right to left, taking the bit from the carry while ROR will rotate the bit from right to left, taking the bit from the right but is that the only difference between them? If this is so, both of the instructions seem to do the same work. Please help out. Thanks
RCR includes the carry flag in the rotation, so it's effectively an N+1 bit rotate, whereas ROR does not include the carry flag, so it's just an N bit rotate.
Some nice diagrams from www.c-jump.com:
Both instructions rotate bits from left to right (where the left hand bit is the MSB).
RCR rotates the carry flag into the MSB and the LSB to the carry flag.
ROR rotates the LSB to the MSB without going through the carry flag.
+--> CF --> MSB --> ... -> LSB --+
| | RCR
+---------------------------------+
+-> CF +-> MSB --> ... -> LSB --+
| | | ROR
+------------------------------------+
Related
I know how to draw horizontal lines by doing
LOOP1 STR R5, #0 ;starting ixel
ADD R5, R5, #1 ;increment of pixel on coordinate
ADD R7, R7 #-1 ;decrement to the desired length counter
BRp LOOP1 ;keeps looping until register with desired length is zero
Obviously the registers will be different for whatever the user chooses for the counter and coordinate locations but these were just numbers from my previous code. What would be a way to manipulate that code to draw a vertical line? I'm not completely comfortable with the formatting of the code on this website yet either so please excuse me if I am wrong in a few areas.
The difference between horizontal line and vertical line is how we increment the pixel position.
Let's note that a two dimensional coordinate can (and must) be mapped to a one dimensional system by a formula like rowCoordinate * columSize + columnCoordinate. (Memory is a one-dimensional system, it doesn't have two dimensions so we use this kind of mapping.)
So, as you have shown, we can draw a horizontal line by traversing each pixel from (row,0) to (row,columnSize-1). By the mapping formula above, we go from
(row,c) to (row,c+1) by simply adding 1 to the address of the pixels.
To draw a vertical line, we want to vary the row position and keep the column position fixed as in: from (0,col) to (rowSize-1,col).
According to the mapping of 2d to 1d, that means going from
(r,col) to (r+1,col) we need to increment by columnSize instead of 1.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to make a raycasting engine in assembly and i have a problem.
drawing textures does not seem to work properly.
This is how it looks like:
in the for loops of finding collision with the wall , if collision was found I took the floating point part of the x or the y and used it to calculate where on the texture to draw.
I have tried debugging and I have found that the problem could be that the final texture x is the same few times but you can see in the pictures that it works almost fine when looking from the side so i don't think it's the problem.
The wanted result is just that the textures will be drawn correctly without those distortions.
I think the problem is somewhere in the code here:
mov ebx,WINDOW_HEIGHT / 2
sub ebx,eax
mov eax,height
mov screenypos,ebx
dec typeofwall
movss xmm0,floatingpoint
mulss xmm0,FP4(64.0f)
mov eax,typeofwall
cvtsi2ss xmm1,eax
mulss xmm1,FP4(64.0f)
addss xmm0,xmm1
movss tempvarr,xmm0
invoke FLOOR,tempvarr
cvtss2si eax, xmm0
mov finaltexturex,eax
;invoke
BUILDRECT,screenpos,screenypos,linewidth,height,hdc,localbrush
invoke DrawImage,hdc,wolftextures,screenpos,screenypos,finaltexturex,0,linewidth,64,linewidth,height
Try to print first for each column the "hit" coordinates, and which one would you use for texturing (keep in mind, that you have to use either map_x or map_y axis for texturing, depending on which grid line the ray intersected first with the wall and from which direction).
Now I got other idea... are you even using the byte map[16][16]; or something similar for walls definitions (Wolf3D 2.5D ray casting), or is this semi-polygon map system, calculating intersections with segments (DOOM 2.5D perspective BSP 2D-edge drawer (not ray casting at all in original DOOM!))?
If you are doing the Wolf3D raycaster, be aware you have to clean up your intersection formulas a lot, and decide wisely which part of calculation you do when, as bad order of calculation may quickly cumulate considerable amount of accuracy error, leading to quirks like "holes" in walls (when for single pixel column you miss the intersection with wall), etc.
With floating point numbers you are even more susceptible to unexpected accuracy problems, as the accuracy encoded in bits shifts fast by exponent (so around 0.0,0.0 coordinates you have quite better accuracy, than around 1e6,1e6 coordinates on map).
When done properly, it should look like "easy" stuff. I once made quick and dirty version in Pascal in one afternoon (as an example for a friend, who was trying to learn Pascal). But it's as easy to do it wrong (for example Bethesda's first Elder Scrolls "ARENA" had horrible intersection calculation, with walls y-position being jagged a lot). And usually the not-proper calculation has not only worse accuracy, but also almost always involves more calculation operations, so it's slower.
Use paper and pencil to draw it all down (map grid, projection plane, triangulate around with values you have, look how you can minimize setup phase per screen-column-x, as minimum amount of calculation = highest accuracy).
(the answer is quite general, because there's almost no code to check (the code posted looks OK to me)).
Before starting:
A2B10G10R10 (2 bits for the alpha, 10 bits for each color channels)
A8B8G8R8 (8 bits for every channels)
Correct me if I'm wrong, but is it right that the A2B10G10R10 pixel format cannot be displayed directly on screens ?
If so, I would like to convert my A2B10G10R10 image to a displayable A8B8G8R8 one either using OpenCV, Direct3D9 or even manually but I'm really bad when it comes to bitwise operation that's why I need your help.
So here I am:
// Get the texture bits pointer
offscreenSurface->LockRect(&memDesc, NULL, 0);
// Copy the texture bits to a cv::Mat
cv::Mat m(desc.Height, desc.Width, CV_8UC4, memDesc.pBits, memDesc.Pitch);
// Convert from A2B10G10R10 to A8B8G8R8
???
Here how I think I should do for every 32 bits pack:
Copy the first original 2 bits into the first converted 8 bits
Scale every original 10 bits to every converted 8 bits (How to do that ?) for every other channels
Note:
The cv::cvtColor doesn't seem to propose the format conversion I need
I can't use IDirect3DDevice9::StretchRect method
Even Google seems to be lost on this subject
So to resume, the question is:
How to convert a A2B10G10R10 pixel format texture to a A8B8G8R8 one ?
Thanks. Best regards.
I'm not sure why you are using legacy Direct3D 9 instead of DirectX 11. In any case, the naming scheme between Direct3D 9 era D3DFMT and the modern DXGI_FORMAT is flipped, so it can be a bit confusing.
D3DFMT_A8B8G8R8 is the same as DXGI_FORMAT_R8G8B8A8_UNORM
D3DFMT_A2B10G10R10 is the same as DXGI_FORMAT_R10G10B10A2_UNORM
D3DFMT_A8R8G8B8 is the same as DXGI_FORMAT_B8G8R8A8_UNORM
There is no direct equivalent of D3DFMT_A2R10G10B10 in DXGI but you can swap the red/blue channels to get it.
There's also a long-standing bug in the deprecated D3DX9, D3DX10, and D3DX11 helper libraries where the DDS file format DDPIXELFORMAT have the red and blue masks backwards for both 10:10:10:2 formats. My DDS texture readers solve this by flipping the mapping of the masks to the formats on read, and always writing DDS files using the more modern DX10 header where I explicitly use DXGI_FORMAT_R10G10B10A2_UNORM
. See this post for more details.
The biggest problem with converting 10:10:10:2 to 8:8:8:8 is that you are losing 2 bits of data from the R, G, B color channels. You can do a naïve bit-shift, but the results are usually crap. To handle the color conversion where you are losing precision, you want to use something like error diffusion or ordered dithering.
Furthermore for the 2-bit alpha, you don't want 3 (11) to map to 192 (11000000) because in 2-bit alpha 3 "11" is fully opaque while 255 (11111111) is in 8-bit alpha.
Take a look at DirectXTex which is an open source library that does conversions for every DXGI_FORMAT and can handle legacy conversions of most D3DFMT. It implements all the stuff I just mentioned.
The library uses float4 intermediate values because it's built on DirectXMath and that provides a more general solution than having a bunch of special-case conversion combinations. For special-case high-performance use, you could write a direct 10-bit to 8-bit converter with all the dithering, but that's a pretty unusual situation.
With all that discussion of format image conversion out of the way, you can in fact render a 10:10:10:2 texture onto a 8:8:8:8 render target for display. You can use 10:10:10:2 as a render target backbuffer format as well, and it will get converted to 8:8:8:8 as part of the present. Hardware support for 10:10:10:2 is optional on Direct3D 9, but required for Direct3D Feature Level 10 or better cards when using DirectX 11. You can even get true 10-bit display scan-out when using the "exclusive" full screen rendering mode, and Windows 10 is implementing HDR display out natively later this year.
There's a general solution to this, and it's nice to be able to do it at the drop of a hat without needing to incorporate a bulky library, or introduce new rendering code (sometimes not even practical).
First, rip it apart. I can never keep track of which order the RGBA fields are in, so I just try it every way until one works, a strategy which reliably works every time.. eventually. But you may as well trust your analysis for your first attempt. The docs I found said D3D is listing them from MSB to LSB, so in this case we have %AA RRRRRRRRRR GGGGGGGGGG BBBBBBBBBB (but I have no idea if that's right)
b = (src>> 0) & 0x3FF;
g = (src>>10) & 0x3FF;
r = (src>>20) & 0x3FF;
a = (src>>30) & 0x003;
Next, you fix the precision. Naive bit-shift frequently works fine. If the results are 8 bits per channel, you're no worse off than you are with most images. A shift down from 10 bits to 3 would look bad without dithering but from 10 to 8 can look alright.
r >>= 2; g >>= 2; b >>= 2;
Now the alpha component does get tricky because it's shifting the other way. As #chuck-walbourn said you need to consider how you want the alpha values to map. Here's what you probably want:
%00 -> %00000000
%01 -> %01010101
%10 -> %10101010
%11 -> %11111111
Although a lookup table with size 4 probably makes the most sense here, there's a more general way of doing it. What you do is shove your small value to the top of the big value and then replicate it. Here it is with your scenario and one other more interesting scenario:
%Aa -> %Aa Aa Aa Aa
%xyz -> %xyz xyz xy
Let's examine what would happen for xyz with a lookup table:
%000 -> %000 000 00 (0)
%001 -> %001 001 00 (36) +36
%010 -> %010 010 01 (73) +37
%011 -> %011 011 01 (109) +36
%100 -> %100 100 10 (146) +37
%101 -> %101 101 10 (182) +36
%110 -> %110 110 11 (219) +37
%111 -> %111 111 11 (255) +36
As you can see, we get some good characteristics with this approach. Naturally having a %00000000 and %11111111 result is of paramount importance.
Next we pack the results:
dst = (a<<24)|(r<<16)|(g<<8)|(b<<0);
And then we decide if we need to optimize it or look at what the compiler does and scratch our heads.
This may or may not be a very stupid question so I do apologise, but I haven't come across this in any books or tutorials as yet. Also I guess it can apply to any language...
Assume you create a window of size: 640x480 and an object/shape inside it of size 32x32 and you're able to move the shape around the window with keyboard inputs.
Does it matter what Type (int, float...) you use to control the movement of the shape. Obviously you can not draw halfway through a pixel, but if you move the shape by 0.1f (for example with a glTranslation function) what happens as supposed to moving it by an int of 1... Does it move the rendered shape by 1/10 of a pixel or?
I hope I've explained that well enough not to be laughed at.
I only ask this because it can affect the precision of collision detection and other functions of a program or potential game.
glTranslate produces a translation by x y z . The current matrix (glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix, as if glMultMatrix were called with the following matrix for its argument:
1 0 0 x 0 1 0 y 0 0 1 z 0 0 0 1
If the matrix mode is either GL_MODELVIEW or GL_PROJECTION, all objects drawn after a call to glTranslate are translated.
Use glPushMatrix and glPopMatrix to save and restore the untranslated coordinate system.
This meaning that glTranslate will give you a translation, to use with the current matrix, resulting in non decimal numbers. You can not use half a pixel. glTranslate receives either doubles or floats, so if you are supposed to move it 1 in x,y or z, just give the function a float 1 or double 1 as an argument.
http://www.opengl.org/sdk/docs/man2/xhtml/glTranslate.xml
The most important reason for using floats or doubles to represent positioning is the background calculation. If u keep calculating your position with ints not only do you have to probably use conversion steps to get back to ints. You will also lose data every x amount of steps
if you want to animate you sprite to have anything less than 1 pixel movement per update then YES you need to use floating point, otherwise you will get no movement. your drawing function would most likely round to the nearest integer so it's probably not relevant for that. however you can of course draw to sub pixel accuracy!
I drew some quad like this with OpenGL:
_______ _______
| || |
| || |
| || |
|_______||_______|
currently I draw second quad using firstQuad.pos.x + width which is calculated manually.but when I want to scale them in at center point, I was wondering is it the right way to use calculated value, or use glTranslatef one by one, then glTranslatef to center of them, then use glScalef to scale them in? or how to do it right?
Unless you are updating quad's position firstQuad according to your transformations, yes, you will have to use the GL matrix manipulation functions as you described. I'm assuming you are using legacy GL here (2.1 and older), modern releases no longer provide matrix manipulation functions.
What you must understand is that a GL transformation must be seen as a transformation on the base and origin that will be used for further draw calls, until reset to a previous state with glPopMatrix().