gpt4 book ai didi

c++ - 简单的彩色 3D 棱镜

转载 作者:行者123 更新时间:2023-11-30 00:52:27 25 4
gpt4 key购买 nike

我开始学习 OpenGL 并将其与 SFML 2.1 一起使用以获取窗口、加载图像等。但是我遇到了简单棱镜的问题。面部部分透明,看起来很糟糕:/我正在看教程,但我不知道我的代码有什么问题......你能帮帮我吗?我读到这是 Z-Buffering 的问题。如何解决?

这是我的代码:

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>

using namespace std;

void drawCube (float x, float y, float z, float width, float height, GLuint Texture);

int main()
{
// Window
sf::RenderWindow window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(32));

// Camera
GLdouble eyex = 0;
GLdouble eyey = 0;
GLdouble eyez = 2575;

GLuint Texture = 0;
{
sf::Image Image;
if (!Image.loadFromFile("background.png"))
return EXIT_FAILURE;
glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Image.getSize().x, Image.getSize().y, 0, 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);
}

// Main loop
while (window.isOpen())
{
// Checking events
sf::Event event;
while (window.pollEvent(event))
{
// Close the window
if (event.type == sf::Event::Closed)
window.close();

// Resize the window
if (event.type == sf::Event::Resized)
glViewport(0, 0, event.size.width, event.size.height);
}

// Close the window
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
window.close();

// Clear the window
window.clear(sf::Color::White);

// Viewport
glViewport( 0, 0, window.getSize().x, window.getSize().y );

// Matrix Mode
glMatrixMode( GL_PROJECTION );

// Matrix Load Identity
glLoadIdentity();

// Perspective
gluPerspective(window.getSize().y/45.0, 1.0f*window.getSize().x/window.getSize().y, 0.0f, 100.0f);

// Clear color buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Set Matrix Mode
glMatrixMode( GL_MODELVIEW );

// Matrix Load Identity
glLoadIdentity();

// Change camera position
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
eyey -= 0.1f;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
eyey += 0.1f;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
eyex -= 0.1f;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
eyex += 0.1f;

printf("%f %f\n", eyex, eyey);

// Set the camera
gluLookAt( eyex, -eyey, eyez, eyex, -eyey, 0, 0, 1, 0 );

// RECTANGLE
/*
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture);
glColor4f( 0.0, 1.0, 0.0, 1.0f );
glScalef(1,-1,1);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(100, 200, 0.0f);
glTexCoord2f(3.333333f, 0.0f); glVertex3f(200, 200, 0.0f);
glTexCoord2f(3.333333f, 3.333333f); glVertex3f(200, 300, 0.0f);
glTexCoord2f(0.0f, 3.333333f); glVertex3f(100, 300, 0.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
*/

// Set color drawing
glColor3f( 0.0, 0.0, 0.0 );
glScalef(1,-1,1);

// Draw cube
drawCube(0.0f, 0.0f, 1000.0f, 100.0f, 100.0f, Texture);

// Flush the scene
glFlush();

// Update the window
window.display();
}
return 0;
}

void drawCube (float x, float y, float z, float width, float height, GLuint Texture)
{
width /= 2;
height /= 2;
x += width;
y += height;
y = -y;
width = -width;

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture);
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
// Top face
glVertex3f( x + width, y + height, 0.0f);
glVertex3f( x - width, y + height, 0.0f);
glVertex3f( x - width, y + height, z);
glVertex3f( x + width, y + height, z);

glColor3f(1.0f, 1.0f, 0.0f);
// Left face
glVertex3f( x - width, y + height, z);
glVertex3f( x - width, y + height, 0.0f);
glVertex3f( x - width, y - height, 0.0f);
glVertex3f( x - width, y - height, z);

glColor3f(0.0f, 1.0f, 1.0f);
// Right face
glVertex3f( x + width, y + height, 0.0f);
glVertex3f( x + width, y + height, z);
glVertex3f( x + width, y - height, z);
glVertex3f( x + width, y - height, 0.0f);

glColor3f(0.0f, 0.0f, 0.0f);
// Bottom face
glVertex3f( x + width, y - height, 0.0f);
glVertex3f( x - width, y - height, 0.0f);
glVertex3f( x - width, y - height, z);
glVertex3f( x + width, y - height, z);

glColor3f(0.0f, 1.0f, 0.0f);
// Front face
glVertex3f( x + width, y + height, z);
glVertex3f( x - width, y + height, z);
glVertex3f( x - width, y - height, z);
glVertex3f( x + width, y - height, z);
glEnd();
glDisable(GL_TEXTURE_2D);
}

这是我的结果:

最佳答案

你是对的,这个问题与 Z-Buffering 有关。

实际上我在您的代码中看到了两个问题:

  1. 并非所有硬件都支持 32 位深度缓冲区

    • 24 位深度 + 8 位模板是一种更兼容的格式,对于您的简单应用来说绰绰有余。这可以使用 sf::ContextSettings (24, 8) 请求。

  2. OpenGL 中默认禁用深度测试

    • 即使您的硬件支持 32 位深度缓冲区,仅分配深度缓冲区也是不够的。您必须在创建 sf::RenderWindow 后通过添加对 glEnable (GL_DEPTH_TEST) 的调用来自行启用它。

更新:

我第一次运行您的代码时完全错过了这一点:

// Perspective
gluPerspective(
window.getSize().y/45.0, 1.0f*window.getSize().x/window.getSize().y,
0.0f, 100.0f);
~~~~

您正在使用 0.0 作为透视投影矩阵中的近平面。这是一件非常糟糕的事情,它会完全扰乱您的深度范围,这可能是您在评论中包含的两个屏幕截图的原因。

两个平面必须是正值。如果 gluPerspective (...) 实际上是 OpenGL API 的一部分,它会在这些情况下生成 GL_INVALID_VALUE 错误。另请注意,近平面和远平面之间的距离将决定深度缓冲区的整体精度(这在 gluPerspective 的文档中进行了讨论)。

要更正此问题,请为近平面使用非常接近但不完全是 0.0 的值(即 0.1)。

关于c++ - 简单的彩色 3D 棱镜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19140924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com