JOGL Texture problems - opengl

I'm in the process of trying to learn JOGL bindings. The tutorials seem to be outdated, so I'm always trying to piece together what is valid from each one.
I'm having problems trying to apply a simple texture to a square plane.
I have an image that is 204 X 204 called box.png.
In my init() I do the following to get the texture loaded:
try {
InputStream stream = getClass().getResourceAsStream("box.png");
TextureData data = TextureIO.newTextureData(gl.getGLProfile(),
stream, 100, 200, false, "png");
boxTexture = TextureIO.newTexture(data);
} catch (IOException exc) {
exc.printStackTrace();
System.exit(1);
}
Then I try to apply my texture doing the following in my display():
gl.glEnable(GL.GL_TEXTURE_2D);
boxTexture.enable(gl);
boxTexture.bind(gl);
gl.glBegin(GL2.GL_QUADS);
// Front Face
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glEnd();
Are there any blaring problems that would explain why I'm failing?

Only thing I can think of is that the texture isn't a power of 2. Change the size of the texture to 256x256 and see if it works then. Depending on your graphics card, it will or won't be supported (it should be if the card isn't ancient).

Related

MFC and OpenGL events for drawing

I have built a SDI MFC application, where the CView child is drawing a cube with OpenGL. This cube is drawn by the following function:
void CglSDI3View::setupScene()
{
wglMakeCurrent(m_hDC, m_hRC);
// Clear color and depth buffer bits
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Wireframe Mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
// Front Side
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
// Back Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
// Top Side
(...)
glEnd();
SwapBuffers(m_hDC);
}
I have no Timer defined. Rigth now, my OnDraw function is as follows:
void CglSDI3View::OnDraw(CDC* /*pDC*/)
{
CglSDI3Doc* pDoc = GetDocument();
wglMakeCurrent(m_hDC, m_hRC);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -m_fZoom);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
setupScene();
wglMakeCurrent(NULL, NULL);
ValidateRect(NULL);
}
where m_fRotX, m_fRotY, m_fPosX, etc. are scaling and translation factors. My question is: do I need to call setupScene() on every OnDraw() call? Or can this be optimized? In other words, does the cube have to be redrawn on every OnDraw() call or is there a way to do this only once and then apply only transformations?
Please note that in the future, the setupScene() function will draw a huge point cloud with millions of colored points, so this needs to be optimized as much as possible.
The name "setupScene" is misleading. OpenGL has no scenes. OpenGL has no models. OpenGL is not a scene graph.
OpenGL is a "dumb" drawing API. It draws points, lines and triangles, one at a time. And after drawing something it already forgets about it.
So yes, you have to redraw if you want to have some changes in the drawing to happen, because, well, it's just a drawing and nothing more. There's no retained scene OpenGL could manipulate.
So rename "setupScene" to "drawScene" and use it as the thereby apt name suggests.

Drawing tetrahedron in openGL + SDL 2.0

So I'm pretty new to openGL programming and am just going over the basics for now. I know I should be using VBOs and stuff but wanted to get a little foundation first. I wont present you with all the code just the stuff that draws and sets the scene.
Heres a little code for setting up my camera:
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, width / height, 1, 1000);
glEnable(GL_DEPTH_TEST);
// Move the camera back to view the scene
glTranslatef(0.0f, 0.0f, -5.0f);
I tried to create it around the origin like so (also I never draw the bottom face) :
void drawtetrahedron(GLfloat angle)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); //FRONT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //RIGHT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //LEFT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(0.0f, -1.0f, -1.0f);
glEnd();
}
When my window first comes up the red triangle looks fine, but as I rotate it the shape looks a little distorted. If I rotate all the way around (where I cant see the red face at all) it looks normal... What am I missing here?
Heres where it starts to look weird
Also any pointers on openGL stuff I'm doing incorrectly (or in general) are greatly appreciated! :D
I don't know if this is what you consider a wierd looking shape, but your shape doesn't seem to be a regular Tetrahedron:
The 3 Corners of the base don't have the same distance to the top corner (the two front corners have a distance of sqrt(6) to the top corner, while the back corner has a distance of sqrt(5)).
the distance on the base is off too: the front corners have a distance of sqrt(2) while the distance between any front corner and the back corner is sqrt(3).
An example for a regular tetrahedron would be:
(Please note that these coordinates don't have a base parallel to the xz plane)
(1,1,1)(1,-1,-1)(-1,1,-1)(-1,-1,1)
Your code itself looks to be ok. (Except for the translating the projection matrix) I, myself prefer to create code blocks after push/popmatrix and glbegin/end (these things { ... }), but that's just to keep my code easy to read.
Also, as a general rule of thumb, in opengl you don't move the camera: you move everything else. (That's why translating negative z moves objects away from you, translating positive x makes them move right and so on...)

Mapping a 2D image to a 3D texture

Question:
I am trying to map a single 2D image to a 3D texture. When I visualize the output, OpenGL renders a white texture floating in black background. Why is this happening? Is it possible to map a 2D image to a 3D texture?
My goal is to place multiple 2D images along the z-dimension to resemble a volume. An example of such an approach is in this video: http://cvlab.epfl.ch/research/medical/em/synapses
Approaches attempted:
I took 2D images and mapped them to 2D textures. I have also used 2D texture arrays. Both of these approaches provide a good result. However, when I tried to paint the surface of a 3D texture with the same image, I get a white texture floating around in a black space.
Code
I have followed the texture mapping tutorial that is available on NeHe's website.
http://nehe.gamedev.net/tutorial/lesson_06_texturing_update/47002/
Except changes to these three functions, everything else in the program (present in the solution file in the website) is the same.
... // header file declarations
#include <glext.h>
PFNGLTEXIMAGE3DPROC glTexImage3D;
GLuint texture;
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
/* load an image file directly as a new OpenGL texture */
texture = SOIL_load_OGL_texture("Data/NeHe.bmp",SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,S OIL_FLAG_INVERT_Y);
// "Data/NeHe.bmp"
if(texture == 0) {return false;}
glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
if (glTexImage3D == NULL)
{
printf("Error in line %d: Couldn't load glTexImage3D function. Aborting.\n", __LINE__);
return -1;
}
glBindTexture(GL_TEXTURE_3D, texture);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4096, 4096, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
return true;
}
int InitGL(GLvoid)
{
if (!LoadGLTextures())
{ return FALSE; }
glEnable(GL_TEXTURE_3D);
// glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); //
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective calculations
return TRUE; // Initialization Went OK
}
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
// glBindTexture(GL_TEXTURE_2D, texture[0]);
glBindTexture(GL_TEXTURE_3D, texture);
glBegin(GL_QUADS);
glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
return TRUE;
}
...
It is better to use 3D textures instead of 2D ones as you will be able to apply rotations correctly using glRotate(). You will also need to do blending and/or alpha-testing to see different layers of your 2D image.
To create a 3D texture, you can create an array of dimension [width x height x number_of_slices] and then store the raw data slice by slice
Look at this tutorial: http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering?msg=4729498#xx4729498xx
It's very good and it worked for me to do the same thing

OpenGL - How do you scroll a texture?

I am creating a texture from a pango layout and mapping the texture to the screen using OpenGL and GLUT. I want to scroll the texture in the window. I'm not concerned with the controls to scroll, but how do I cause map the portion of the texture I want to see onto the screen? I assume I use glTranslate, but where do I apply it?
Thanks in advance.
Here is what I currently do:
glEnable(GL_TEXTURE_2D);
{
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex2f( 0.0f+x, 0.0f+y);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_width+x, 0.0f+y);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_width+x, _height+y);
glTexCoord2f(0.0f, 1.0f); glVertex2f( 0.0f+x, _height+y);
}
glEnd();
}
glFlush();
glDisable(GL_TEXTURE_2D);
Another way would be to use a texture matrix (matrix mode GL_TEXTURE) or do it in a shader.
Depends on how many vertices would have to be modified. If just a few it could be more performant but for many vertices a texture matrix/shader approach could be better. Note that built in matrix operations are deprecated, i.e. it now is recommended to use textures.
Scrolling in a shader would be easy: out.tex = in.tex + offset where offset could be a uniform which is set per frame or be calculated from other input.
Since your example uses immediate mode, I'll expand it with the texture matrix mode.
But please be aware that this is deprecated methodology.
glEnable(GL_TEXTURE_2D);
{
glMatrixMode(GL_TEXTURE);
glLoadIndentity();
glTranslatef(x,y,0);
glMatrixMode(GL_MODELVIEW);
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex2f( 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_width, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_width, _height);
glTexCoord2f(0.0f, 1.0f); glVertex2f( 0.0f, _height);
}
glEnd();
}
glFlush();
glDisable(GL_TEXTURE_2D);
Unless you also want to tile I would just modify the UV coordinates of the vertices you are outputting. Then you just change the coordinates you feed to glTexCoord2f to specify a crop.
There is also a nice example of texture transformations here http://potatoland.org/glart/week5/GLART_5_texture_samples.java (it's java but you can easily translate it to C)

opengl texture cube c++

hello i create a cube and want on one side an texture.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);
glBegin(GL_POLYGON); //Vorderseite
glColor4f(1.0f,0.0f,0.0f,1.0f); //ROT
glVertex3f(-fSeitenL/2.0f,-fSeitenL/2.0f,+fSeitenL/2.0f);
glColor4f(1.0f,1.0f,0.0f,1.0f); //GELB
glVertex3f(+fSeitenL/2.0f,-fSeitenL/2.0f,+fSeitenL/2.0f);
glColor4f(1.0f,1.0f,1.0f,1.0f); //WEISS
glVertex3f(+fSeitenL/2.0f,+fSeitenL/2.0f,+fSeitenL/2.0f);
glColor4f(1.0f,0.0f,1.0f,1.0f); //MAGENTA
glVertex3f(-fSeitenL/2.0f,+fSeitenL/2.0f,+fSeitenL/2.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
but i can't see my texture, what did i wrong?
thanks.
You haven't supplied texture coordinates. You need to issue one call to glTexCoord (the 2f variant being the most commonly-used) that indicates a part of the texture that the vector maps to, before the corresponding glVertex call.
Otherwise, OpenGL has no idea how the texture should be pasted onto the polygons.
First of all this doesn't seem a cube but just a quad, a cube is made by 6 different quads.. (and you could use GL_QUADS instead that GL_POLYGON.
Second thing is that you are loading the texture but not mapping it to the vertices. You need to supply coordinates to map how the texture should fit onto the quad. You can do it by using
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
the example is taken from NEHE OpenGL guide and I really suggest you to take a look since it's quite well explained: http://nehe.gamedev.net
Check tutorial 6 about texture mapping: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06