6

我正在尝试将 .png 图像渲染为纹理。但是,正在渲染的只是一个白色方块。

我给我的纹理一个称为 texID 的唯一 int ID,将像素数据读入缓冲区“图像”(在 .h 文件中声明)。我加载我的像素缓冲区,完成我所有的 OpenGL 工作并将该像素缓冲区绑定到 OpenGL 的纹理。然后我使用 glDrawElements 将其全部绘制出来。

此外,当调用构造函数时,我将纹理初始化为 32x32 的大小,因此我怀疑它与大小的二次幂问题有关。

任何人都可以在我的 OpenGL GL_TEXTURE_2D 设置中看到任何可能给我一个白色方块的错误。

 #include "Texture.h"




Texture::Texture(int width, int height, string filename)
{

    const char* fnPtr = filename.c_str(); //our image loader accepts a ptr to a char, not a string
    printf(fnPtr);
    w = width; //give our texture a width and height, the reason that we need to pass in the width and height values manually
    h = height;//UPDATE, these MUST be P.O.T.

    unsigned error = lodepng::decode(image,w,h,fnPtr);//lodepng's decode function will load the pixel data into image vector
    //display any errors with the texture
    if(error)
    {
        cout << "\ndecoder error " << error << ": " << lodepng_error_text(error) <<endl;
    }

    for(int i = 0; i<image.size(); i++)
    {
        printf("%i,", image.at(i));

    }

    printf("\nImage size is %i", image.size());

    //image now contains our pixeldata. All ready for OpenGL to do its thing

    //let's get this texture up in the video memory
    texGLInit();
}

void Texture::texGLInit()
{
    //WHERE YOU LEFT OFF: glGenTextures isn't assigning an ID to textures. it stays at zero the whole time
    //i believe this is why it's been rendering white
    glGenTextures(1, &textures);
    printf("\ntexture = %u", textures);
    glBindTexture(GL_TEXTURE_2D, textures);//evrything we're about to do is about this texture
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    //glDisable(GL_COLOR_MATERIAL);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,w,h,0, GL_RGBA, GL_UNSIGNED_BYTE, &image);
    //we COULD free the image vectors memory right about now.


}

void Texture::draw(point centerPoint, point dimensions)
{
    glEnable(GL_TEXTURE_2D);
    printf("\nDrawing block at (%f, %f)",centerPoint.x, centerPoint.y);
    glBindTexture(GL_TEXTURE_2D, textures);//bind the texture
    //create a quick vertex array for the primitive we're going to bind the texture to
    printf("TexID = %u",textures);
    GLfloat vArray[8] = 
    {
        centerPoint.x-(dimensions.x/2), centerPoint.y-(dimensions.y/2),//bottom left i0
        centerPoint.x-(dimensions.x/2), centerPoint.y+(dimensions.y/2),//top left i1
        centerPoint.x+(dimensions.x/2), centerPoint.y+(dimensions.y/2),//top right i2
        centerPoint.x+(dimensions.x/2), centerPoint.y-(dimensions.y/2)//bottom right i3
    };

    //create a quick texture array (we COULD create this on the heap rather than creating/destoying every cycle)
    GLfloat tArray[8] = 
    {
        0.0f,0.0f, //0
        0.0f,1.0f, //1
        1.0f,1.0f, //2
        1.0f,0.0f //3
    };

    //and finally.. the index array...remember, we draw in triangles....(and we'll go CW)
    GLubyte iArray[6] =
    {
        0,1,2,
        0,2,3
    };

    //Activate arrays
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    //Give openGL a pointer to our vArray and tArray
    glVertexPointer(2, GL_FLOAT, 0, &vArray[0]);
    glTexCoordPointer(2, GL_FLOAT, 0, &tArray[0]);

    //Draw it all
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &iArray[0]);

    //glDrawArrays(GL_TRIANGLES,0,6);

    //Disable the vertex arrays
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_2D);
    //done!

    /*glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);
        glVertex2f(centerPoint.x-(dimensions.x/2), centerPoint.y-(dimensions.y/2));
    glTexCoord2f(0.0f,1.0f);
        glVertex2f(centerPoint.x-(dimensions.x/2), centerPoint.y+(dimensions.y/2));
    glTexCoord2f(1.0f,1.0f);
        glVertex2f(centerPoint.x+(dimensions.x/2), centerPoint.y+(dimensions.y/2));
    glTexCoord2f(1.0f,0.0f);
        glVertex2f(centerPoint.x+(dimensions.x/2), centerPoint.y-(dimensions.y/2));
    glEnd();*/
}



Texture::Texture(void)
{
}
Texture::~Texture(void)
{
}

我还将包括主类的 init,在此之前我会在其中进行更多的 OGL 设置。

void init(void)
{
    printf("\n......Hello Guy. \n....\nInitilising");
    glMatrixMode(GL_PROJECTION);    
    glLoadIdentity();
    gluOrtho2D(0,XSize,0,YSize);
    glEnable(GL_TEXTURE_2D);
    myBlock = new Block(0,0,offset);
    glClearColor(0,0.4,0.7,1);


    glLineWidth(2);         // Width of the drawing line
    glMatrixMode(GL_MODELVIEW); 
    glDisable(GL_DEPTH_TEST);
    printf("\nInitialisation Complete");

}

更新:在我第一次设置 OpenGL 窗口的地方添加主函数。

int main(int argc, char** argv) 
{
  glutInit(&argc, argv);    // GLUT Initialization 
  glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); // Initializing the Display mode
  glutInitWindowSize(800,600);  // Define the window size
  glutCreateWindow("Gem Miners");   // Create the window, with caption.
        printf("\n========== McLeanTech Systems =========\nBecoming Sentient\n...\n...\n....\nKILL\nHUMAN\nRACE \n");
  init();   // All OpenGL initialization


  //-- Callback functions ---------------------
  glutDisplayFunc(display);
  glutKeyboardFunc(mykey);
  glutSpecialFunc(processSpecialKeys);
  glutSpecialUpFunc(processSpecialUpKeys);
  //glutMouseFunc(mymouse);


  glutMainLoop();   // Loop waiting for event 
}
4

1 回答 1

14
于 2012-12-13T20:16:27.863 回答