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的主要内容,如果未能解决你的问题,请参考以下文章