在 OpenGL 中将四边形分层
Layering quads on top of each other in OpenGL
我正在使用 C++ 使用 OpenGL 创建一个基于 2D 图块的战术角色扮演游戏,但我在 tiles/quads 分层时遇到了困难。我想能够说一个树纹理四边形,图像是树和一个周围透明的 alpha 层,在一个不透明的草纹理四边形之上。我需要让树出现在草地上,草通过树图像的 alpha 层显示。
到目前为止,我一直在搞乱 glDisable(GL_DEPTH_TEST)、glEnable(GL_BLEND) 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 但没有运气远的。我最终得到了一棵黑色背景的树,而不是草地砖。有人能给我指出正确的方向吗?
下面是我的渲染函数和初始化函数,它们可能是最相关的。
void View::initialize() {
updateProjection(window);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 1.0);
camera = new Camera(Vector3(-1, -3, 25), Vector3(-1, -3, 0), Vector3(0, 1, 0));
loadImages();
initShaders();
//needed for transparency?
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void View::render(World* worldTemp)
{
Matrix4 mvpMatrix, viewMatrix, modelMatrix;
Matrix4 XAxisRotationMatrix, YAxisRotationMatrix, ZAxisRotationMatrix;
input->handleInput(camera, worldTemp->getPlayer());
worldTemp->timerTick();
worldTemp->clearFog();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen and Depth Buffer
XAxisRotationMatrix = Matrix4::IDENTITY;
YAxisRotationMatrix = Matrix4::IDENTITY;
ZAxisRotationMatrix = Matrix4::IDENTITY;
XAxisRotationMatrix.rotate(Vector3(1.0, 0.0, 0.0), XAxisRotationAngle);
YAxisRotationMatrix.rotate(Vector3(0.0, 1.0, 0.0), YAxisRotationAngle);
ZAxisRotationMatrix.rotate(Vector3(0.0, 0.0, 1.0), ZAxisRotationAngle);
viewMatrix = camera->getViewMatrix();
modelMatrix = translationMatrix(Vector3(-4, 2, 0));
mvpMatrix = projectionMatrix * viewMatrix * modelMatrix;
//Spit out the map
for (int i = 0; i < 100; i++){
for (int j = 0; j < 100; j++){
for (int t = 0; t < 5; t++){
if (worldTemp->getTile(i, j)->isOccupied() == true) {
if (worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getFog()){
worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix, true);
}
else{
worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix);
}
}
}
}
}
//Place the player
worldTemp->getPlayer()->getEntityQuad()->render_self(mvpMatrix);
renderEnemies();
glutSwapBuffers(); //works with GL_DOUBLE. use glFlush(); instead, if using GL_SINGLE
}
基本上,在 2d 游戏中,分层是通过渲染调用的顺序完成的。如果你想要层A在层B之上,你应该先渲染层B,然后层A。
您使用的混合函数应该取决于图像的纹理格式。 alpha有两种常见的格式:
预乘 alpha
直阿尔法
更多相关信息:https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre
opengl es2 premultiplied vs straight alpha + blending
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); is for premultiplied alpha, and it should work well if you use colors as is. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); is for straight alpha.
我正在使用 C++ 使用 OpenGL 创建一个基于 2D 图块的战术角色扮演游戏,但我在 tiles/quads 分层时遇到了困难。我想能够说一个树纹理四边形,图像是树和一个周围透明的 alpha 层,在一个不透明的草纹理四边形之上。我需要让树出现在草地上,草通过树图像的 alpha 层显示。
到目前为止,我一直在搞乱 glDisable(GL_DEPTH_TEST)、glEnable(GL_BLEND) 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 但没有运气远的。我最终得到了一棵黑色背景的树,而不是草地砖。有人能给我指出正确的方向吗?
下面是我的渲染函数和初始化函数,它们可能是最相关的。
void View::initialize() {
updateProjection(window);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 1.0);
camera = new Camera(Vector3(-1, -3, 25), Vector3(-1, -3, 0), Vector3(0, 1, 0));
loadImages();
initShaders();
//needed for transparency?
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void View::render(World* worldTemp)
{
Matrix4 mvpMatrix, viewMatrix, modelMatrix;
Matrix4 XAxisRotationMatrix, YAxisRotationMatrix, ZAxisRotationMatrix;
input->handleInput(camera, worldTemp->getPlayer());
worldTemp->timerTick();
worldTemp->clearFog();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen and Depth Buffer
XAxisRotationMatrix = Matrix4::IDENTITY;
YAxisRotationMatrix = Matrix4::IDENTITY;
ZAxisRotationMatrix = Matrix4::IDENTITY;
XAxisRotationMatrix.rotate(Vector3(1.0, 0.0, 0.0), XAxisRotationAngle);
YAxisRotationMatrix.rotate(Vector3(0.0, 1.0, 0.0), YAxisRotationAngle);
ZAxisRotationMatrix.rotate(Vector3(0.0, 0.0, 1.0), ZAxisRotationAngle);
viewMatrix = camera->getViewMatrix();
modelMatrix = translationMatrix(Vector3(-4, 2, 0));
mvpMatrix = projectionMatrix * viewMatrix * modelMatrix;
//Spit out the map
for (int i = 0; i < 100; i++){
for (int j = 0; j < 100; j++){
for (int t = 0; t < 5; t++){
if (worldTemp->getTile(i, j)->isOccupied() == true) {
if (worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getFog()){
worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix, true);
}
else{
worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix);
}
}
}
}
}
//Place the player
worldTemp->getPlayer()->getEntityQuad()->render_self(mvpMatrix);
renderEnemies();
glutSwapBuffers(); //works with GL_DOUBLE. use glFlush(); instead, if using GL_SINGLE
}
基本上,在 2d 游戏中,分层是通过渲染调用的顺序完成的。如果你想要层A在层B之上,你应该先渲染层B,然后层A。
您使用的混合函数应该取决于图像的纹理格式。 alpha有两种常见的格式:
预乘 alpha
直阿尔法
更多相关信息:https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre
opengl es2 premultiplied vs straight alpha + blending
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); is for premultiplied alpha, and it should work well if you use colors as is. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); is for straight alpha.