UV Mapping with large Pictures

Hello,
i want to make this UV Mapping with large Picture (640 x 640.000).
When I try picture 400 x 4.000 everthing goes well, but if I try 400 x 40.000 I got this message:
A Basecode Error Occurred While Creating The Application’s Form:
Stack Trace: in CsGL.OpenGL.OpenGLExceptions.Assert() in CsGL.Basecode.App.CreateForm()

Any suggestions?

Here is my Code LoadTextures():

string filename = @"uvtestbild00001.png";

Bitmap bitmap = null;
Rectangle rectangle;
BitmapData bitmapData = null;

bitmap = new Bitmap(filename);
rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, (int)GL_RGB8, bitmap.Width, bitmap.Height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, bitmapData.Scan0);

and here Draw():

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                glLoadIdentity();

                glTranslatef(0.0f, 0.0f, -5.0f);

                breite_bild = 1 / anzahl_bild;
                position_bild = breite_bild * Convert.ToInt64( Math.Round(zaehler_bild));
                glBegin(GL_QUADS);

                glTexCoord2f(position_bild + breite_bild, 1f);
                glVertex3f(0.5f, 0.5f, 1.0f);

                glTexCoord2f(position_bild, 1f);
                glVertex3f(-0.5f, 0.5f, 1.0f);

                glTexCoord2f(position_bild, 0f);
                glVertex3f(-0.5f, -0.5f, 1.0f);

                glTexCoord2f(position_bild + breite_bild, 0f);
                glVertex3f(0.5f, -0.5f, 1.0f);

                glEnd();
                zaehler_bild += 0.5F;

my suggestion is that i don’t understand why 400x4.00 is first integer second float? by the looks it should be weird because those are not power of two values. 4.000 is, 40.000 not, 400 neither. also whats that CsGL code? never encountered and somewhat curious.

sorry, both are integer, I just make a dot after thousand.

doesn’t make any sense that 400x4000 works properly. should be slow at least. GL_TEXTURE_2D only supports power of two values (8,16,32,64,128,256,512,1024,…). for non power of two textures there are rect textures.

check for more info on that exception.

I’m not able to find anthing usefull, but I’m searching further :wink:
I Post the whole code, maybe someone has an idea.

//using CsGL.OpenGL;
using CsGL.Basecode;
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Windows.Forms;

namespace Holomachine
{
    class my_openGL : Model
    {
        // TODO
        // Variabeln vom Programm bestimmen lassen


        Boolean UVMapping = true;
        float breite_bild = 400;
        //Breite einer Einzelgrafik
        float anzahl_bild = 50;
        // Anzahl der Bilder
        float zaehler_bild = 0;
        // Zähler für den Counter
        float position_bild = 0;
        // Position des Einzelbildes in der Gesamtgrafik

        private static uint[] texture = new uint[1];       // Our Texture 
        private static float xrot = 0;                     // X Rotation
        private static float yrot = 0;                     // Y Rotation
        private static float zrot = 0;                     // Z Rotation 

        public static void Main_2()
        {                                                 // Eingangspunkt
            App.Run(new my_openGL());                     // Starte das Programm als Windows Forms Application

        }
        public override void Initialize()
        {
            base.Initialize();                           // Run The Base Initialization
            glEnable(GL_TEXTURE_2D);                     // Enable Texture Mapping

            LoadTextures();                              // Jump To Our Texture Loading Routine
        }

        private void LoadTextures()
        {
            // TODO vom Programm steuern lassen
            string filename = @"uvtestbild00003.png";
            // The File To Load
            Bitmap bitmap = null;
            // The Bitmap Image For Our Texture
            Rectangle rectangle;
            // The Rectangle For Locking The Bitmap In Memory
            BitmapData bitmapData = null;
            // The Bitmap's Pixel Data

            bitmap = new Bitmap(filename);
            // Load The File As A Bitmap
            rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            // Select The Whole Bitmap

            bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            glGenTextures(1, texture);
            // Create One Texture

            glBindTexture(GL_TEXTURE_2D, texture[0]);
            // Zuweisung: die Textur ist 2D

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            // tpnTextureMinFilter besagt, mit welchem Filter die Grafik zusammengedrückt werden soll.
            // tpnTextureMagFilter besagt, mit welchem Filter die Grafik auseinandergezogen wird.
            // Der Parameter GL_LINEAR erzeugt das beste Ergebnis, belastet aber den Prozessor.
            // Möglich wäre auch GL_NEAREST. Das entlastet zwar die Hardware, sieht aber schnell recht pixelig aus.


            glTexImage2D(GL_TEXTURE_2D, 0, (int)GL_RGB8, bitmap.Width, bitmap.Height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, bitmapData.Scan0);
            // Der 1. Parameter besagt wieder 2D Textur
            // Der 2. Parameter gibt den Grad der Details an
            // Der 3. Parameter gibt die Art der Farbkanäle an, 3 = RGB.
            // Parameter 4 und 5 sind Breite und Höhe der Textur
            // Der 6. Parameter gibt die Rahmenbreite an, vorerst aber mal 0.
            // Parameter 7 und 8 geben Farbformat (RGB) und Art der Daten (Unsigned Byte = 0 - 255) an.
            // Der letzte Parameter übergibt schlußendlich die eigentliche Textur.

        }

        public override void Draw()
        {
            bool debug = false;

            if (UVMapping == true)
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                // Clear Screen And Depth Buffer
                glLoadIdentity();
                // setzt die aktuelle Modell-Matrix zurück

                glTranslatef(0.0f, 0.0f, -5.0f);
                //Zeichenpunkt setzen

                breite_bild = 1 / anzahl_bild;
                position_bild = breite_bild * Convert.ToInt64( Math.Round(zaehler_bild));
                //ohne Round haben wir einen Verlauf und keine GanzBilderSprünge

                glBindTexture(GL_TEXTURE_2D, texture[0]);


                //Dim PicPos () As GLfloat 'Position des Einzelbildes in der Gesamtgrafik
                // position_bild
                //Dim Piclength As GLfloat 'Breite einer Einzelgrafik 
                // breite_bild
                //Dim Pic As GLfloat 'Zähler für den Counter
                // zaehler_bild

                //glLoadIdentity 'setzt die aktuelle Modell-Matrix zurück
                //glTranslatef 2#, 0#, -8# 'Zeichenpunkt setzen

                //Piclength = 1 / 8 'das Bild besteht aus 8 Einzelbildern
                //PicPos = Round(Pic) * Piclength 'errechnen, an welcher Position das Einzelbild steht

                glBegin(GL_QUADS);

                

                glTexCoord2f(position_bild + breite_bild, 1f);
                glVertex3f(0.5f, 0.5f, 1.0f);
                // Oben Rechts

                glTexCoord2f(position_bild, 1f);
                glVertex3f(-0.5f, 0.5f, 1.0f);
                // Oben Links

                glTexCoord2f(position_bild, 0f);
                glVertex3f(-0.5f, -0.5f, 1.0f);
                // Unten Links

                glTexCoord2f(position_bild + breite_bild, 0f);
                glVertex3f(0.5f, -0.5f, 1.0f);
                // Unten Rechts

                glEnd();


                zaehler_bild += 0.2F;
                //Pic = Pic + 0.001
                 //Auch hier wäre die bessere Lösung eine Erhöhung anhand der verstrichenen Zeit, 
                //    damit die Geschwindigkeit nicht hardwareabhängig ist.




            }
            
            
            // #############
            if (UVMapping == false)
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                // Clear Screen And Depth Buffer
                glLoadIdentity();
                // Reset The Current Modelview Matrix


                glTranslatef(0.0f, 0.0f, -5.0f);
                // Zeichenpunkt zurücksetzen
                // glTranslate - Multipliziert die aktuelle Matrix mit einer Verschiebungsmatrix. x, y, z
                // Move Into The Screen 5.0 Units, 1.0 for fullscreen (-5.0 or -1.0)


                // glBindTexture - Bindet eine benannte Textur an ein Texturenziel. 
                glBindTexture(GL_TEXTURE_2D, texture[0]);            // Select Our Texture



                // Quadrat (Würfel) zeichnen
                glBegin(GL_QUADS);

                // Front Face
                // glColor - Setzt die aktuelle Farbe. RGB
                // glTexCoord2f - setzen die aktuellen Texturkoordinaten
                // glVertex3f - - Bestimmt die Koordinaten eines Vertex. Ein Vertex (Mehrzahl: Vertice(s)) ist ein Punkt im Raum. 

                // --- unten links ---
                glTexCoord2f(0.0f, 0.0f);
                glVertex3f(-1.5f, -1.0f, 1.0f);

                // --- unten rechts ---                  
                glTexCoord2f(1.0f, 0.0f);
                glVertex3f(1.0f, -1.0f, 1.0f);

                // --- oben rechts ---     
                glTexCoord2f(1.0f, 1.0f);
                glVertex3f(1.0f, 1.0f, 1.0f);

                // --- oben links ---      
                glTexCoord2f(0.0f, 1.0f);
                glVertex3f(-1.5f, 1.0f, 1.0f);


                glEnd();

                
            }
            // #############
 
        }

    }
}

The simple answer is that 400x40000 is not supported on any card I know of. Check your maximum supported texture size with:


GLint texSize; 
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);

Not true. Read the specs of ARB_texture_non_power_of_two.

yea, 400x4000 is valid if you have the npot extension.
However that is not the problem here, no the problem is that max texture size is around 4196 in any dimension, 40000 is way above that, and 640000 is not even in the same universe.

To reach those sizes you need either megatexturing or some kind of texture paging.

satan: Not true. Read the specs of ARB_texture_non_power_of_two.
did you understand my post?

but yes, 40000 is not supported and won’t be for the next couple years i guess.
just a hint: i hope anzahl_bild is a float value.

Thanks a lot for the replies, so what is the best way to solve it?
Megatexturing, Texture Paging or just cut the picturestrip so its not bigger than 8192 Px.

@_NK47 anzahl_bild is float

Of course I did not, because I am totally retarded. But please don’t tell me that npot and rect textures are the same, as they are not.

@Daniel:
Depends on what you want to do with the picture. If you only want to display it then paging looks like the best solution.
Remember that your picture is quite large and that it most possibly will not fit in your graphics card memory (if my estimation is correct we are talking about nearly 1 GB + 33% for mipmaps). So the question remains what do you want to do with it?

Of course I did not, because I am totally retarded. But please don’t tell me that npot and rect textures are the same, as they are not. [/QUOTE]

care to clarify?

anyways, what are you trying to accomplish with such big textures? there might be some techniques on that.

http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt
http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_non_power_of_two.txt

satan: Not true. Read the specs of ARB_texture_non_power_of_two.
satan: But please don’t tell me that npot and rect textures are the same, as they are not.

i accept my bitter defeat if you can post where i actually wrote that 1. they are same 2. that rect textures are not NPOT textures.

don’t be a retard.

I will exposure a hologram, each Pixel is a 2D-Bitmap (24bpp) and one row could have dimensions like 640 x 640.000 for 1000 columns.

And I need to implement a Genlock function, so we can affect the fps with a TTL, during the exposure Because the SPS will move in 40Hz to the next Pixel.

So I was thinking to use UV Mapping, sadly I’m far away to be good programmer so I tried the easy way :wink:

I’m realy open to any suggestion.

the thing is that you CANNOT use such big textures. it depends on your application what max texture size is supported. you need to split up all textures but im not sure that what you want will fit in the GPU and perform good.
no ideas actually. satan?

Let’s not spam the board. But if you insist.

It does make perfect sense that it works and GL_TEXTURE_2D supports ‘non power of two textures’ via ARB_texture_non_power_of_two.

This sounds like you should use rect textures if you need npot dimensions. This is a bad advice as rect textures don’t support mipmaps, don’t support REPEAT or MIRRORED_REPEAT wrap modes, don’t work with normalized texture coordinates and even introduce a new texture target namely GL_TEXTURE_RECTANGLE_ARB.
Remember that this is the beginners board and many people new to graphics programming are happy to get texturing working at all. For them (and IMHO everybody) ARB_texture_non_power_of_two is the way to go as it works exactly the same as OpenGLs standard texture mapping.

you’re right. one piece of advice though. next time write the actual meaning of what you think:
This sounds like you should use rect textures if you need npot dimensions. This is a bad advice as rect textures don’t support mipmaps, don’t support REPEAT or MIRRORED_REPEAT wrap modes, don’t work with normalized texture coordinates and even introduce a new texture target namely GL_TEXTURE_RECTANGLE_ARB.

this is a perfect explanation for the beginners forum!

and i will make sure i post and read more carefully next time.

@Daniel, maybe you can use texture array

http://developer.download.nvidia.com/opengl/specs/GL_EXT_texture_array.txt

Texture array are like 3D textures, a lot of 2D texture one on the top of the other. The main difference is that there isn’t interpolation of the 3rd coordinate.
The limit here is the limit of Max 3d Texture size that in my G8800 is 2024x2024x2024. :slight_smile:
Surely with such big data you have a lot of swap.
If you use 512x512x1024 you have 800Mb of data for a 8bit RGB texture… :-S

Definitly need 24bpp :wink:
But I will try this EXT_texture_array.

Can I extend my UV-Mapping by adding a few texture to one another?
Like 400x2024 + 400x2024 + …

Can I extend my UV-Mapping by adding a few texture to one another?
what do you mean?

what i forgot is that you could use texture compression (lossy) and thus get more textures into the GPU memory.