OpenGL透明度是不透明的
OpenGL transperency is opaque
我知道之前有人问过这个问题,但是 none 的其他答案有助于解决我的具体问题。我有一个简单的 C++ 和 OpenGL 程序,我正在其中绘制带纹理的立方体。纹理的透明度显示为黑色。我不确定我做错了什么
#include <GL/glew.h>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include <SFML/Window.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "shader.h"
#include "mesh.h"
int main(int argc, char* argv[])
{
sf::Window window(sf::VideoMode(640, 480), "OpenGL Test", sf::Style::Close);
sf::Event event;
glewInit();
//clear color
glEnable(GL_TEXTURE_2D);
glClearColor(0.8, 0.8, 0.8, 1);
glEnable(GL_BLEND);
glAlphaFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//view and projection matrix
glm::mat4 projection = glm::perspective<float>(glm::radians(45.f), 640.f / 480.f, 0.1f, 100.f); //fov, ratio, display range min, display range max
glm::mat4 view = glm::lookAt(
glm::vec3(4, 3, 3), //camera position
glm::vec3(0, 0, 0), //camera looking at this position
glm::vec3(0, 1, 0) //head is up
);
//shader
Shader shader;
shader.loadVertex("testShader.vs");
shader.loadFragment("testShader.fs");
shader.link();
float points[] = {
-0.8, -0.8, -0.8,
-0.8, 0.8, -0.8,
0.8, 0.8, -0.8,
0.8, -0.8, -0.8,
-0.8, 0.8, 0.8,
0.8, 0.8, 0.8,
-0.8, -0.8, 0.8,
0.8, -0.8, 0.8
};
//irrelevent for now...
float colors[] = {
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 1,
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 1
};
float texCoords[] = {
0, 1,
0, 0,
1, 0,
1, 1,
0, 1,
1, 1,
0, 0,
1, 0
};
unsigned int elements[] = {
0, 1, 2, 2, 3, 0, //front
1, 4, 5, 5, 2, 1, //top
4, 6, 7, 7, 5, 4, //back
6, 0, 3, 3, 7, 6, //bottom
3, 2, 5, 5, 7, 3, //right
6, 4, 1, 1, 0, 6 //left
};
Mesh mesh(&projection, &view, 8, points, 36, elements, texCoords, colors);
mesh.setShader(shader);
while (window.isOpen())
{
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
//resize viewport if window is resized
else if (event.type == sf::Event::Resized)
glViewport(0, 0, event.size.width, event.size.height);
}
glClear(GL_COLOR_BUFFER_BIT);
mesh.draw();
window.display();
}
return 0;
}
我不会 post 我的所有代码,因为它在单独的 类 中,但这里是加载纹理的代码,以防它很重要。
//texture
sf::Image image;
image.loadFromFile("Numel.png");
textureID = 0;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, false, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
这是我的着色器:
(顶点着色器)
#version 450
in vec3 v_pos;
in vec3 v_color;
in vec2 v_texCoord;
out vec3 color;
out vec2 texCoord;
uniform mat4 mvp;
void main()
{
color=v_color;
texCoord=v_texCoord;
gl_Position=mvp*vec4(v_pos, 1.0);
}
(片段着色器)
#version 450
in vec3 color;
in vec2 texCoord;
out vec4 f_color;
uniform sampler2D texture;
void main()
{
f_color=texture2D(texture, texCoord);
}
澄清一下,我的图像是 PNG,它是 256x256(2 的幂大小),并且它实际上具有透明像素。
您从未设置混合功能。您可能认为您使用以下调用:
glAlphaFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
但那是不同的东西。此调用将用于设置 alpha 测试功能。如果您不知道那是什么……请不要打扰。 Alpha 测试是一项已弃用的功能,OpenGL 核心配置文件不再支持它。实际上在某些情况下它在固定功能 OpenGL 中非常有用,但这些可以很容易地通过可编程管道实现,因此不再需要专用的 alpha 测试。
您要调用的设置混合函数是:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
如果您的 OpenGL 代码没有按预期工作,请确保您始终 调用 glGetError()
。在这种情况下,您会立即得到一个错误,因为 glAlphaFunc()
采用与 glBlendFunc()
截然不同的参数,因此 glGetError()
会立即返回 GL_INVALID_ENUM
。
我知道之前有人问过这个问题,但是 none 的其他答案有助于解决我的具体问题。我有一个简单的 C++ 和 OpenGL 程序,我正在其中绘制带纹理的立方体。纹理的透明度显示为黑色。我不确定我做错了什么
#include <GL/glew.h>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include <SFML/Window.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "shader.h"
#include "mesh.h"
int main(int argc, char* argv[])
{
sf::Window window(sf::VideoMode(640, 480), "OpenGL Test", sf::Style::Close);
sf::Event event;
glewInit();
//clear color
glEnable(GL_TEXTURE_2D);
glClearColor(0.8, 0.8, 0.8, 1);
glEnable(GL_BLEND);
glAlphaFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//view and projection matrix
glm::mat4 projection = glm::perspective<float>(glm::radians(45.f), 640.f / 480.f, 0.1f, 100.f); //fov, ratio, display range min, display range max
glm::mat4 view = glm::lookAt(
glm::vec3(4, 3, 3), //camera position
glm::vec3(0, 0, 0), //camera looking at this position
glm::vec3(0, 1, 0) //head is up
);
//shader
Shader shader;
shader.loadVertex("testShader.vs");
shader.loadFragment("testShader.fs");
shader.link();
float points[] = {
-0.8, -0.8, -0.8,
-0.8, 0.8, -0.8,
0.8, 0.8, -0.8,
0.8, -0.8, -0.8,
-0.8, 0.8, 0.8,
0.8, 0.8, 0.8,
-0.8, -0.8, 0.8,
0.8, -0.8, 0.8
};
//irrelevent for now...
float colors[] = {
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 1,
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 1
};
float texCoords[] = {
0, 1,
0, 0,
1, 0,
1, 1,
0, 1,
1, 1,
0, 0,
1, 0
};
unsigned int elements[] = {
0, 1, 2, 2, 3, 0, //front
1, 4, 5, 5, 2, 1, //top
4, 6, 7, 7, 5, 4, //back
6, 0, 3, 3, 7, 6, //bottom
3, 2, 5, 5, 7, 3, //right
6, 4, 1, 1, 0, 6 //left
};
Mesh mesh(&projection, &view, 8, points, 36, elements, texCoords, colors);
mesh.setShader(shader);
while (window.isOpen())
{
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
//resize viewport if window is resized
else if (event.type == sf::Event::Resized)
glViewport(0, 0, event.size.width, event.size.height);
}
glClear(GL_COLOR_BUFFER_BIT);
mesh.draw();
window.display();
}
return 0;
}
我不会 post 我的所有代码,因为它在单独的 类 中,但这里是加载纹理的代码,以防它很重要。
//texture
sf::Image image;
image.loadFromFile("Numel.png");
textureID = 0;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, false, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
这是我的着色器:
(顶点着色器)
#version 450
in vec3 v_pos;
in vec3 v_color;
in vec2 v_texCoord;
out vec3 color;
out vec2 texCoord;
uniform mat4 mvp;
void main()
{
color=v_color;
texCoord=v_texCoord;
gl_Position=mvp*vec4(v_pos, 1.0);
}
(片段着色器)
#version 450
in vec3 color;
in vec2 texCoord;
out vec4 f_color;
uniform sampler2D texture;
void main()
{
f_color=texture2D(texture, texCoord);
}
澄清一下,我的图像是 PNG,它是 256x256(2 的幂大小),并且它实际上具有透明像素。
您从未设置混合功能。您可能认为您使用以下调用:
glAlphaFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
但那是不同的东西。此调用将用于设置 alpha 测试功能。如果您不知道那是什么……请不要打扰。 Alpha 测试是一项已弃用的功能,OpenGL 核心配置文件不再支持它。实际上在某些情况下它在固定功能 OpenGL 中非常有用,但这些可以很容易地通过可编程管道实现,因此不再需要专用的 alpha 测试。
您要调用的设置混合函数是:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
如果您的 OpenGL 代码没有按预期工作,请确保您始终 调用 glGetError()
。在这种情况下,您会立即得到一个错误,因为 glAlphaFunc()
采用与 glBlendFunc()
截然不同的参数,因此 glGetError()
会立即返回 GL_INVALID_ENUM
。