gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Texture incorrect when drawn from file different than loaded

#148457 - stevens - Sun Jan 06, 2008 12:40 am

I restructured my program so it's not one big file. Once I did this textures aren't displayed properly. I'm at a loss as to why. I wrote a sample program which shows this behavior.

The program displays two quads one drawn from an inner class and one from an external class. The quad drawn from the inner class (ModelLocal) works fine, but the quad draw from the external class (Model) doesn't.

Any idea what I'm doing wrong?

Thanks!

main.cpp
Code:

#include <nds.h>
#include <nds/arm9/image.h>
#include <stdlib.h>

#include "test_pcx.h"
#include "Model.h"

int texture[1];

class ModelLocal
{
public:
    int texture;
    float tx,ty,tz;
   
    void draw()
    {
        float w = 1.0f;
        float h = 1.0f;
        float l = 1.0f;

        float x = tx - w / 2;
        float y = ty - h / 2;
        float z = tz - l / 2;

        glBindTexture(GL_TEXTURE_2D, texture);
        glColor3f(1.0f,1.0f,1.0f);

        glBegin(GL_QUADS);      
            glTexCoord2f(1.0f, 1.0f); glVertex3f(x+w, y,   z);
            glTexCoord2f(1.0f, 0.0f); glVertex3f(x+w, y+h, z);
            glTexCoord2f(0.0f, 0.0f); glVertex3f(x,     y+h, z);
            glTexCoord2f(0.0f, 1.0f); glVertex3f(x,     y,   z);
        glEnd();
    }

    void init(int text, float x, float y, float z)
    {
        texture = text;
        tx = x;
        ty = y;
        tz = z;
    }

    ModelLocal() {}
};

int loadTexture(const u8* image, int* text, int width, int height)
{
    sImage pcx;

    loadPCX((u8*)image, &pcx);

    image8to16(&pcx);

    glGenTextures(1, text);
    glBindTexture(0, *text);
   
    glTexImage2D(0, 0, GL_RGB, width, height, 0, TEXGEN_TEXCOORD, pcx.image.data8);

    imageDestroy(&pcx);

    return *text;
}
   
Model model;
ModelLocal modelLocal;

void Initialize(void)   
{
    powerON(POWER_ALL);

    videoSetMode(MODE_0_3D);
    vramSetBankA(VRAM_A_TEXTURE);
    vramSetBankB(VRAM_B_TEXTURE);

    irqInit();
    irqSet(IRQ_VBLANK, 0);

    glInit();

    glEnable(GL_TEXTURE_2D);

    glViewport(0,0,255,191);

    glEnable(GL_ANTIALIAS);

    glClearColor(31,31,31,31);
    glClearPolyID(63);
    glClearDepth(GL_MAX_DEPTH);

    loadTexture(test_pcx, &texture[0], TEXTURE_SIZE_128, TEXTURE_SIZE_128);

    model.init(texture[0], -1.0f, 0.0f, -2.0f);
    modelLocal.init(texture[0], 1.0f, 0.0f, -2.0f);
   
    return;
}

void Draw3d()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
   
    gluPerspective(70, 256.0 / 192.0, 0.1, 100);
   
    glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0);
    glLight(1, RGB15(31,31,31) , 0, 0, floattov10(-1.0));
    glLight(2, RGB15(31,31,31) , 0, 0, floattov10(1.0));
   
    glMaterialf(GL_AMBIENT, RGB15(5,5,5));
    glMaterialf(GL_DIFFUSE, RGB15(12,12,19));
    glMaterialf(GL_SPECULAR, BIT(15) | RGB15(21,21,31));
    glMaterialf(GL_EMISSION, RGB15(0,0,0));
   
    glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 | POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2);

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();   

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();   
   
    gluLookAtf32(0, 0, 0, floattof32(0.0f), floattof32(0.0f), floattof32(-1.0f), floattof32( 0), floattof32( 1), floattof32( 0));
   
    model.draw();
    modelLocal.draw();
}

void Draw()
{
    Draw3d();
   
    glFlush(0);

    swiWaitForVBlank();
}

int main()
{
    Initialize();

    while (1)
    {
        Draw();
    }

    return 0;
}


Model.h
Code:

#include <nds.h>

class Model
{
public:
    int texture;
    float tx,ty,tz;
   
    void draw();
    void init(int text, float x, float y, float z);
   
    Model();
};


Model.cpp
Code:

#include <nds.h>
#include <stdlib.h>

#include "Model.h"

void Model::draw()
{
    float w = 1.0f;
    float h = 1.0f;
    float l = 1.0f;

    float x = tx - w / 2;
    float y = ty - h / 2;
    float z = tz - l / 2;

    glBindTexture(GL_TEXTURE_2D, texture);
    glColor3f(1.0f,1.0f,1.0f);

    glBegin(GL_QUADS);      
        glTexCoord2f(1.0f, 1.0f); glVertex3f(x+w, y,   z);
        glTexCoord2f(1.0f, 0.0f); glVertex3f(x+w, y+h, z);
        glTexCoord2f(0.0f, 0.0f); glVertex3f(x,     y+h, z);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(x,     y,   z);
    glEnd();
}
   
void Model::init(int text, float x, float y, float z)
{
    texture = text;
    tx = x;
    ty = y;
    tz = z;   
}
   
Model::Model() {}

#148464 - strager - Sun Jan 06, 2008 2:44 am

Does the code work the same if you comment out the call to one of Model::draw() or ModelLocal::draw()? Will it work if those calls are swapped? What happens if you change the position of the quads (e.g. swap them)?

#148467 - stevens - Sun Jan 06, 2008 3:10 am

strager wrote:
Does the code work the same if you comment out the call to one of Model::draw() or ModelLocal::draw()? Will it work if those calls are swapped? What happens if you change the position of the quads (e.g. swap them)?


Neither the call order or the lack of one or the other effects which will display the texture. The position of the quad doesn't effect it either. ModelLocal is the only one which displays properly.

One thing I should elaborated on, it displays something. It's just not correct. I'm not sure if it's a distorted view of the correct texture or it's displaying the wrong area of memory.

#148714 - stevens - Wed Jan 09, 2008 6:35 am

I have somewhat of a solution to my problem. A few print lines showed me the glGlob global was not initialized in the Model class. If I add

Code:

    glGlob = glGetGlobals();


to Model:init() it works.

Anyone know why I need to do this?

#148732 - elhobbs - Wed Jan 09, 2008 3:49 pm

I think this is because of the definition of glGlob in videogl.h

Code:

// Pointer to global data for videoGL
static gl_hidden_globals* glGlob = 0;


since it is declared as static in the header file a new instance is created for each file that the header is included in. glTexCoord2f should probably not be declared as an inline function in the header file as it would need to be in videogl.c for the the correct instance of glGlob to be used. this function appears to be the only one that references glGlob outside of videogl.c. you would be better off using glTexCoord2t16 anyway and dropping floats all together. however, this should be fixed in libnds.

#148739 - nipil - Wed Jan 09, 2008 5:58 pm

elhobbs wrote:
since it is declared as static in the header file a new instance is created for each file that the header is included in.

I just learnt something here. I'm so used to declare a global variable in one file
and use extern in another to access it, that i never quite realize or wondered
what would happen if i declared it without the extern keyword...
Thanks for the info.

#148772 - stevens - Thu Jan 10, 2008 3:51 am

elhobbs wrote:
you would be better off using glTexCoord2t16 anyway and dropping floats all together. however, this should be fixed in libnds.


I took your advice and converted everything to fixed point. I knew fixed point was faster, but wow I didn't realize how much faster. Thanks!