PDA

View Full Version : UV Mapping with large Pictures



Daniel (CGN)
11-17-2008, 04:28 AM
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;

_NK47
11-17-2008, 04:31 AM
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.

Daniel (CGN)
11-17-2008, 04:35 AM
sorry, both are integer, I just make a dot after thousand.

_NK47
11-17-2008, 05:08 AM
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.

Daniel (CGN)
11-17-2008, 05:43 AM
I'm not able to find anthing usefull, but I'm searching further ;)
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();


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

}

}
}

satan
11-17-2008, 06:03 AM
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);


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.
Not true. Read the specs of ARB_texture_non_power_of_two.

zeoverlord
11-17-2008, 06:05 AM
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.
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.

_NK47
11-17-2008, 06:34 AM
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.

Daniel (CGN)
11-17-2008, 06:43 AM
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

satan
11-17-2008, 06:45 AM
did you understand my post?
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?

_NK47
11-17-2008, 06:48 AM
did you understand my post?
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.

care to clarify?

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

satan
11-17-2008, 07:02 AM
care to clarify?
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

_NK47
11-17-2008, 07:06 AM
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.

Daniel (CGN)
11-17-2008, 07:09 AM
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 ;)

I'm realy open to any suggestion.

_NK47
11-17-2008, 07:13 AM
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?

satan
11-17-2008, 07:27 AM
Let's not spam the board. But if you insist.

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,...).
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.


for non power of two textures there are rect textures.
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.

_NK47
11-17-2008, 07:39 AM
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.

Rosario Leonardi
11-17-2008, 06:19 PM
@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. :)
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

Daniel (CGN)
11-19-2008, 02:54 AM
@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. :)
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 ;)
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 + ...

_NK47
11-19-2008, 03:14 AM
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.

Daniel (CGN)
11-19-2008, 03:39 AM
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 get more textures into the GPU.
I mean, I can make UV-Mapping with one 400x2048 Texture, so it should be possible to arrange more textures so I can use 400x2048*n, or?

This Texture Compression is a good Idea, I'm searching for a lossles method. Because for the exposure it is important that the data is clean and not change by a lossy algorithm.

_NK47
11-19-2008, 03:43 AM
not sure if there is any lossless compression of textures. but yeah check and let us know.
http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage2D.xml

Daniel (CGN)
11-19-2008, 03:49 AM
Do you know waht I mean with "to arrange more textures"?

_NK47
11-19-2008, 04:19 AM
sorry no. multiple textures with same uv set?? and describe <arrange> a bit more.

would not advice to use non power of two values still. but that depends what hardware you are targeting. for older hardware no can go.