Jump to content
  • Advertisement
Sign in to follow this  
pi__sec

OpenGL 3D software renderer

This topic is 3029 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


Hey all,

I have been working on a very basic 3D software renderer (I'm new to graphics programming), it is nearing completion but I can't seem to get the pipeline right. It looks like my scene is directed towards the upper left corner of the screen as shown in the image below.

http://yfrog.com/mrscreenshot3denginep

Also the rectangle in the scene seems to be stretched out towards this point.


My current pipeline is (p0, p1 and p2 are 4D vertices), without clipping:

/* initialization etc */

p0 = modelview_matrix * p0;
p1 = modelview_matrix * p1;
p2 = modelview_matrix * p2;

p0 = projection_matrix * p0;
p1 = projection_matrix * p1;
p2 = projection_matrix * p2;

p0.devideByW();
p1.devideByW();
p2.devideByW();

p0.viewport( m_half_width, m_half_height );
p1.viewport( m_half_width, m_half_height );
p2.viewport( m_half_width, m_half_height );

/*draw*/

The lookAt and perspective/frustum functions that I'm using are based upon the opengl versions. I have already tried rewriting them two or three times but keep coming up with the same result. Also the matrices seem to match those in my opengl project.

Here are two of the implementations, I got these two from forums and modified them to fit my project for testing purposes, but seeing as they seem to give the same result and are much easier to understand I will post them.

void Matrix4D::perspective3( const double yfov, const double aspectRatio, const double zNear, const double zFar )
{
const double h = 1.0f/tan(yfov*M_PI_OVER_360);
double neg_depth = zNear-zFar;

m_matrix[0] = h / aspectRatio;
m_matrix[1] = 0;
m_matrix[2] = 0;
m_matrix[3] = 0;

m_matrix[4] = 0;
m_matrix[5] = h;
m_matrix[6] = 0;
m_matrix[7] = 0;

m_matrix[8] = 0;
m_matrix[9] = 0;
m_matrix[10] = (zFar + zNear)/neg_depth;
m_matrix[11] = -1;

m_matrix[12] = 0;
m_matrix[13] = 0;
m_matrix[14] = 2.0f*(zNear*zFar)/neg_depth;
m_matrix[15] = 0;
}

void Matrix4D::setLookAt( double eyeX, double eyeY, double eyeZ,
double centerX, double centerY, double centerZ,
double upX, double upY, double upZ )
{
double f[3], s[3], u[3];

f[0] = centerX - eyeX;
f[1] = centerY - eyeY;
f[2] = centerZ - eyeZ;

double mag = sqrt( f[0]*f[0] + f[1]*f[1] + f[2]*f[2] );
f[0] /= mag;
f[1] /= mag;
f[2] /= mag;

// in my other implementation up is also normalized but this does not matter much
// seeing as up is (0,1,0)

s[0] = f[1]*upZ - f[2]*upY;
s[1] = f[2]*upX - f[0]*upZ;
s[2] = f[0]*upY - f[1]*upX;

mag = sqrt( s[0]*s[0] + s[1]*s[1] + s[2]*s[2] );
s[0] /= mag;
s[1] /= mag;
s[2] /= mag;

u[0] = s[1]*f[2] - s[2]*f[1];
u[1] = s[2]*f[0] - s[0]*f[2];
u[2] = s[0]*f[1] - s[1]*f[0];

m_matrix[0] = s[0];
m_matrix[4] = s[1];
m_matrix[8] = s[2];
m_matrix[12] = 0.0;

m_matrix[1] = u[0];
m_matrix[5] = u[1];
m_matrix[9] = u[2];
m_matrix[13] = 0.0;

m_matrix[2] = -f[0];
m_matrix[6] = -f[1];
m_matrix[10] = -f[2];
m_matrix[14] = 0.0;

m_matrix[3] =
m_matrix[7] =
m_matrix[11] =
m_matrix[15] = 0.0;

translate( -eyeX, -eyeY, -eyeZ );
}

Viewport is written like this, I have tried both the commented and non commented implementations:

void Vertex4D::viewport ( double half_width, double half_height )
{
// m_x = half_width * (m_x+1);
// m_y = half_height * (m_y+1);

m_x = ( half_width * m_x) + ( ( half_width + m_x ) * m_z );
m_y = ( half_height * m_y) + ( ( half_height + m_y ) * m_z );
}


I have also noticed that after my devide by w, my x and y coordinates are often not in between -1 and 1.

void Vertex4D::devideByW()
{
if( m_w ) // if not vector -> if (w!=0)
{
m_x /= m_w;
m_y /= m_w;
m_z /= m_w;
m_w = 1.0;
}
}

For moving around I use the same code I use in my opengl project to alter eye and center positions and it works fine over there, so I guess I don't have to post that.

As I said I'm new to graphics programming so if this turns out to be a stupid mistake, sorry for wasting your time.

If anyone sees it however, please let me know.

Thanks,
pi__sec


Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!