COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### GL_TEXTURE transformations for 3D textures

• Email
• Follow

Hi all,

I'm doing volume rendering with 3D textures. To rotate my data I
manipulate openGL's texture matrix. For example:

glMatrixMode ( GL_TEXTURE );
// shift origin to center of texture
glTranslatef ( 0.5, 0.5, 0.5 );
// apply rotation
glRotatef(20, 0.0, 0.0, 1.0);
// shift back
glTranslatef ( -0.5, -0.5, -0.5 );

However, recently I discovered that one axis always seems to be
oriented in the wrong direction (depending on how I map texel coords
to quad vertices). Currently it's the z axis, meaning that glRotatef
(20, 0.0, 0.0, 1.0) will rotate my volume in clockwise direction

No matter how I alter mapping of texture coords, there is always one
axis that is affected by this problem. Here is what my mapping looks
like:

glMatrixMode ( GL_MODELVIEW );
// view transformation
gluLookAt (0.0, 0.0, 1000.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
float tex_z;
for ( int z = num_quads - 1; z >= 0; z -- )
{
tex_z = ((double) z) / ((double) num_quads);
glTexCoord3f ( 0.0, 0.0, tex_z );
glVertex3f ( -100, -100, z );
glTexCoord3f ( 1.0, 0.0, tex_z );
glVertex3f ( 100, -100, z );
glTexCoord3f ( 1.0, 1.0, tex_z );
glVertex3f ( 100,  100, z );
glTexCoord3f ( 0.0, 1.0, tex_z );
glVertex3f ( -100,  100, z );
}
glEnd();

glDisable ( GL_TEXTURE_3D );
glutSwapBuffers();
}

I already tested what's it's like for 2D textures. However I couldn't
find this effect there. I hope you guys can help me, because my work
strongly depends on a correct representation of data in terms of the
transformation matrix.

Cheers,
Sebastian

 0

See related articles to this posting

sebastianthelen@googlemail.com wrote:

> Hi all,
>
> I'm doing volume rendering with 3D textures. To rotate my data
> I manipulate openGL's texture matrix. For example:
>
> glMatrixMode ( GL_TEXTURE );
> // shift origin to center of texture
> glTranslatef ( 0.5, 0.5, 0.5 );
> // apply rotation
> glRotatef(20, 0.0, 0.0, 1.0);
> // shift back
> glTranslatef ( -0.5, -0.5, -0.5 );
>
> However, recently I discovered that one axis always seems to be
> oriented in the wrong direction (depending on how I map texel
> coords to quad vertices). Currently it's the z axis, meaning
> that glRotatef (20, 0.0, 0.0, 1.0) will rotate my volume in
> clockwise direction instead of counterclockwise.

Are you sure it's really clockwise? A screenshot/movie would be
nice (if you got a Unix system you can use the code I append at
the end of the post, to create a movie file, which you can

Most people get confused by the right handedness of OpenGL,
whereas in school they oftenly learn left handed coordinate
systems. Now get one axis wrong and you end up, misinterpreting
rotations. Small hint: Just draw a small coordinate system
indicator into the scene: Just three lines originating at 0,0,0
going to
* 1,0,0 in red
* 0,1,0 in green
* 0,0,1 in blue

BTW: The way you address the texture coordinates, you're not
going to hit the texels exactly.

Here's the basic setup, with which you can dump a video directly,
though it's quite rudimentary, and requires the viewport being
the same size as the target video and not changed during between
frames.
/* videodump.c */
typedef struct VidDumpInfo {
int vid_width;
int vid_height;
FILE *pipe_mencoder;
void *image_buffer;
} VidDumpInfo;

void dump_frame(VidDumpInfo restrict * vdi)
{
if( !vdi || !vdi->image_buffer || !vdi->pipe_mencoder )
return;

int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);

if(viewport[2] != vdi->vid_width || viewport[3] !=
vdi->vid_height) {
/* error: Viewport size changed */
}

glPixelStorei(GL_PACK_LSB_FIRST, GL_TRUE);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);

GL_BGR, GL_UNSIGNED_BYTE, vdi->image_buffer);
fwrite(vdi->image_buffer, vdi->vid_width*3, vdi->vid_height,
vdi->pipe_mencoder);
fflush(vdi->pipe_mencoder);
}

#define MAX_CMDLINE
int start_dump(VidDumpInfo *vdi, char const * const
output_filename)
{
int viewport[4];
char mencoder_cmdline[MAX_CMDLINE+1];

if( !vdi || ! output_filename )
return -1;

glGetIntegerv(GL_VIEWPORT, viewport);
vdi->vid_width = viewport[2];
vdi->vid_height = viewport[3];

vdi->image_buffer = (void*) realloc(image_buffer, 3*w*h);
if( !vdi->image_buffer ) {
return -1;
}

snprintf(mencoder_cmdline, MAX_CMDLINE,
"mencoder -"
" -demuxer rawvideo"
" -rawvideo w=%d:h=%d:format=bgr24:size=%d"
" -flip -nosound"
#if defined VIDEODUMP_XVID
" -ovc xvid -xvidencopts bitrate=3000"
#else if defined VIDEODUMP_X264
#else if defined VIDEODUMP_NUV
" -ovc nuv"
#endif
" -o %s",
vdi->vid_width, vdi->vid_height,
vdi->vid_width*vdi->vid_height*3,
output_filename );
vdi->pipe_mencoder = popen(mencoder_cmdline, "w");

return 0;
}

void stop_dump(VidDumpInfo *vdi)
{
fclose(vdi->pipe_mencoder);
free(vdi->image_buffer);
}

Call start_dump with vdi pointing to a VidDumpInfo stored as some
persistent place in memory, to begin to caputure video
(eventually reduce the viewport size to something reasonable
beforehand). Then for each frame call dump_frame with the OpenGL
context being current. Once done call stop_dump. Both with the
vdi being the one, initialized by start_dump.

The main dependency on Unix or a alike comes from the use of
popen. Although Windows provides popen, too, it's implementation
is somewhat broken.

Note that this is a hack and in a big scale application you
should either implement a frameserver or use some encoder/muxer
library (like the one of ffmpeg).

Wolfgang Draxinger
--
E-Mail address works, Jabber: hexarith@jabber.org, ICQ: 134682867


 0

Hi Wolfang,

first of all thank you, I really appreciate your immediate response.

> Are you sure it's really clockwise? A screenshot/movie would be
> nice (if you got a Unix system you can use the code I append at
> the end of the post, to create a movie file, which you can

Well, I'm pretty sure, though not 100% =3D) I tried to chose unambigous
rotation angles, so that it's easy to make out the orientation (hence
20=B0). However, I think it's definitely a good idea to draw a small
coordinate system, just to be sure. Taking a video seems to be kind of
an overkill to me, though I'm really thankful for your video capturing
code. Don't you think 2 screenshots should identify each ratation's
orientation uniquely?

> Most people get confused by the right handedness of OpenGL,
> whereas in school they oftenly learn left handed coordinate
> systems. Now get one axis wrong and you end up, misinterpreting
> rotations. Small hint: Just draw a small coordinate system
> indicator into the scene: Just three lines originating at 0,0,0
> going to
> * 1,0,0 in red
> * 0,1,0 in green
> * 0,0,1 in blue

Yeah, probably something like that is right now happening to me and
I'm misinterpretating rotations. I currently assume that a texture's x
coordinate increases when moving "right", a y coordinate increases
when moving "up" and a z coordinate increses when moving "out of the
screen"  I tried to compare the rotations of my 3d texture to that of
threedimensional vertices my manipulating openGL's modelview matrix.
Calling glRotate(20, 0.0, 0.0, 1.0) should rotate a perfectly
vertically oriented line through the origin, so that is runs from top
left to bottom right. Vertices behave exactly as expected while
textures seem to have this weird rotation "bug". I will try to come up
with a few screenhots as soon as possible.

> BTW: The way you address the texture coordinates, you're not
> going to hit the texels exactly.

What exactly do you mean by that? Can you explain that a little more
in detail?

Thanks,
Sebastian

 0

sebastianthelen@googlemail.com wrote:

>> BTW: The way you address the texture coordinates, you're not
>> going to hit the texels exactly.
>
> What exactly do you mean by that? Can you explain that a little
> more in detail?

In your case it probably doesn't matter, but I noticed, that
you're drawing 128 slices, probably to match with 128 layers in
the texture volume.

What a lot of people get wrong with OpenGL textures is, how
OpenGL interprets the coordinate. Imagine a unit
line/square/cube/hypercube, etc. or in general a [0,1]^n
intervall. Now I give you the task to devide this intervall into
2^k subintervalls in each of the n dimensions; where are the
centers of those subintervalls. OpenGL treats textures exactly
in this way: A function
t_i -> r,g,b,a: [0,1]^n |-> [0,1]^4, i \in {1...n}
(I hope you're not scared of mathematical notation).
However this function is defined in terms of a descreete grid,
with the sampling points being the texel values, placed in the
center of the subintervalls (these subintervalls are, what one
refers to as texel or pixel). So the actual sampling value is
determined by interpolating between adjacent sampling point,
with the interpolation factor being the offset from the texel
center(s).

0, 1 and similair are _not_ located on the texel centers, but
their borders. So if you're in GL_LINEAR filtering, GL_WRAP
clamping, the texture coordinate 0 takes exactly 0.5 of the
first texel and 0.5 of the last texel in that dimension (well,
actually you've to consider the distance, so it's more like
sqrt(ds^2 + du^2 + ...), but I think you got the concept).

So to exactly hit a texel you've to lineary remap the texture
coordinates a bit. This can be done with a matrix and homogenous
coordinates of course, and OpenGL's 4x4 GL_TEXTURE_MATRIX can do
it for 3D textures. But for the general case I give you a code
snippet to calculate the texture coordinate to hit a desired
texel's "bull's eye":

GLfloat TexCoordByTexel(GLuint texture_dim, GLuint texel_pos)
{
return 0.5/texture_dim + texel_pos /
( (texture_dim) + 1./(texture_dim) );
}

should be easy enough to translate into other languages.

Wolfgang Draxinger
--
E-Mail address works, Jabber: hexarith@jabber.org, ICQ: 134682867


 0

On 18 Dez., 15:42, Wolfgang Draxinger <wdraxin...@darkstargames.de>
wrote:
> >> BTW: The way you address the texture coordinates, you're not
> >> going to hit the texels exactly.
>
> > What exactly do you mean by that? Can you explain that a little
> > more in detail?
>
> In your case it probably doesn't matter, but I noticed, that
> you're drawing 128 slices, probably to match with 128 layers in
> the texture volume.
>
> What a lot of people get wrong with OpenGL textures is, how
> OpenGL interprets the coordinate. Imagine a unit
> line/square/cube/hypercube, etc. or in general a [0,1]^n
> intervall. Now I give you the task to devide this intervall into
> 2^k subintervalls in each of the n dimensions; where are the
> centers of those subintervalls. OpenGL treats textures exactly
> in this way: A function
> t_i -> r,g,b,a: [0,1]^n |-> [0,1]^4, i \in {1...n}
> (I hope you're not scared of mathematical notation).
> However this function is defined in terms of a descreete grid,
> with the sampling points being the texel values, placed in the
> center of the subintervalls (these subintervalls are, what one
> refers to as texel or pixel). So the actual sampling value is
> determined by interpolating between adjacent sampling point,
> with the interpolation factor being the offset from the texel
> center(s).
>
> 0, 1 and similair are _not_ located on the texel centers, but
> their borders. So if you're in GL_LINEAR filtering, GL_WRAP
> clamping, the texture coordinate 0 takes exactly 0.5 of the
> first texel and 0.5 of the last texel in that dimension (well,
> actually you've to consider the distance, so it's more like
> sqrt(ds^2 + du^2 + ...), but I think you got the concept).
>
> So to exactly hit a texel you've to lineary remap the texture
> coordinates a bit. This can be done with a matrix and homogenous
> coordinates of course, and OpenGL's 4x4 GL_TEXTURE_MATRIX can do
> it for 3D textures. But for the general case I give you a code
> snippet to calculate the texture coordinate to hit a desired
> texel's "bull's eye":
>
> GLfloat TexCoordByTexel(GLuint texture_dim, GLuint texel_pos)
> {
> =A0 =A0 =A0 =A0 return 0.5/texture_dim + texel_pos /
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ( (texture_dim) + 1./(texture_dim) );
>
> }
>
> should be easy enough to translate into other languages.
>
> Wolfgang Draxinger
> --
> E-Mail address works, Jabber: hexar...@jabber.org, ICQ: 134682867

Hi Wolfgang,

I finally found some time to continue working on my little project. I
added a coordinate system and multiplied both the texture matrix and
modelview matrix by the same transformation matrix (glRotate(20, 0, 0,
1)). I took 2 screenshots and sent them to you via email. As you can
see, the effect of the transformation is inverse. The coordinate
system's tripod turns left, while the texture turns right. Weird,
huh?!

I thought a little about manipulating GL_TEXTURE and the consequences
for texture mapping. Is it possible, that I have to apply the inverse
transformation matrix to my texture? For example, think of a pointer
pointing at 12:00 on a clock. Now rotate this pointer 90=B0 left, i.e.
it will point at 9:00. If I understand texture mapping correctly, the
texel at 9:00 will be mapped the vertex, where the original 12:00
texel would have been mapped. That means although I apply a
counterclockwise rotation to the texture matrix, the optical effect
will be that of a clockwise rotation. If that was the case, I would
have to invert my transformation matrix. What concerns me a little is,
that my argumentation would only apply to the current z axis, since x-
and y rotation seem to work. Also tests with 2D textures seem to

Sebastian

 0

4 Replies
250 Views

Similar Articles

12/6/2013 1:20:06 AM
page loaded in 125674 ms. (0)

Similar Artilces:

Vector Graphics as Textures
Hi. Is it possible to use Vector Graphics as textures, rather than Raster/Bitmap type images? This would solve the problem of unrealistic close detail, and probably eliminate the need for mipmapping or magnification/minification filtering. If it is possible, could anyone point me in the direction of any resources? Thanks, Rellik Rellik wrote: > Hi. Is it possible to use Vector Graphics as textures, rather than > Raster/Bitmap type images? This would solve the problem of unrealistic > close detail, and probably eliminate the need for mipmapping or > magnification/minification filtering. If it is possible, could anyone point > me in the direction of any resources? A texture is per definition a raster image. Actually there is no need for a special "vector" texture, since what OpenGL is processing is vector data. So what you could do is transform the coordinates of a vector drawing to texture local space. -- +------------------------------------------------+ | +----------------+ WOLFGANG DRAXINGER | | | ,-. DARKSTAR | lead programmer | | |( ) +---------+ wdraxinger@darkstargames.de | | | `-' / GAMES

get line number
How do get the actual line number from the actual running sourcecode. I need it for debugging purpose

Best (nonBBEdit) Textworker?
Hi team BBEdit annoys my Panther, but I miss using it. SO - can anyone recommend a similar utility. TextEdit is OK but it doesn't save as TeXT! Please, anyone Nikki In article <161220040104418633%user@ccount.dot>, Nikki <user@ccount.dot> wrote: > TextEdit is OK but it doesn't save as > TeXT! Sure it does. Look at the preferences. Dear Nikki - >>>>> "Nikki" == Nikki <user@ccount.dot> writes: Nikki> Hi team BBEdit annoys my Panther, but I miss using it. SO Nikki> - can anyone recommend a similar utility. www.xe

procedural planet surface textures
i plan to write code that generates realistic looking planet surfaces, by passing it just a few parameters. ideally i would like to be able to generate textures that look as good as these: http://www.starbasedelta.com/img/ss/terrafrm.jpg they don't need to be very detailed, 512x256 would be sufficient, as i dont plan to show the planets up close. i want to be able to create rocky/moon-style planets (possibly with craters on the surface) as well as earth style planets with water, vegetation, continental structures and an extra cloud later, but also gaseous planets like saturn or jupiter. so in short the full range and beyond ;-) before i'd start doing this i'd like to know if there are any people out there that would like to share their experiences, or could give some pointers, webpages, sample codes, what ever serves to get a better picture. i am aware that this is by far no simple task. i did find a few pointers on the web myself, which are: http://cat.nyu.edu/~lisa/javaplanet/ http://www.cs.wpi.edu/~matt/courses/cs563/talks/noise/noise.html http://www.noisemachine.com/ http://baddoggames.com/planet/ http://www.stanford.edu/~jjshed/perlin/index.html http

Multiple Textures with Mesa
Hi there! I'm trying to compile a Windows OpenGL application under Linux (Mesa). The problem is that this application uses Multi Texturing and I don't know, how to get the entry point addresses for the extension functions in Mesa. Here the concerned lines of code: PFNGLACTIVETEXTUREARBPROC glActiveTextureARB=NULL; PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB=NULL; and glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) glutGetProcAddress("glActiveTextureARB"); glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) glutGetProcAddress("glMultiTe

Problems with transparency and multiple textures
I'm working on an emulator, and I decided to add OpenGL support. The following is sample code which is very close to what I want to do, but it doesn't seem to work. This reason for this code will be to generate a font texture, and draw individual glyphs onto the main window texture. I think there is some problem with the interaction between the main texture and the font texture. GLubyte subimage[100][100][4]; for(int i=0;i<100;i++) { for(int j=0;j<50;j++) { subimage[i][j][0] = (GLubyte) 0xff; subimage[i][j][1] = (GLubyte) 0; subimage[i][j][2] =

VRML with Textures from Solidworks
I am intrested to know if anyone has a way to get out the information from Solidworks with the VRML and textures attached to it. Currently the porgram can do VRML 1.0 and 97, but no VRML 2.0 with textures. You do have the ability to texture map and render with the program, but when you export the VRML, only the colors go with it. The program does have the ability to write to the API. Visual basics and the likes can be used to set up what ever you want. So I guess my question is if anyone has tried this, and if not where would one being to look to find information on how to add this in.