Освещение с использованием прозрачностиC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Освещение с использованием прозрачности

Сообщение Anonymous »

У меня есть пустая текстура и легкая текстура, маску которых я создал, используя изображения и шейдер. Я могу визуализировать прозрачное изображение поверх окна и использовать градиентный круг, чтобы «пробить дыру» в нем, но мне нужно добавить больше «градиентных кругов» в разных местах. Я в тупике. Я включил весь код, который, по моему мнению, имеет отношение к решению моей проблемы. По сути, у меня есть текстура, отображаемая поверх игровой карты, я хотел бы создать массив «Lights», чтобы замаскировать альфа-значение наложенной текстуры, источники света будут содержать свои собственные переменные x/y/z/w.< /p>
основной файл:

Код: Выделить всё

// Vec locations for the objects
glm::vec4 bgBody(0.0f, 0.0f, 600.0f, 500.0f);
glm::vec4 objectBody(20.0f, 20.0f, 100.0f, 100.0f);
glm::vec4 overlay = bgBody;
glm::vec4 light1(0.0f, 0.0f, 100.0f, 100.0f);
glm::vec4 light2(200.0f, 150.0f, 100.0f, 100.0f);

// The Glyph class
Glyph::Glyph(const glm::vec4& destRect, const glm::vec4& uvRect, GLuint Texture, float Depth, const ColorRGBA8& color , GLuint MaskTexture ) :
texture(Texture),
maskTexture(MaskTexture),
depth(Depth) {

topLeft.color = color;
topLeft.setPosition(destRect.x, destRect.y + destRect.w);
topLeft.setUV(uvRect.x, uvRect.y + uvRect.w);

bottomLeft.color = color;
bottomLeft.setPosition(destRect.x, destRect.y);
bottomLeft.setUV(uvRect.x, uvRect.y);

bottomRight.color = color;
bottomRight.setPosition(destRect.x + destRect.z, destRect.y);
bottomRight.setUV(uvRect.x + uvRect.z, uvRect.y);

topRight.color = color;
topRight.setPosition(destRect.x + destRect.z, destRect.y + destRect.w);
topRight.setUV(uvRect.x + uvRect.z, uvRect.y + uvRect.w);
}

// Compile and bind all the shader stuff.
glShaderSource(m_vertexShaderID, 1, &vertexSource, nullptr);
glShaderSource(m_fragmentShaderID, 1, &fragmentSource, nullptr);
glCompileShader(m_vertexShaderID);
glCompileShader(m_fragmentShaderID);
glBindAttribLocation(m_programID, m_numAttributes++, "vertexPosition");
glBindAttribLocation(m_programID, m_numAttributes++, "vertexColor");
glBindAttribLocation(m_programID, m_numAttributes++, "vertexUV");
glAttachShader(m_programID, m_vertexShaderID);
glAttachShader(m_programID, m_fragmentShaderID);
glLinkProgram(m_programID);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
glBindVertexArray(0);

/****************************LOOPING CODE********************************/

// Enable all the attributes we added with addAttribute.
for (int i = 0; i < m_numAttributes; i++) { glEnableVertexAttribArray(i); }
GLint location = glGetUniformLocation(m_programID, "mySampler");
glUniform1i(location, 0);
GLint location1 = glGetUniformLocation(m_programID, "myMask");
glUniform1i(location1, 1);
GLint UseMask = glGetUniformLocation(m_programID, "useMask");
glUniform1i(UseMask, 0);
glActiveTexture(GL_TEXTURE0);

_renderBatches.clear();
_glyphs.clear();

_glyphs.emplace_back(bgBody, UV, bgTexture.id, 0.0f, ColorRGBA8(255, 255, 255,255)); // BG
_glyphs.emplace_back(objectBody, UV, objectTexture.id, 0.0f, ColorRGBA8(255, 255, 255,255) ); // Object
_glyphs.emplace_back(overlay, UV, blankTexture.id, 0.0f, ColorRGBA8(0, 0, 0, 200), lightTexture.id); // BG

//This can be used instead to draw the overlay with the 2 lights under it where i want the light to come through
//_glyphs.emplace_back(light1, UV, lightTexture.id, 0.0f, ColorRGBA8(0, 0, 0, 200)); // BG
//_glyphs.emplace_back(light2, UV, lightTexture.id, 0.0f, ColorRGBA8(0, 0, 0, 200)); // BG
//_glyphs.emplace_back(overlay, UV, blankTexture.id, 0.0f, ColorRGBA8(0, 0, 0, 200)); // BG

// Create variables.
int offset = 0; // current offset
int cv = 0; // current vertex
// Number of vertices we are working with.
int numVerts = 6;

//Add the first batch
_renderBatches.emplace_back(offset, numVerts, _glyphPointers[0]->texture , _glyphPointers[0]->maskTexture);
vertices[cv++] = _glyphPointers[0]->topLeft;
vertices[cv++] = _glyphPointers[0]->bottomLeft;
vertices[cv++] = _glyphPointers[0]->bottomRight;
vertices[cv++] = _glyphPointers[0]->bottomRight;
vertices[cv++] = _glyphPointers[0]->topRight;
vertices[cv++] = _glyphPointers[0]->topLeft;
offset += numVerts;

//Add all the rest of the glyphs
for (size_t cg = 1; cg < _glyphPointers.size();  cg++) {
// Check if this glyph can be part of the current batch
if ( (_glyphPointers[cg]->texture != _glyphPointers[cg - 1]->texture) || (_glyphPointers[cg]->maskTexture != _glyphPointers[cg - 1]->maskTexture) ) {
// Make a new batch
_renderBatches.emplace_back(offset, numVerts, _glyphPointers[cg]->texture, _glyphPointers[cg]->maskTexture);
}
else {
// If its part of the current batch, just increase numVertices
_renderBatches.back().numVertices += numVerts;
}
vertices[cv++] = _glyphPointers[cg]->topLeft;
vertices[cv++] = _glyphPointers[cg]->bottomLeft;
vertices[cv++] = _glyphPointers[cg]->bottomRight;
vertices[cv++] = _glyphPointers[cg]->bottomRight;
vertices[cv++] = _glyphPointers[cg]->topRight;
vertices[cv++] = _glyphPointers[cg]->topLeft;
offset += numVerts;
}

glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vertex), vertices.data());
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(_vao);

// Draw the render batches.
for (size_t i = 0; i < _renderBatches.size(); i++) {
if (_renderBatches[i].maskTexture) {
glUniform1i(UseMask, 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _renderBatches[i].maskTexture);
}
else {
glUniform1i(UseMask, 0);
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _renderBatches[i].texture);
glDrawArrays(GL_TRIANGLES, _renderBatches[i].offset, _renderBatches[i].numVertices);
}

// Unbind.
glBindVertexArray(0);
};
фрагмент шейдера:

Код: Выделить всё

#version 130
in vec2 fragmentPosition;
in vec4 fragmentColor;
in vec2 fragmentUV;
//in vec2 maskUV;

uniform sampler2D mySampler;
uniform sampler2D myMask;
uniform bool useMask;

out vec4 color;

void main() {

vec4 textureColor = texture(mySampler, fragmentUV);
if (useMask) {
vec4 MaskAlpha = texture(myMask, fragmentUV);
vec4 test = fragmentColor*textureColor;
test.a *= MaskAlpha.a;
color = test;
} else {
vec4 test = fragmentColor*textureColor;
color = test;
}
}
Шейдер верт:

Код: Выделить всё

#version 130
in vec2 vertexPosition;
in vec4 vertexColor;
in vec2 vertexUV;

out vec2 fragmentPosition;
out vec4 fragmentColor;
out vec2 fragmentUV;

uniform mat4 P;

void main() {
gl_Position.xy = (P * vec4(vertexPosition, 0.0, 1.0)).xy;

gl_Position.z = 0.0;

gl_Position.w = 1.0;

fragmentPosition = vertexPosition;

fragmentColor = vertexColor;

fragmentUV = vertexUV;
}
Результат: здесь происходит то, что текстура света передается в текстуру наложения в качестве маски, однако она соответствует координатам x/y/Width/Height наложения. сам. Он выполняет свою работу, маскируя альфа-дыру через наложенную текстуру.
Изображение

Желаемый результат (Вроде того): я визуализирую наложение поверх двух индивидуально визуализированных световых текстур.
Изображение

Я создал реальный желаемый доход с помощью редактора изображений, показывающего два источника света, проходящие через наложение, раскрывающее карта внизу. По сути, действует как система тумана войны.
Изображение

Можно ли создать один идентификатор текстуры из двух источников света и передать его в качестве маски?
Все работает хорошо, я просто не знаю, как это применить с несколько изображений кругов и координаты, которые будут служить маской для прозрачного наложения.

Подробнее здесь: https://stackoverflow.com/questions/792 ... ansparency
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»