OpenGL 使纹理透明 VBO

Posted

技术标签:

【中文标题】OpenGL 使纹理透明 VBO【英文标题】:OpenGL Make Texture Transparent VBO 【发布时间】:2017-11-19 22:11:06 【问题描述】:

我一直在研究如何使气泡纹理透明,但没有找到适合我的代码的任何内容。我试过glColor4f(),但我可能把它放错了地方。我是 openGL 的初学者,我已经获得了一个基本代码,我需要在其中添加其他对象以制作 2D 场景。我也不完全知道每一行的作用。 这些是相关的代码:

// Globals
GLuint locT; // location of "T" uniform variable in myShaderProgram
GLuint locT2;


// Textures
GLuint myBubblesTexture = 0;

// Shader program object for applying textures to our shapes
GLuint myShaderProgram;

// Vertex Buffer Object IDs for the ground texture object
GLuint bubblesPosVBO, bubblesColourVBO, bubblesTexCoordVBO, bubblesIndicesVBO;


// 1) Position Array - Store vertices as (x,y) pairs
static GLfloat bubblesVertices[] = 

    -0.2f, -0.2f,
    -0.2f, 0.2f,
    0.2f, -0.2f,
    0.2f, 0.2f
;
// 2) Colour Array - Store RGB values as unsigned bytes
static GLubyte bubblesColors[] = 

    255, 0, 0, 255,
    255, 255, 0, 255,
    0, 255, 0, 255,
    0, 255, 255, 255

;
// 3) Texture coordinate array (store uv coordinates as floating point values)
static float bubblesTextureCoords[] = 

    0.0f, 1.0f,
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f

;
// 4) Index Array - Store indices to quad vertices - this determines the order the vertices are to be processed
static GLubyte bubblesVertexIndices[] =  0, 1, 2, 3 ;


void init(int argc, char* argv[]);
void setupBubblesTextureVBO(void);
void display(void);
void drawTexturedBubblesVBO(void);

int _tmain(int argc, char* argv[]) 


    init(argc, argv);

    glutMainLoop();

    // Shut down COM
    shutdownCOM();

    return 0;



void init(int argc, char* argv[]) 

    // Initialise COM so we can use Windows Imaging Component
    initCOM();

    // Initialise FreeGLUT
    glutInit(&argc, argv);

    glutInitContextVersion(3, 3);
    glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

    glutInitWindowSize(1200, 800);
    glutInitWindowPosition(64, 64);
    glutCreateWindow("Funky Fish");

    // Register callback functions
    glutDisplayFunc(display);

    // Initialise GLEW library
    GLenum err = glewInit();

    // Setup colour to clear the window
    glClearColor(0.2f, 0.2f, 0.8f, 0.0f);
    glLineWidth(9.0f);

    //Load textures
    myBubblesTexture = fiLoadTextureA("bubbles.png");

    //Shader setup 
    myShaderProgram = setupShaders(string("Shaders\\basic_vertex_shader.txt"), string("Shaders\\basic_fragment_shader.txt"));

    // Get uniform location of "T" variable in shader program (we'll use this in the play function to give the uniform variable "T" a value)
    locT = glGetUniformLocation(myShaderProgram, "T");

    //Setup the bubbles using VBO
    setupBubblesTextureVBO();


// our bubbles
void setupBubblesTextureVBO(void) 

    // setup VBO for the quad object position data
    glGenBuffers(1, &bubblesPosVBO);
    glBindBuffer(GL_ARRAY_BUFFER, bubblesPosVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(bubblesVertices), bubblesVertices, GL_STATIC_DRAW);

    // setup VBO for the quad object colour data
    glGenBuffers(1, &bubblesColourVBO);
    glBindBuffer(GL_ARRAY_BUFFER, bubblesColourVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(bubblesColors), bubblesColors, GL_STATIC_DRAW);

    // setup VBO for the quad object texture coord data
    glGenBuffers(1, &bubblesTexCoordVBO);
    glBindBuffer(GL_ARRAY_BUFFER, bubblesTexCoordVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(bubblesTextureCoords), bubblesTextureCoords, GL_STATIC_DRAW);

    // setup quad vertex index array
    glGenBuffers(1, &bubblesIndicesVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bubblesIndicesVBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(bubblesVertexIndices), bubblesVertexIndices, GL_STATIC_DRAW);


void display(void) 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // draw our bubble
    drawTexturedBubblesVBO();
    glutSwapBuffers();


void drawTexturedBubblesVBO(void) 

    glUseProgram(myShaderProgram);

    glEnable(GL_TEXTURE_2D);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    // Move our bubble to the centre of the screen
    GUMatrix4 T = GUMatrix4::translationMatrix(0.0f, 0.0f, 0.0f);
    glUniformMatrix4fv(locT, 1, GL_FALSE, (GLfloat*)&T);


    // Bind each vertex buffer and enable
    // The data is still stored in the GPU but we need to set it up (which also includes validation of the VBOs behind-the-scenes)

    // Bind texture
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, myBubblesTexture);
    glUniform1i(glGetUniformLocation(myShaderProgram, "texture"), 0);
    glEnable(GL_TEXTURE_2D);

    glBindBuffer(GL_ARRAY_BUFFER, bubblesPosVBO);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, bubblesColourVBO);
    glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (const GLvoid*)0);
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, bubblesTexCoordVBO);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
    glEnableVertexAttribArray(2);


    // Bind the index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bubblesIndicesVBO);

    // Draw the object - same function call as used for vertex arrays but the last parameter is interpreted as an offset into the currently bound index buffer (set to 0 so we start drawing from the beginning of the buffer).
    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (GLvoid*)0);
    //  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glDisable(GL_TEXTURE_2D);

    // use to force disable our shaderprogram
    // glUseProgram(0);


【问题讨论】:

【参考方案1】:

代码看起来不错:

您的纹理是否有 Alpha 通道? 您的 OpenGL 上下文像素格式是否具有 Alpha 通道缓冲区? 您想要什么样的透明度(整个纹理具有相同的透明度,或者应该对透明度进行调制)?

glColor4f(1.0,1.0,1.0,alpha) 仅在您的纹理配置为由 glColor 调制并且设置了非零 Alpha 通道时才有效,因此您需要添加:

glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

绑定纹理后调用以使其工作。

如果您没有 alpha 通道(纹理或像素格式),您可以使用:

glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);

还请看:

OpenGL - How to create Order Independent transparency?

【讨论】:

以上是关于OpenGL 使纹理透明 VBO的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL正确附加纹理

透明四边形上的OpenGL DECAL纹理?

OpenGL透明纹理问题

渲染具有透明度的纹理时 OpenGL 不需要的像素

OpenGL渲染到纹理透明度问题

OpenGL:渲染具有大量纹理透明度的模型,没有绘制顺序?