我一直在努力制作一个小小的着色器。 它完美地工作,我的意思是,光线应该按照预期的方式消失,它是围绕着我的角色移动的一个圆圈。 只有当调整大小事件不存在时,它才可能是完美的。
当SFML调整窗口大小时,它会扩大所有内容,但是会以一种奇怪的方式。它扩大了所有但着色器。 我试图调整窗口大小(我喜欢调整像素图形游戏的大小,我觉得它最漂亮。所以我不想阻止调整大小的事件。)
这是我的着色器:
with open ('dict_output.csv', 'r') as f:
reader = csv.reader(f)
columns = next(reader)
#Strips white space in header
columns = [h.strip() for h in columns]
#reader = csv.DictReader(f, fieldnames=columns)
for row in reader:
print(row)
con = sqlite3.connect("city_spec.db")
cursor = con.cursor()
#Inserts data from csv into table in sql database.
query = 'insert into MyTable({0}) values ({1})'
query = query.format(','.join(columns), ','.join('?' * len(columns)))
print(query)
cursor = con.cursor()
for row in reader:
cursor.execute(query, row)
#cursor.commit()
con.commit()
con.close()
所以,问题是,我的窗口显示为1280 x 736(适合32x32纹理),我有一个1920 x 1080显示器。当我放大窗口以适应1920 x 1080(包括标题栏)时,整个事情正确调整大小,一切都很好,但着色器现在是1920x1080(减去标题栏)。因此着色器需要不同的坐标(假设x = 32,y = 0,对于着色器,x = 48 y = 0)。
所以我想知道,是否可以用整个窗口放大着色器?我应该使用类似事件吗?
感谢您的回答^^
编辑:这是一些照片: 所以这是在它调整大小之前的浅色着色器(它到处都是黑暗但在播放器上,就像它应该的那样)。 然后我调整窗口大小,播放器不移动,纹理适合整个窗口,但光线移动。所以,为了正确解释,当我调整窗口大小时,我希望所有东西都适合窗口,所以它充满了纹理,但是当我这样做时,给我的着色器的坐标是在调整大小之前的坐标,如果我移动它就好像我没有调整窗口大小一样,所以光线再也不会出现在我的播放器上了。
我不确定它更清楚,但我尽力了。
EDIT2:这是调用着色器的代码:
uniform vec3 light;
void main(void) {
float distance = sqrt(pow(gl_FragCoord.x - light.x, 2) + pow(gl_FragCoord.y - light.y, 2));
float alpha = 1.;
if (distance <= light.z) {
alpha = (1.0 / light.z) * distance;
}
gl_FragColor = vec4(0., 0., 0., alpha);
}
答案 0 :(得分:1)
您显示的代码片段实际上只更新着色器坐标(从快速一瞥看起来很好)。这个错误最有可能发生在您实际绘制的地方。
我会使用一种完全不同的方法,因为一旦你渲染了多个东西,其他光源等,你的着色器方法可能会变得相当乏味。
因此我建议你渲染一个光照贴图到渲染纹理(基本上就像“黑色=没有光,颜色=那种颜色的光”)。
我没有试图解释文本中的所有内容,而是编写了一个快速评论的示例程序,它将在屏幕上绘制一个窗口并在背景图像上移动一些光源(我使用了SFML着色器示例附带的那个) ):
除了在启动路径中有一个名为“background.jpg”的文件之外,没有任何要求。
随意复制此代码或将其用作灵感。请记住,这不是优化的,只是快速编辑以显示一般的想法。
#include <SFML/Graphics.hpp>
#include <vector>
#include <cmath>
const float PI = 3.1415f;
struct Light
{
sf::Vector2f position;
sf::Color color;
float radius;
};
int main()
{
// Let's setup a window
sf::RenderWindow window(sf::VideoMode(640, 480), "SFML Lights");
window.setVerticalSyncEnabled(false);
window.setFramerateLimit(60);
// Create something simple to draw
sf::Texture texture;
texture.loadFromFile("background.jpg");
sf::Sprite background(texture);
// Setup everything for the lightmap
sf::RenderTexture lightmapTex;
// We're using a 512x512 render texture for max. compatibility
// On modern hardware it could match the window resolution of course
lightmapTex.create(512, 512);
sf::Sprite lightmap(lightmapTex.getTexture());
// Scale the sprite to fill the window
lightmap.setScale(640 / 512.f, 480 / 512.f);
// Set the lightmap's view to the same as the window
lightmapTex.setView(window.getDefaultView());
// Drawable helper to draw lights
// We'll just have to adjust the first vertex's color to tint it
sf::VertexArray light(sf::PrimitiveType::TriangleFan);
light.append({sf::Vector2f(0, 0), sf::Color::White});
// This is inaccurate, but for demo purposes…
// This could be more elaborate to allow better graduation etc.
for (float i = 0; i <= 2 * PI; i += PI * .125f)
light.append({sf::Vector2f(std::sin(i), std::cos(i)), sf::Color::Transparent});
// Setup some lights
std::vector<Light> lights;
lights.push_back({sf::Vector2f(50.f, 50.f), sf::Color::White, 100.f });
lights.push_back({sf::Vector2f(350.f, 150.f), sf::Color::Red, 150.f });
lights.push_back({sf::Vector2f(150.f, 250.f), sf::Color::Yellow, 200.f });
lights.push_back({sf::Vector2f(250.f, 450.f), sf::Color::Cyan, 100.f });
// RenderStates helper to transform and draw lights
sf::RenderStates rs(sf::BlendAdd);
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
switch (event.type) {
case sf::Event::Closed:
window.close();
break;
}
}
bool flip = false; // simple toggle to animate differently
// Draw the light map
lightmapTex.clear(sf::Color::Black);
for(Light &l : lights)
{
// Apply all light attributes and render it
// Reset the transformation
rs.transform = sf::Transform::Identity;
// Move the light
rs.transform.translate(l.position);
// And scale it (this could be animated to create flicker)
rs.transform.scale(l.radius, l.radius);
// Adjust the light color (first vertex)
light[0].color = l.color;
// Draw the light
lightmapTex.draw(light, rs);
// To make things a bit more interesting
// We're moving the lights
l.position.x += flip ? 2 : -2;
flip = !flip;
if (l.position.x > 640)
l.position.x -= 640;
else if (l.position.x < 0)
l.position.x += 640;
}
lightmapTex.display();
window.clear(sf::Color::White);
// Draw the background / game
window.draw(background);
// Draw the lightmap
window.draw(lightmap, sf::BlendMultiply);
window.display();
}
}