我试着画一个半透明的盒子,里面有不透明的东西。类似这样:
的数据
对于半透明的盒子,我也创建了一个纹理(whitebg.jpg),我想应用:
的
到目前为止,这是我尝试的:
主要功能
private static void CreateItems(List<Items> packedItems)
{
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
Glut.glutInitWindowSize(width, height);
Glut.glutCreateWindow("pack");
Glut.glutIdleFunc(OnRenderFrame);
Glut.glutDisplayFunc(OnDisplay);
Glut.glutKeyboardFunc(OnKeyboardDown);
Glut.glutKeyboardUpFunc(OnKeyboardUp);
Glut.glutMouseWheelFunc(OnMouseWheel);
Glut.glutCloseFunc(OnClose);
Glut.glutReshapeFunc(OnReshape);
Gl.Disable(EnableCap.DepthTest);
Gl.Enable(EnableCap.Blend);
Gl.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
program = new ShaderProgram(VertexShader, FragmentShader);
program.Use();
program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));
program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 10), Vector3.Zero, new Vector3(0, 1, 0)));
program["light_direction"].SetValue(new Vector3(0, 0, 1));
program["enable_lighting"].SetValue(lighting);
bgTexture = new Texture("whitebg.jpg");
}
字符串
- 酒店GLUT. ALIDLEFUNC**
private static void OnRenderFrame()
{
watch.Stop();
float deltaTime = (float)watch.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency;
watch.Restart();
// perform rotation of the cube depending on the keyboard state
if (autoRotate)
{
xangle += deltaTime / 2;
yangle += deltaTime;
}
if (right) yangle += deltaTime;
if (left) yangle -= deltaTime;
if (up) xangle -= deltaTime;
if (down) xangle += deltaTime;
// set up the viewport and clear the previous depth and color buffers
Gl.Viewport(0, 0, width, height);
Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// make sure the shader program and texture are being used
Gl.UseProgram(program);
Gl.BindTexture(bgTexture);
// set up the model matrix and draw the cube
program["model_matrix"].SetValue(Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle));
program["enable_lighting"].SetValue(lighting);
for (int i = 0; i < virtual_items.Count; i++)
{
Gl.BindBufferToShaderAttribute(virtual_items[i], program, "vertexPosition");
Gl.BindBufferToShaderAttribute(virtual_items_color[i], program, "vertexColor");
Gl.BindBuffer(virtual_items_quads[i]);
Gl.DrawElements(BeginMode.Quads, virtual_items_quads[i].Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
}
Gl.BindBufferToShaderAttribute(virtual_container, program, "vertexPosition");
Gl.BindBufferToShaderAttribute(virtual_container_normals, program, "vertexNormal");
Gl.BindBufferToShaderAttribute(virtual_container_UV, program, "vertexUV");
Gl.BindBuffer(virtual_container_Quads);
Gl.DrawElements(BeginMode.Quads, virtual_container_Quads.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
Glut.glutSwapBuffers();
}
型
但得到的结果是不是我所期望的。纹理是适用于框,也在里面的项目。这里有一个例子,我有一个框(2x1x1)和两个项目(1x1x1):
的
有没有可能只在盒子上应用纹理,并保持物品的真实的不透明颜色,就像第一张图片一样?
1条答案
按热度按时间wnvonmuf1#
在你的初始化方法“测试项目”中,你正在禁用深度测试并启用混合:
字符串
这些状态在OnRenderFrame方法中不会改变。但是如果你想让项目不透明,那么你必须在绘制它们之前禁用混合。当然,在绘制半透明容器之前重新启用它。
如果你想只在背景中显示半透明的盒子,而项目不受它的影响。那么你应该使用命令
glDepthMask(false)
禁用深度缓冲来渲染它。然后你使用glDepthMask(true)
重新打开它。此外,您还需要启用深度测试,因为否则项目可能无法正确显示。即,远离相机的面可能会与较近的面重叠。