glDrawTexfOES Problem

This topic contains 8 replies, has 5 voices, and was last updated by  Stuart Neilson 7 years ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #29982

    nak
    Member

    Hi, all.

    Firstly, I am Japanes, so I am not good at English, sorry.

    I develop a graphics porgram using OGLES-1.1_WINDOWS_PCEMULATION_2.05.25.0804 on WindowsXP.
    And, I have a problem.
    I can draw a sprite using glDrawTexfOES when format of texture is GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG or GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG.
    But, the program hung when format of texture is not GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG or GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG.

    Is there someone who have same problem?

    A test code is below.



    #include <windows.h>
    #include <assert.h>
    #include <GLES/gl.h>
    #include <EGL/egl.h>

    #include “PVRTglesExt.h”
    #include “PVRTTexture.h”

    #ifndef VRETURN
    #define VRETURN(b)    if(!(b)) { assert(false); return false; }
    #endif

    #define _READ(fp, b, size)    VRETURN(fread(b, 1, size, fp) == size);
    #define _SKIP(fp, offset)    VRETURN(fseek(fp, offset, SEEK_CUR) == 0);

    namespace {
        // Get configs
        inline bool _GetConfigs(
            const PVR_Texture_Header& header,
            GLenum* format,
            GLenum* type,
            int* bpp)
        {
            bool ret = true;

            PVRTuint32 fmt = header.dwpfFlags & PVRTEX_PIXELTYPE;

            switch (fmt) {
            case OGL_RGBA_4444:
                *format = GL_RGBA;
                *type = GL_UNSIGNED_SHORT_4_4_4_4;
                *bpp = 2;
                break;
            case OGL_RGBA_8888:
                *format = GL_RGBA;
                *type = GL_UNSIGNED_BYTE;
                *bpp = 4;
                break;
            case OGL_RGB_565:
                *format = GL_RGB;
                *type = GL_UNSIGNED_SHORT_5_6_5;
                *bpp = 2;
                break;
            case OGL_PVRTC2:
                *format = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
                *type = GL_UNSIGNED_BYTE;    // Not use
                *bpp = 0;    // Not use
                break;
            case OGL_PVRTC4:
                *format = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
                *type = GL_UNSIGNED_BYTE;    // Not use
                *bpp = 0;    // Not use
                break;
            case OGL_RGBA_5551:
            case OGL_RGB_555:
            case OGL_RGB_888:
            case OGL_I_8:
            case OGL_AI_88:
                // TODO
                assert(false);
                ret = false;
                break;
            }

            return ret;
        }

        // Return whether compressed format
        inline bool _IsComressedFormat(const PVR_Texture_Header& header)
        {
            PVRTuint32 fmt = header.dwpfFlags & PVRTEX_PIXELTYPE;

            bool ret = ((fmt == OGL_PVRTC2)
                        || (fmt == OGL_PVRTC4));

            return ret;
        }

        // Get biyesize
        inline unsigned int _GetBytes(
            const PVR_Texture_Header& header,
            PVRTuint32 width,
            PVRTuint32 height)
        {
            unsigned int ret = 0;

            if (_IsComressedFormat(header)) {
                PVRTuint32 fmt = header.dwpfFlags & PVRTEX_PIXELTYPE;

                if (fmt == OGL_PVRTC2) {
                    ret = (PVRT_MAX(width, PVRTC2_MIN_TEXWIDTH) * PVRT_MAX(height, PVRTC2_MIN_TEXHEIGHT) * header.dwBitCount + 7) / 8;
                }
                else {
                    ret = (PVRT_MAX(width, PVRTC4_MIN_TEXWIDTH) * PVRT_MAX(height, PVRTC4_MIN_TEXHEIGHT) * header.dwBitCount + 7) / 8;
                }
            }
            else {
                ret = (width * height * header.dwBitCount + 7) / 8;
            }

            return ret;
        }

        struct SPvr {
            int width;
            int height;
            unsigned int size;
            int bpp;
            GLenum format;
            GLenum type;
            void* data;
            GLuint name;

            SPvr()
            {
                width = 0;
                height = 0;
                size = 0;
                bpp = 0;
                format = 0;
                type = 0;
                data = NULL;
                name = 0;
            }
            ~SPvr() { Clear(); }

            void Clear()
            {
                if (data != NULL) {
                    free(data);
                }

                if (name > 0) {
                    glDeleteTextures(1, &name);
                }

                width = 0;
                height = 0;
                size = 0;
                bpp = 0;
                format = 0;
                type = 0;
                data = NULL;
                name = 0;
            }
        };

        class CFilePtr {
        public:
            CFilePtr(FILE* fp) { m_FP = fp; }
            ~CFilePtr()
            {
                if (m_FP != NULL) {
                    fclose(m_FP);
                }
            }

        private:
            FILE* m_FP;
        };

        bool _ReadPvr(
            const char* path,
            SPvr* pvr)
        {
            FILE* fp = fopen(path, “rb”);
            CFilePtr filePtr(fp);
            VRETURN(fp != NULL);

            PVR_Texture_Header header;
            _READ(fp, &header, sizeof(header));

            // Check error
            {
                VRETURN(header.dwPVR == PVRTEX_IDENTIFIER);

                VRETURN(
                    (header.dwHeaderSize == sizeof(header))
                    && (header.dwNumSurfs > 0));

                // Only accept untwiddled data UNLESS texture format is PVRTC
                VRETURN(
                    !(((header.dwpfFlags & PVRTEX_TWIDDLE) == PVRTEX_TWIDDLE)
                        && ((header.dwpfFlags & PVRTEX_PIXELTYPE) != OGL_PVRTC2)
                        && ((header.dwpfFlags & PVRTEX_PIXELTYPE) != OGL_PVRTC4)));

                // Prohibit cubemap
                VRETURN(
                    ((header.dwpfFlags & PVRTEX_CUBEMAP) == 0)
                    && (header.dwNumSurfs == 1));
            }

            // Get configs
            VRETURN(_GetConfigs(
                        header,
                        &pvr->format,
                        &pvr->type,
                        &pvr->bpp));

            pvr->width = header.dwWidth;
            pvr->height = header.dwHeight;

            // Texture size
            pvr->size = _GetBytes(header, header.dwWidth, header.dwHeight);
            VRETURN(pvr->size > 0);

            // Alloc buffer
            pvr->data = malloc(pvr->size);
            VRETURN(pvr->data != NULL);

            // Read pixels
            _READ(fp, pvr->data, pvr->size);

            // TODO
            // mipmap

            return true;
        }
    }    // namespace

    namespace {
        bool _isPVRCompressedFormat(GLenum format)
        {
            return ((format == GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG)
                    || (format == GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG));
        }

        SPvr* s_pPvr = NULL;
    }    // namespace

    #define VGOTO(b, label)    if (!(b)) { assert(false); goto label; }

    bool init()
    {
        s_pPvr = new SPvr;
        
        bool ret = _ReadPvr(“data/foo.pvr”, s_pPvr);
        VGOTO(ret, __EXIT__);

        GLenum format = s_pPvr->format;
        GLenum type = s_pPvr->type;

        glGenTextures(1, &s_pPvr->name);
        ret = (s_pPvr->name > 0);
        VGOTO(ret, __EXIT__);

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, s_pPvr->name);

        if (_isPVRCompressedFormat(format)) {
            int w = s_pPvr->width;
            int h = s_pPvr->height;
            int size = s_pPvr->size;

            glCompressedTexImage2D(
                GL_TEXTURE_2D,
                0,
                format,
                w,
                h,
                0,
                size,
                s_pPvr->data);
        }
        else {
            int w = s_pPvr->width;
            int h = s_pPvr->height;

            glPixelStorei(GL_UNPACK_ALIGNMENT, s_pPvr->bpp);

            glTexImage2D(
                GL_TEXTURE_2D,
                0,
                format,
                w,
                h,
                0,
                format,
                type,
                s_pPvr->data);
        }

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    __EXIT__:
        return ret;
    }

    namespace {
        void _Ortho(
            GLfloat left, GLfloat right, GLfloat bottom, GLfloat top,
            GLfloat fNear, GLfloat fFar)
        {
            GLfloat mat[16];

            memset(mat, 0, sizeof(mat));

            mat[0] = 2 / (right – left);
            mat[5] = 2 / (top – bottom);
            mat[10] = 2 / (fNear – fFar);
            mat[15] = 1;

            mat[12] = (right + left) / (left – right);
            mat[13] = (top + bottom) / (bottom – top);
            mat[14] = (fFar + fNear) / (fNear – fFar);

            glMultMatrixf(mat);
        }

        void _drawRect(
            int x, int y,
            int width,
            int height)
        {
            struct SVtx {
                GLfloat pos[2];
                GLfloat uv[2];
                int color;
            };
            SVtx vtx[4];

            vtx[0].uv[0] = 0.0f;
            vtx[0].uv[1] = 0.0f;

            vtx[1].uv[0] = 0.0f;
            vtx[1].uv[1] = 1.0f;

            vtx[2].uv[0] = 1.0f;
            vtx[2].uv[1] = 0.0f;

            vtx[3].uv[0] = 1.0f;
            vtx[3].uv[1] = 1.0f;

            vtx[0].color = 0xffffffff;
            vtx[1].color = 0xffffffff;
            vtx[2].color = 0xffffffff;
            vtx[3].color = 0xffffffff;

            unsigned char* p = reinterpret_cast<unsigned char*>(vtx);

            static const int OFFSET_VTX_POS = 0;
            static const int OFFSET_VTX_UV = sizeof(GLfloat) * 2;
            static const int OFFSET_VTX_CLR = sizeof(GLfloat) * 4;

            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            glEnableClientState(GL_COLOR_ARRAY);

            glVertexPointer(2, GL_FLOAT, sizeof(SVtx), p + OFFSET_VTX_POS);
            glTexCoordPointer(2, GL_FLOAT, sizeof(SVtx), p + OFFSET_VTX_UV);
            glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(SVtx), p + OFFSET_VTX_CLR);
       
            vtx[0].pos[0] = x;
            vtx[0].pos[1] = y;

            vtx[1].pos[0] = x;
            vtx[1].pos[1] = y + height;

            vtx[2].pos[0] = x + width;
            vtx[2].pos[1] = y;

            vtx[3].pos[0] = x + width;
            vtx[3].pos[1] = y + height;
           
            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        }

        typedef void (APIENTRY * PFNGLDRAWTEXFOES) (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
        PFNGLDRAWTEXFOES glDrawTexfOES = NULL;

        void _drawSprite(
            int screenH,
            const GLint* rcSrc,
            const GLint* rcDst)
        {
            if (glDrawTexfOES == NULL) {
                glDrawTexfOES = (PFNGLDRAWTEXFOES)eglGetProcAddress(“glDrawTexfOES”);
            }

            glDisableClientState(GL_VERTEX_ARRAY);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            glDisableClientState(GL_COLOR_ARRAY);

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

            glMatrixMode(GL_TEXTURE);
            glLoadIdentity();
            glScalef(-1.0f, -1.0f, 0.0f);

            glEnable(GL_TEXTURE_2D);

            glTexParameteriv(
                GL_TEXTURE_2D,
                GL_TEXTURE_CROP_RECT_OES,
                rcSrc);

            GLfloat w = rcDst[2];
            GLfloat h = rcDst[3];
            GLfloat x = rcDst[0];
            GLfloat y = screenH – rcDst[1] – h;

            (*glDrawTexfOES)(
                x, y, 0.0f,
                w, h);
        }
    }    // namespace

    void doFrame(int w, int h)
    {
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        _Ortho(0, w, h, 0, -1, 1);

        glMatrixMode(GL_TEXTURE);
        glLoadIdentity();

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glViewport(0, 0, w, h);

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, s_pPvr->name);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    #if 0
        _drawRect(100, 100, 128, 128);
    #else
        GLint rcSrc[] = {
            0, 0,
            s_pPvr->width,
            s_pPvr->height,
        };
        GLint rcDst[] = {
            100, 100,
            128, 128,
        };

        _drawSprite(
            h,
            rcSrc,
            rcDst);
    #endif
    }

    void end()
    {
        if (s_pPvr != NULL) {
            delete s_pPvr;
        }
    }


    Regards.

    #33527

    Gordon
    Moderator

    Do the demos and training courses from the SDK run successfully for you? If they do not then there may be a problem with PVRVFrame on your system.

    I can’t see anything immediately wrong with your code. When you say “hung” what do you mean? Does the application crash out – if so after which line above?

    #33528

    nak
    Member

    Hi, Gordon.

    Thank you for your reply.

    My program hungs below code

    glTexParameteriv(
                GL_TEXTURE_2D,
                GL_TEXTURE_CROP_RECT_OES,
                rcSrc);

    When texture format is not GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG or GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, my program hungs.

    I will try the demos and training courses in the SDK again.

    Regards.

    #33529

    Gordon
    Moderator

    Ok – I spoke to the engineer who works on PVRVFrame and he says that this issue has come up previously with another developer and is fixed for the next major release in the new year. We should have a version available sooner that will include the fix so please check for updates, however.

    #33530

    nak
    Member

    Hi, Gordon.

    I look forward to new update at the new year.
    Thank you.

    Regards.

    #33531

    zerosoft
    Member

    zerosoft2009-12-10 17:49:01

    #33532

    Xmas
    Member
    zerosoft wrote:
    I noticed that you have assigned wrong values for texture format and texture type for the first 3 cases.

    The original code is correct.

    #33533

    zerosoft
    Member

    sorry my mistake..

    nak, disregard my previous commentzerosoft2009-12-10 16:58:30

    #33534

    I thinks that it is too difficult for me to understand . But I will try !!!!

    chieuhado2010-10-19 08:23:30

Viewing 9 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic.