views:

35

answers:

1

Hi all, I'm new to opengl and have been able to learn a lot on my own, but i am stuck on this one.

I have a room rendered, but I need a sphere that hovers in the center reflecting everything else perfectly. So far, I've been able to cube map to it with pretty good results, but the 6 textures are all the same: namely, the view I have of the room. I am calling gluLookAt to reposition the camera to where the sphere is going to be, and look at its surroundings, then I make a call to glCopyTexImage2D to get that loaded into the appropriate texture, but I can't get 6 different perspectives loaded... just the one, six times.

here's the relevant code if you can look through it and help me out, i will love you forever :)

 void drawReflectiveSphere(){
  glEnable(GL_TEXTURE_CUBE_MAP);

  float pos[] = {10.0, 1.0, -40.0};
  float x_pos [] = {pos[0] + 1, pos[1], pos[2]};
  float x_neg [] = {pos[0] - 1, pos[1], pos[2]};
  float y_pos [] = {pos[0], pos[1] + 1, pos[2]};
  float y_neg [] = {pos[0], pos[1] - 1, pos[2]};
  float z_pos [] = {pos[0], pos[1], pos[2] + 1};
  float z_neg [] = {pos[0], pos[1], pos[2] - 1};
  float view_pos[][3] = {x_pos[0], x_neg[0], y_pos[0], y_neg[0], z_pos[0], z_neg[0]};

  glGenTextures(1, &cubemap);

  glReadBuffer(GL_BACK);

  //Use different frustum
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glFrustum(-5.0, 5.0, -5.0, 5.0, 0.0, width + 10.0);

  glMatrixMode(GL_MODELVIEW);
  glViewport(0, 0, 128, 128);

  //Generate cube map textures
  for(int i = 0; i < 6; i++){
    glPushMatrix();  
      gluLookAt(pos[0], pos[1], pos[2],
            view_pos[i][0], view_pos[i][1], view_pos[i][2],
            0.0, -1.0, 0.0);  
      glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 0, 0, 128, 128, 0);
    glPopMatrix();
  }

  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  
  glEnable(GL_TEXTURE_GEN_S);
  glEnable(GL_TEXTURE_GEN_T);
  glEnable(GL_TEXTURE_GEN_R);

  //Restore viewport
  glViewport(0, 0, W, H);

  //Draw cube-mapped sphere
  glPushMatrix();
    glTranslatef(pos[0], pos[1], pos[2]);
    gluSphere(quadratic, 5.0f, 128, 128);
  glPopMatrix();

  //Restore projection matrix
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glDisable(GL_TEXTURE_GEN_S);
  glDisable(GL_TEXTURE_GEN_T);
  glDisable(GL_TEXTURE_GEN_R);
  glDisable(GL_TEXTURE_CUBE_MAP);
}
+2  A: 

(It's been a while since I've done any graphics programming, so I may be totally off base.)

glCopyTexImage2D copies from the current GL_READ_BUFFER, which is not getting modified by your gluLookAt calls. I don't think this approach is going to work; you're sending a bunch of drawing commands, copying the pixels to a texture, using gluLookAt to change the view and expecting all of the previous drawing commands to still be hanging around. You're going to need to repeat all of the drawing for each perspective and copy into a single texture after each one. Then to actually use your cube map, you'll need to redraw the entire scene again, and then draw the sphere with the cube map.

You're also drawing to the screen, or whatever it's called (the default color buffer?), and then copying it into a texture. That's fine for a simple program, but you'd really want to render directly to your textures, and only draw the final result. (Especially when they're wildly different sizes.)

sfink
Ok, so if I have a method called render() which draws the whole scene, i could call it after my gluLookAt(), it would render from each new perspective and load into the texture? Also, I should generate these textures separately from (as in prior to) drawing the cube map?
JakeVA
also... how would I go about rendering directly to my textures? I only just barely figured out how matrix stacks work, it's all brand new to me.
JakeVA
@JakeVA To render directly to textures, you need to use Framebuffer Objects (FBO).
Matias Valdenegro
ok thx. clearly opengl is not noob friendly, guess i need to reread the book.
JakeVA
Rereading the book now will just make your eyes bleed. Good tutorials are a much better way to learn, from somewhere like http://nehe.gamedev.net/ . But: yes, FBOs are the right way to render to a texture. When experimenting, though, your current approach is much easier. (FBOs are a PITA to set up and use.) But you need to understand the basic control flow: you redraw everything in every frame to an unseen buffer, then swap it with the visible. Or in your case, copy it out to a texture, clear it, and continue until you have your final scene rendered. (So yes, your 1st comment is 100% correct.)
sfink
Oh, and yes, generate your textures once before doing anything else. You don't need to recreate them per frame. (You'll need to update their contents every frame if you want stuff that is moving/changing in the scene to be visible in the reflection, of course.)
sfink