2011-05-02 33 views
0

更新:在@datenwolf的幫助下,我知道gluBuild2DMipmaps的返回值不是指向紋理的指針,而只是一個錯誤代碼。我忘了調用glGenTextures和glBindTexture。在這個答案中查看方法LoadTextureRaw爲什麼我的OpenGL對象使用相同的紋理渲染?

我在渲染多個對象時出現問題,每個對象都有自己的紋理文件定義,即它們都繪製相同的紋理。我創建了一個類層次結構CDrawObject->CBall。在CDrawObject,我定義這個:

public ref class CDrawObject 
{ 
protected: 
BYTE * dataTexture; 
GLuint * texture; 

public: 
String^filename; 
CDrawObject(void); 
virtual void draw(); 
void LoadTextureRaw(); 
}; 

在LoadTextureDraw(),我定義的:

void CDrawObject::LoadTextureRaw() 
{ 
//GLuint texture; 
if(!filename) return; 
if(filename->Equals("")) return; 
texture = new GLuint; 

System::Drawing::Bitmap^bitmap = gcnew Bitmap(filename); 
int h = bitmap->Height; 
int w = bitmap->Width; 
int s = w * h; 
dataTexture = new BYTE[s * 3]; 

System::Drawing::Rectangle rect = System::Drawing::Rectangle(0,0,w,h); 
System::Drawing::Imaging::BitmapData^bitmapData = 
    bitmap->LockBits(rect,System::Drawing::Imaging::ImageLockMode::ReadWrite , System::Drawing::Imaging::PixelFormat::Format24bppRgb); 

::memcpy(dataTexture,bitmapData->Scan0.ToPointer(),s*3); 

/* old code 
bitmap->UnlockBits(bitmapData); 
pin_ptr<GLuint*> pt = &texture;//pin managed pointer, to be unmanaged 
**pt = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w,h,GL_BGR_EXT, GL_UNSIGNED_BYTE, dataTexture); 
    */ 


    //new code : working fine this way. I forgot to call glGenTextures and glBindTexture 
    bitmap->UnlockBits(bitmapData); 
pin_ptr<GLuint*> pt = &texture;//pin managed pointer, to be unmanaged... a must here :) 
    glEnable(GL_TEXTURE_2D); 
glGenTextures(1,*pt); 
    glBindTexture(GL_TEXTURE_2D,**pt); 
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, w,h,GL_BGR_EXT, GL_UNSIGNED_BYTE, dataTexture); 

} 

而作爲CBall:繪製自己,我定義這個:

void CBall::draw(){ 
glLoadIdentity(); 

if(texture!=NULL && !filename->Equals("")) 
{ 
    glEnable(GL_TEXTURE_2D); 
    pin_ptr<GLuint*> pt = &texture; 
    glBindTexture(GL_TEXTURE_2D,**pt); 
} 

glEnable(GL_LIGHTING); 
glEnable(GL_LIGHT0); 
glShadeModel(GL_SMOOTH); 
glEnable(GL_DEPTH_TEST); 
glEnable(GL_NORMALIZE); 
glTranslatef(this->x,this->y,this->z); 
glRotatef(this->sudut_rotasi_x,1,0,0); 
glRotatef(this->sudut_rotasi_y,0,1,0); 
glRotatef(this->sudut_rotasi_z,0,0,1); 
glScalef(this->x_scale,this->y_scale,this->z_scale); 
GLUquadricObj *q = gluNewQuadric(); 
gluQuadricNormals(q, GL_SMOOTH); 
gluQuadricTexture(q, GL_TRUE); 
gluSphere(q, r, 32, 16); 
glFlush(); 
    glDisable(GL_TEXTURE_2D); 
} 

問題是,當我繪製兩個(或更多)球對象時,它們都使用相同的紋理繪製。我已經調試過代碼,並且對於每個對象,它們都有不同的texture變量。下面是我的代碼繪製這些球的快照:

... 
    CBall^ball = gcnew CBall(); 
ball->x=Convert::ToSingle(r->GetAttribute("x")); 
ball->y=Convert::ToSingle(r->GetAttribute("y")); 
ball->z=Convert::ToSingle(r->GetAttribute("z")); 
ball->r=Convert::ToSingle(r->GetAttribute("r")); 
ball->filename=r->GetAttribute("filename"); 
ball->LoadTextureRaw(); 
addGraphic(id, ball); 
    ... 

這些代碼是從讀取XML文件方法調用的。

這個OpenGL代碼我做了什麼錯?

+0

使用相同的文件名的紋理,他們終於畫(我重新安排一點點) ? – ColWhi 2011-05-02 15:31:51

回答

4

你的問題是,gluBuild2DMipmaps不會返回紋理名稱,而是一個錯誤代碼。你需要分別創建一個紋理名稱。

試試這個:

public ref class CDrawObject 
{ 
protected: 
    GLuint texture; // just a GLuint, not a pointer! 

public: 
    String^filename; 
    CDrawObject(void); 
    virtual void draw(); 
    void LoadTextureRaw(); 
}; 

變化LoadTextureRaw一點:

void CDrawObject::LoadTextureRaw() 
{ 

    if(!filename) 
     return; 
    if(filename->Equals("")) 
     return; 

    System::Drawing::Bitmap^bitmap = gcnew Bitmap(filename); 
    int h = bitmap->Height; 
    int w = bitmap->Width; 
    int s = w * h; 

    System::Drawing::Rectangle rect = System::Drawing::Rectangle(0,0,w,h); 
    System::Drawing::Imaging::BitmapData^bitmapData = 
     bitmap->LockBits(rect, 
          System::Drawing::Imaging::ImageLockMode::ReadWrite, 
          System::Drawing::Imaging::PixelFormat::Format24bppRgb); 

    // This is the important part: We generate a texture name and... 
    glGenTextures(1, &texture); // this should not require a pin_ptr, after all were in the middle of a member function of the class, so the garbage collector will not kick in. 

    // ...bind it, causing creation of a (yet uninitialized) texture object 
    glBindTexture(GL_TEXTURE_2D, texture); 

    GLint error = gluBuild2DMipmaps(
     GL_TEXTURE_2D, 
     GL_RGB, // this should be a valid OpenGL token, not the number of components! 
     w, h, 
     GL_BGR_EXT, GL_UNSIGNED_BYTE, 
     bitmapData->Scan0.ToPointer()); 

    bitmap->UnlockBits(bitmapData); 
} 

void CBall::draw(){ 

    glLoadIdentity(); 

    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_NORMALIZE); 

    glTranslatef(this->x,this->y,this->z); 
    glRotatef(this->sudut_rotasi_x,1,0,0); 
    glRotatef(this->sudut_rotasi_y,0,1,0); 
    glRotatef(this->sudut_rotasi_z,0,0,1); 
    glScalef(this->x_scale,this->y_scale,this->z_scale); 

    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, texture); 

    GLUquadricObj *q = gluNewQuadric(); 
    gluQuadricNormals(q, GL_SMOOTH); 
    gluQuadricTexture(q, GL_TRUE); 
    gluSphere(q, r, 32, 16); 
    // glFlush is not required 
    glDisable(GL_TEXTURE_2D); 

} 
+1

+1好的隱藏錯誤! – 2011-05-03 03:58:23