You are not logged in.

#1 2008-07-30 01:07:44

woogal
Member

hardcoded 480 height

In GRRLIB_Start, shouldn't the line

Code:

guOrtho(perspective,0,479,0,639,0,300);

read something like

Code:

guOrtho(perspective,0,rmode->efbHeight-1,0,639,0,300);

instead for PAL users? On my PAL TV I noticed I was getting slightly rectangular shapes instead of squares which I put down to my TV being a bit old and crap, but then when I tried taking a screengrab and drawing it back again it became clear that something was wrong because the image was stretched vertically. Changing the line above has fixed it for me, but I'm new to libogc/gx so I've got no idea if I've done things the right way or not, or if it should be efbheight, xfbheight, or viheight smile

Offline

 

#2 2008-07-30 01:24:24

RedShade
Member

Re: hardcoded 480 height

The issue with that is that you will have different parts of your game visible depending on what TV the program is running on. I suppose there could be a switch triggered at that point in the code that will resize the projection matrix to fit differently depending on the TV.

Offline

 

#3 2008-08-07 08:12:31

CarstenK
Member

Re: hardcoded 480 height

RedShade wrote:

The issue with that is that you will have different parts of your game visible depending on what TV the program is running on. I suppose there could be a switch triggered at that point in the code that will resize the projection matrix to fit differently depending on the TV.

I could be mistaken, I think PAL developers just should avoid drawing in the top and bottom 50 pixels or so to make sure it will be visible on NTSC screens. That's not much really when you remember you probably want to avoid the screen edges anyway to keep clear of overscan.

Also, I think it really should be 480 and not 479. In this demo I draw some concentric circles centred at 320,240. You will notice a "tearing" effect about 1/6 way down the top of the screen. This artifact disappears when you set guOrtho height to 640 instead of 639 (or just use rmode->efbHeight).

Code:

    guOrtho(perspective,0,rmode->efbHeight,0,rmode->fbWidth,0,300); //ptblr

(Also I am not clear either, whether it should be efbheight, xfbheight, or viheight because I haven't studied the GRRLIB code much yet, but that is besides the point. It looks like something is "off by 1", either in GRRLIB or in libogc gx.c/gu.c).

Try this main.c, then modify your GRRLIB 3.0.1a to use 480 instead of 479 and the "tearing" goes away. (Hint: Press HOME to exit)

Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>
#include <unistd.h>

#include "GRRLIB/GRRLIB.h"

int gohome = 0;
Mtx GXmodelView2D;

/* http://www.inversereality.org/tutorials/graphics%20programming/circles.html
   http://groups.csail.mit.edu/graphics/classes/6.837/F98/Lecture6/circle.html
 */

void _CirclePoints (s32 cx, s32 cy, s32 x, s32 y, u32 c)
{
    if (x == 0)
    {
        GRRLIB_Plot(cx, cy+y, c);
        GRRLIB_Plot(cx, cy-y, c);
        GRRLIB_Plot(cx+y, cy, c);
        GRRLIB_Plot(cx-y, cy, c);
    }
    else if (x == y)
    {
        GRRLIB_Plot(cx+x, cy+y, c);
        GRRLIB_Plot(cx-x, cy+y, c);
        GRRLIB_Plot(cx+x, cy-y, c);
        GRRLIB_Plot(cx-x, cy-y, c);
    }
    else if (x < y)
    {
        GRRLIB_Plot(cx+x, cy+y, c);
        GRRLIB_Plot(cx-x, cy+y, c);
        GRRLIB_Plot(cx+x, cy-y, c);
        GRRLIB_Plot(cx-x, cy-y, c);
        GRRLIB_Plot(cx+y, cy+x, c);
        GRRLIB_Plot(cx-y, cy+x, c);
        GRRLIB_Plot(cx+y, cy-x, c);
        GRRLIB_Plot(cx-y, cy-x, c);
    }
}

void Circle (s32 xcenter, s32 ycenter, s32 radius, u32 color)
{
    s32 x = 0;
    s32 y = radius;
    s32 p = (5 - radius*4)/4;
    _CirclePoints(xcenter, ycenter, x, y, color);
    while (x < y)
    {
        x++;
        if (p < 0)
        {
            p += 2*x+1;
        }
        else
        {
            y--;
            p += 2*(x-y)+1;
        }
        _CirclePoints(xcenter, ycenter, x, y, color);
    }
}

void draw_screen()
{
    static s32 xcenter = 320;
    static s32 ycenter = 240;
    static s32 radius = 100;
    static u32 color = 0xFFFFFFFF;
    
    f32 rectw = 480;
    f32 recth = 480;
    GRRLIB_Rectangle(xcenter-rectw/2, ycenter-recth/2, rectw, recth, color, 0);// l t r b
    Circle (xcenter, ycenter, radius, color);
    rectw = 640;
    recth = 640;
    GRRLIB_Rectangle(xcenter-rectw/2, ycenter-recth/2, rectw, recth, color, 0);// l t r b
    
    u16 r;
    for(r=240;r<=320;r=r+20)
    {
        Circle (xcenter, ycenter, r, color);
    }
    Circle (xcenter, ycenter, 426, color);

    
}

void clear_screen()
{
    GRRLIB_FillScreen(0xFF000000);
    GRRLIB_Render();
}

void fade_screen()
{
    u16 i;
    int step = 8;
    for(i=1;i<255;i=i+step)
    {
        draw_screen();
        GRRLIB_FillScreen(i<<24);
        GRRLIB_Render();
    }
    GRRLIB_FillScreen(0xFF000000);
    GRRLIB_Render();
}

void check_wiimote()
{
    int res;
    u32 type;
    WPADData *wd;

    WPAD_ReadPending(WPAD_CHAN_ALL, 0 /*countevs*/);
    res = WPAD_Probe(0, &type);
    if (res == WPAD_ERR_NONE)
    {
        wd = WPAD_Data(0);
        if (wd->btns_h & WPAD_BUTTON_HOME)
        {
            gohome = 1;
        }
    }
}


void goodbye()
{
    fade_screen();
    //blink_dvd_led()
}


int main(int argc, char **argv) {
    
    VIDEO_Init();
    WPAD_Init();
    
    GRRLIB_InitVideo();
    GRRLIB_Start();
    
    while (!gohome)
    {
        draw_screen();
        GRRLIB_Render();

        check_wiimote();
    }
    goodbye();
    return 0;
}

On the subject of circles, this code does not produce a "circle" on my NTSC TV, rather an oval too tall. The circle code is correct, you can see I even cross-checked it by drawing a square and measuring with a ruler. I used devkitPPC release 15 with libogc 20080602. The TV is LCD so I know it's not a calibration issue due to old CRT.

I am curious, how does this look for other NTSC users or PAL for that matter?

Thanks

Last edited by CarstenK (2008-08-07 08:14:32)

Offline

 

#4 2008-08-07 17:43:52

RedShade
Member

Re: hardcoded 480 height

It's purely virtually related. The projection matrix is only the values stated so that 3.0 code would be even remotely related to previous versions.

Orthographic projection means "Show this area of the 3D world, and don't taper off the images as they get farther from the camera."

The values chosen were to get the resulting images to match 1.6 as closely as NoNameNo and I could. I use

Code:

guOrtho(perspective,50,-50,-,66.666, 66.666,0,300);

I think you might be able to do the dynamic switching using:

Code:

f32 correction = (xfbHeight-480)/2;
guOrtho(perspective,-correction,479.0f+correction,0.0f,639.0f,0.0f,300.0f);

Also, remember that the projection matrix is supposed to be Mtx44, not Mtx (I noted this in one of the other posts as well)

Offline

 

#5 2008-08-07 23:04:47

CarstenK
Member

Re: hardcoded 480 height

I managed to get perfect circles now (using NTSC, component cables):

Code:

//f32 vcorrection = (rmode->xfbHeight-(rmode->xfbHeight/1.125f))/2;
f32 vcorrection = (rmode->xfbHeight-426)/2; //fudge factor
f32 hcorrection = 0.0f;
if( CONF_GetAspectRatio() ) {
    hcorrection = (rmode->xfbHeight-(9.0f*rmode->xfbHeight/16.0f))/2;
}
guOrtho(orthographic,0.0f-vcorrection,rmode->xfbHeight+vcorrection,
    0.0f-hcorrection,rmode->fbWidth+hcorrection,0.0f,300.0f); //tblr

(Code could be modified to check whether the programmer wants to respect the machine's widescreen setting or not. Also GRRLIB_FillScreen would need to be updated, it doesn't properly clear the screen edges when using this.)

Would someone with PAL try this, do you need to modify the "fudge factor" to get perfect circles?

Offline

 

Board footer

Powered by FluxBB