glRotatef backwards in new KGL

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Mon Apr 08, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

glRotatef backwards in new KGL

Post by MisterDave »

Hi PH3NOM

I have recently updated my KOS install to the new codebase with your new KGL for a new project. One thing that I have found when comparing code compiled on PC/Linux compared to the DC is that the rotation direction of glRotatef is backwards on the DC. Could you let me know if this is a possible bug, or intentional please as my initial thought was to reverse the sign in the KGL source? I am attaching a photo to illustrate the effect based on a rotation of glRotatef( 20.0f, 0.0f, 0.0f, 1.0f); after th initial translation in nehe02
Image

So far I have been really impressed with the speed of the new KGL and am looking forward to posting my progress once I resolve this issue.

Thanks,
Dave
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: glRotatef backwards in new KGL

Post by PH3NOM »

Hmm interesting.

My rotation matrix is generated using mat_rotate from KOS, it is possible there are some orientation differences.

Can you test reversing the sign such as glRotatef(-20, 0, 0, 1) and let me know the results?
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
Joined: Mon Apr 08, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by MisterDave »

Thanks PH3NOM.

Please find attached a screenshot of glRotatef(-20.0f, 0.0f, 0.0f, 1.0f) for both PC/Linux (left) and DC (right).

Image

A quick. if a somewhat hacky, fix for this behaviour was to modify gl-matrix.c with the following:

void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
float r = DEG2RAD * angle * -1.0f;
...
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
Joined: Mon Apr 08, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by MisterDave »

Thanks PH3NOM.

Please find attached a screenshot of glRotatef(-20.0f, 0.0f, 0.0f, 1.0f) for both PC/Linux (left) and DC (right).

Image

A quick. if a somewhat hacky, fix for this behaviour was to modify gl-matrix.c with the following:

void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
float r = DEG2RAD * angle * -1.0f;
...
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: glRotatef backwards in new KGL

Post by PH3NOM »

Thanks again for your feedback!

Sorry, but I meant invert your rotations on DC compared to PC for testing orientation correctness.
But yes, what you have said would also perform the same operation.
The simpler way I would do it is
float r = DEG2RAD * -angle;
...

But before modifying GL I would test in your application to invert the sign, to see if that is the only problem with rotations in all directions.

Sorry for any mistakes, and thanks for taking a look!
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
Joined: Mon Apr 08, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by MisterDave »

Sorry, I see what you mean now - I hope this is useful. The attached image shows 20.0 on PC and -20.0 on DC (unpatched):

Image

I had a look at nehe05 with the rotating shapes. Comparing the two versions, I can confirm that the rotation direction is opposite to the PC on DC too.
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: glRotatef backwards in new KGL

Post by PH3NOM »

Okay thank you for the feedback, I guess that is a bug that needs to be fixed in my OpenGL API!

I am curious to see what you are working on :mrgreen:
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
Joined: Mon Apr 08, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by MisterDave »

Apologies for the delay getting back to you on this. I am currently working on a track based space shoot-em-up game with billboard sprites like Galaxy Force or Soulstar. I have attached a picture below which came from a video capture so there is a little bit of bluring. More to come soon once I get back into the swing.

Image
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: glRotatef backwards in new KGL

Post by PH3NOM »

Looks cool, I like the variance in pitch, yaw, and roll you achieve with your tracks.
But I keep thinking it would look better with the "sprites" facing in the direction of their surface normal, instead of facing the camera.

I am curious how you handle batching your sprites, do you use glBegin()/glEnd(), or glDrawArrays(), and what primitives do you use?
GL_QUADS? GL_TRIANGLES?

And thanks again for your feedback!
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
Joined: Mon Apr 08, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by MisterDave »

Thanks PH3NOM. You are very welcome and it is great to be able to make use of the output from your hard work.

At the moment I am using GL_QUADS with glBegin/glEnd, which probably isn't the most efficient option. My understanding is that in order to use glDrawArrays() a mesh would need to be interconnected, which wouldn't work for floating billboard 'sprites'. If I have understood this wrong or if there is a way around the problem then that would be great as I understand that glDrawArrays is really fast in your GL implementation.
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by bogglez »

MisterDave, it is simple to do this.

1. Create a struct Vertex { float u, v, x, y; } with texture coordinates and 2D position on screen.

2. Create an array Vertex sprite_vertices[sprite_max_count * 4] that you will use during your render loop to draw all sprites.

3. glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);

4. Tell GL where the data is
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (char*)sprite_vertices + 2 * sizeof(float)); // skip u, v
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), sprite_vertices);

5. Bind your texture atlas with the sprites glBindTexture(GL_TEXTURE_2D, textureID);

6. glDrawArrays(GL_QUADS, 0, 4 * current_sprite_count);

Here is an example: https://bitbucket.org/bogglez/libgl15/s ... #main.c-45

There is also a special sprite draw mode of the Dreamcast. If you want to render a huge amount of sprites (bullet hell) and run into performance problems it might be worth considering adding that (restricted) Dreamcast sprite drawing mode to OpenGL (add a GL_SPRITES_KGL mode), but it might not be necessary.
Last edited by bogglez on Thu Aug 27, 2015 5:55 am, edited 2 times in total.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
Joined: Mon Apr 08, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by MisterDave »

Thanks bogglez. Does that assume that the same texture is used for all the vertices drawn in glDrawArrays? If so that might not be a problem if a single spritesheet texture is used with individual UV coords.
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by bogglez »

Yes. If you use multiple texture atlases I'd suggest sorting your sprites by texture ID, then counting how many sprites use the same texture id, bind the texture atlas, draw all sprites, repeat.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by bogglez »

By the way, here is my implementation of glRotate.
I'm not using the KOS version but the matrix definition from the specs.
The KOS version calculates sin/cos 3 times, performs 3 matrix multiplications and has different orientation.
I didn't check whether the rotation direction is opposite for the other axes too and just went with my own implementation (unsure whether this is faster since I do some more multiplications in exchange, but it is correct).

Code: Select all

void GLAPIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
	GL_CHECK(GL_INVALID_OPERATION, isImmediateModeActive());

	float s, c;
	fsincos(angle, &s, &c);

	vec3f_normalize(x, y, z);

	float const cinv = 1.f - c;
	float const xs = s * x;
	float const ys = s * y;
	float const zs = s * z;


	float rot[4][4] ALIGN32;
	rot[0][0] = x*x * cinv + c;
	rot[0][1] = y*x * cinv + zs;
	rot[0][2] = x*z * cinv - ys;
	rot[0][3] = 0.f;

	rot[1][0] = x*y * cinv - zs;
	rot[1][1] = y*y * cinv + c;
	rot[1][2] = y*z * cinv + xs;
	rot[1][3] = 0.f;

	rot[2][0] = x*z * cinv + ys;
	rot[2][1] = y*z * cinv - xs;
	rot[2][2] = z*z * cinv + c;
	rot[2][3] = 0.f;

	rot[3][0] = 0.f;
	rot[3][1] = 0.f;
	rot[3][2] = 0.f;
	rot[3][3] = 1.f;

	mat_load(currentMatrix);
	mat_apply(&rot);
	mat_store(currentMatrix);

	onMatrixChanged();
}
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: glRotatef backwards in new KGL

Post by PH3NOM »

MisterDave - Yes, Arrays are more able to be optimized for, and perform much better in my API as a result.
In fact, you can see that I wrote 2 separate clipping algorithms: gl-clip.c and gl-clip-arrays.c, with Arrays being the faster Mode compared to Immediate Mode.
There are a few examples included with my API, look at kos\examples\dreamcast\kgl\basic\zclip_arrays

bogglez - Thanks for pointing that out, my OpenGL API calls mat_rotate(...) from KOS, and that there are differences between the orientation that is used by the KOS function compared to the OpenGL definition. I need to look closer at this.

A crude method I use for testing function efficiency is to run a loop say 10,000,000 times, and measure CPU time spent.
Within that loop, call the function in question; i.e. glRotatef(...).
If your method uses 900 msec while previous method uses 1000 msec, you have made solid progress... :lol:

Also, I am curious how you plan on handling NearZ Clipping, I noticed you have not implemented this in your API?
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by bogglez »

PH3NOM wrote: bogglez - Thanks for pointing that out, my OpenGL API calls mat_rotate(...) from KOS, and that there are differences between the orientation that is used by the KOS function compared to the OpenGL definition. I need to look closer at this.
Yeah, and the mat_perspective function also bit me. It not only performs a perspective projection but also NDC conversion.. I think I'll just get rid of the mat_ functions in the future, since translate and scale are too trivial.
PH3NOM wrote: A crude method I use for testing function efficiency is to run a loop say 10,000,000 times, and measure CPU time spent.
Within that loop, call the function in question; i.e. glRotatef(...).
If your method uses 900 msec while previous method uses 1000 msec, you have made solid progress... :lol:
Yeah, I should do that. But I was just too lazy. An incorrect but fast rotation function is not of much use so I just went with the correct and probably roughly as performant function.
PH3NOM wrote: Also, I am curious how you plan on handling NearZ Clipping, I noticed you have not implemented this in your API?
Recently I'm too busy to work on this (but I'll continue my work in the future), but I had a couple of ideas that change the way glDrawArrays works and I wanted to try those out before I think about clipping.
I was also busy changing the way I build polygon headers first. The "complete recreation of the polygon header by passing a context" method in KOS was wasteful and annoying, since this is a state machine and I just change minor parts of the header anyway.

First idea was that glDrawArrays should just call glMultiDrawArrays, and that one offers more optimization possibilities when performing multiple draws from the same vertex data (set up once, do processing multiple times).

Second I had to realize that there is a huge amount of combinations of enabled vertex attributes and vertex attribute counts (draw 2 or 3 coordinates, 1 or 2 uvs, normal or no normal, with color or without, fog coords etc TIMES various data types like int and float).
My idea here is that I process data not per vertex, but instead per vertex attribute (do normals first, then uvs, then colors, then coord).
Also, since a VAO stores the type of vertex data, it would be possible to determine the proper processing function beforehand and store it in the VAO, which would avoid the check in glMultiDrawArrays. You currently avoid this by not supporting many vertex attributes and combinations.

As commented in a thread about skeletal animation here, I realized it would be possible to add support for vertex data with matrix weights and multiple transformation matrices. This would also work better with the idea above.
I also have yet to add normal matrix support. So that's another reason for writing separate loops for normal matrix, transformation matrix/matrices, color and texture matrix.

It really bugged me to integrate clipping into all of this, when one also has to consider various drawing modes (tristrip, tri, quad, poly, lines). It's probably easier to perform clipping on the transformed and strippified data which will be written to the dest buffer.. With proper visibility checks not much geometry should need clipping enabled and not much geometry should get clipped to begin with. So I doubt it improves performance to perform clipping before transformation and strippification. But maybe you have measurements on that?
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: glRotatef backwards in new KGL

Post by PH3NOM »

bogglez wrote:
PH3NOM wrote: A crude method I use for testing function efficiency is to run a loop say 10,000,000 times, and measure CPU time spent.
Within that loop, call the function in question; i.e. glRotatef(...).
If your method uses 900 msec while previous method uses 1000 msec, you have made solid progress... :lol:
Yeah, I should do that. But I was just too lazy. An incorrect but fast rotation function is not of much use so I just went with the correct and probably roughly as performant function.
About your implementation, are you sure the vector should be normalized by the API?
I thought that would only be the case if GL_NORMALIZE is enabled...?
Here is a quick update to your function, saving 6xFMUL, 6xFLDI0, and 1xFLDI1 instruction per function call:
Spoiler!

Code: Select all

#include <dc/matrix.h>

static matrix_t mat_rot __attribute__((aligned(32))) = {
    { 0.0f, 0.0f, 0.0f, 0.0f },
    { 0.0f, 0.0f, 0.0f, 0.0f },
    { 0.0f, 0.0f, 0.0f, 0.0f },
    { 0.0f, 0.0f, 0.0f, 1.0f }
};

void GLAPIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
   GL_CHECK(GL_INVALID_OPERATION, isImmediateModeActive());

   float s, c;
   fsincos(angle, &s, &c);
    
   if(GL_ENABLE_NORMALIZE) 
       vec3f_normalize(x, y, z);

   float const cinv = 1.f - c;
   float const xs = s * x;
   float const ys = s * y;
   float const zs = s * z;
   
   float const xycinv = x * y * cinv;
   float const xzcinv = x * z * cinv;
   float const yzcinv = y * z * cinv;
   
   mat_rot[0][0] = x*x * cinv + c;
   mat_rot[0][1] = xycinv + zs;
   mat_rot[0][2] = xzcinv - ys;

   mat_rot[1][0] = xycinv - zs;
   mat_rot[1][1] = y*y * cinv + c;
   mat_rot[1][2] = yzcinv + xs;

   mat_rot[2][0] = xzcinv + ys;
   mat_rot[2][1] = yzcinv - xs;
   mat_rot[2][2] = z*z * cinv + c;

   mat_load(currentMatrix);
   mat_apply(&mat_rot);
   mat_store(currentMatrix);

   onMatrixChanged();
}
bogglez wrote:Recently I'm too busy to work on this (but I'll continue my work in the future), but I had a couple of ideas that change the way glDrawArrays works and I wanted to try those out before I think about clipping.
I was also busy changing the way I build polygon headers first. The "complete recreation of the polygon header by passing a context" method in KOS was wasteful and annoying, since this is a state machine and I just change minor parts of the header anyway.

First idea was that glDrawArrays should just call glMultiDrawArrays, and that one offers more optimization possibilities when performing multiple draws from the same vertex data (set up once, do processing multiple times).

Second I had to realize that there is a huge amount of combinations of enabled vertex attributes and vertex attribute counts (draw 2 or 3 coordinates, 1 or 2 uvs, normal or no normal, with color or without, fog coords etc TIMES various data types like int and float).
My idea here is that I process data not per vertex, but instead per vertex attribute (do normals first, then uvs, then colors, then coord).
Also, since a VAO stores the type of vertex data, it would be possible to determine the proper processing function beforehand and store it in the VAO, which would avoid the check in glMultiDrawArrays. You currently avoid this by not supporting many vertex attributes and combinations.

It really bugged me to integrate clipping into all of this, when one also has to consider various drawing modes (tristrip, tri, quad, poly, lines). It's probably easier to perform clipping on the transformed and strippified data which will be written to the dest buffer.. With proper visibility checks not much geometry should need clipping enabled and not much geometry should get clipped to begin with. So I doubt it improves performance to perform clipping before transformation and strippification. But maybe you have measurements on that?
About polygon headers, I use the vertex buffer to store them, so they need to be created anew every time used.
Do you have some benchmarks to show how "wasteful" they really are? I do like your code to update the state, so I am curious...

You can see that the method I use is per component processing for array submission.
Per vertex processing is used for immediate mode.

Clipping requires much thought!
My solution performs triangle clipping after all vertex components besides position are prepared, regardless of primitive type being submitted.
Position Transform becomes a final pass before submitting the vertex data to the PVR.
Position component is transformed into a custom type-casted pvr vertex type named pvr_clip_vertex_t that uses the oargb component of the pvr_vertex_t structure to store the vertex position w component.
If triangle is inside of the clipping field, the vertices will then be clipped and have perspective division applied using the w component of the pvr_clip_vertex_t.
Otherwise, the triangle will not be submitted, and perspective division will not be applied 8-)
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by bogglez »

PH3NOM wrote: About your implementation, are you sure the vector should be normalized by the API?
I thought that would only be the case if GL_NORMALIZE is enabled...?
In the man page it said, below the matrix definition:
Where c = cos(angle), s = sin(angle) and ||(x, y, z)|| = 1 (if not, the GL will normalize this vector).
I also checked the spec, which says the same thing (input vector v, u = v / ||v||, uses u in matrix definition). No mention of NORMALIZE.

The man page says about NORMALIZE:
GL_NORMALIZE

If enabled and no vertex shader is active, normal vectors are normalized to unit length after transformation and before lighting. This method is generally less efficient than GL_RESCALE_NORMAL. See glNormal and glNormalPointer.
So it seems to be limited to normals for lighting.
PH3NOM wrote: Here is a quick update to your function, saving 6xFMUL, 6xFLDI0, and 1xFLDI1 instruction per function call:
Spoiler!

Code: Select all

#include <dc/matrix.h>

static matrix_t mat_rot __attribute__((aligned(32))) = {
    { 0.0f, 0.0f, 0.0f, 0.0f },
    { 0.0f, 0.0f, 0.0f, 0.0f },
    { 0.0f, 0.0f, 0.0f, 0.0f },
    { 0.0f, 0.0f, 0.0f, 1.0f }
};

void GLAPIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
   GL_CHECK(GL_INVALID_OPERATION, isImmediateModeActive());

   float s, c;
   fsincos(angle, &s, &c);
    
   if(GL_ENABLE_NORMALIZE) 
       vec3f_normalize(x, y, z);

   float const cinv = 1.f - c;
   float const xs = s * x;
   float const ys = s * y;
   float const zs = s * z;
   
   float const xycinv = x * y * cinv;
   float const xzcinv = x * z * cinv;
   float const yzcinv = y * z * cinv;
   
   mat_rot[0][0] = x*x * cinv + c;
   mat_rot[0][1] = xycinv + zs;
   mat_rot[0][2] = xzcinv - ys;

   mat_rot[1][0] = xycinv - zs;
   mat_rot[1][1] = y*y * cinv + c;
   mat_rot[1][2] = yzcinv + xs;

   mat_rot[2][0] = xzcinv + ys;
   mat_rot[2][1] = yzcinv - xs;
   mat_rot[2][2] = z*z * cinv + c;

   mat_load(currentMatrix);
   mat_apply(&mat_rot);
   mat_store(currentMatrix);

   onMatrixChanged();
}
Oops, I completely missed x*y == y * x :-D
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: glRotatef backwards in new KGL

Post by PH3NOM »

I double checked this morning, and yes the rotations have been corrected in the current commit, by simply reversing the sign of the rotation angle as mentiond; trick is OpenGL rotations are counter-clockwise, and the mat_rotate code in KOS rotates clockwise :o .

The texture used here is taken from the Nvida CG tutorial, and demonstrates the new ability for OpenGL to convert textures for use with the PVR, when they are not supplied in a pixel format that is supported directly by the PVR.

Code: Select all

glRotatef(xrot, 1.0f, 0.0f, 0.0f);
Image

Code: Select all

glRotatef(yrot, 0.0f, 1.0f, 0.0f);
Image

Code: Select all

glRotatef(zrot, 0.0f, 0.0f, 1.0f);
Image

BTW bogglez-
The input angle is in degrees, but the DC's math functions operate on radians, I did not see your code account for that?
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: glRotatef backwards in new KGL

Post by bogglez »

PH3NOM wrote: BTW bogglez-
The input angle is in degrees, but the DC's math functions operate on radians, I did not see your code account for that?
That's not true. There are degree and radians based functions in fmath.h.
I use fsincos, which is based on degrees. fsincosr uses radians. Both of them do a conversion to some internal measure by performing a multiplication, so it would be wasteful to do the conversion ourselves.
Spoiler!

Code: Select all

/** \brief  Calculate the sine and cosine of a value in degrees.

    This function uses the fsca instruction to calculate an approximation of the
    sine and cosine of the input value.

    \param  f               The value to calculate the sine and cosine of.
    \param  s               Storage for the returned sine value.
    \param  c               Storage for the returned cosine value.
*/
__FMINLINE void fsincos(float f, float *s, float *c) {
    __fsincos(f, *s, *c);
}

/** \brief  Calculate the sine and cosine of a value in radians.

    This function uses the fsca instruction to calculate an approximation of the
    sine and cosine of the input value.

    \param  f               The value to calculate the sine and cosine of.
    \param  s               Storage for the returned sine value.
    \param  c               Storage for the returned cosine value.
*/
__FMINLINE void fsincosr(float f, float *s, float *c) {
    __fsincosr(f, *s, *c);
}


fmath_base.h:
Spoiler!

Code: Select all

#define __fsincos(r, s, c) \
    ({  register float __r __asm__("fr10") = r; \
        register float __a __asm__("fr11") = 182.04444443; \
        __asm__("fmul fr11, fr10\n\t" \
                "ftrc fr10, fpul\n\t" \
                "fsca fpul, dr10\n\t" \
                : "+f" (__r), "+f" (__a) \
                : "0" (__r), "1" (__a) \
                : "fpul"); \
        s = __r; c = __a; })

#define __fsincosr(r, s, c) \
    ({  register float __r __asm__("fr10") = r; \
        register float __a __asm__("fr11") = 10430.37835; \
        __asm__("fmul fr11, fr10\n\t" \
                "ftrc fr10, fpul\n\t" \
                "fsca fpul, dr10\n\t" \
                : "+f" (__r), "+f" (__a) \
                : "0" (__r), "1" (__a) \
                : "fpul"); \
        s = __r; c = __a; })
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Post Reply