我一直在尝试使用sampler2D array + glActiveTexture()向我的着色器发送多个纹理。 使用索引为0的GL_TEXTURE0和sampler2D数组发送的第一个纹理效果很好。但是,第二个纹理不会渲染(重复第一个纹理)。 我一直在网上搜索解决方案,直到现在都没有用。 所以,我在这里。
如果您能伸出援手,将不胜感激。如果您需要其他任何信息,请告诉我。
以下是我尝试调试的一些内容。
下面是我的主文件和一些使用的方法。
// C++
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <stdlib.h>
// OpenGL
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <FreeImage.h>
// Custom
#include "window.h"
#include "math.h"
#include "shader.h"
#include "texture.h"
using namespace std;
using namespace JDEngine;
int main()
{
Window window("Test", 800, 800);
window.SetClearColor(0.0, 0.0, 0.0, 1.0);
Shader* shader = new Shader("src/shaders/testvert.shader", "src/shaders/testfrag.shader");
shader->Enable();
shader->SetUniformMat4("pr_matrix", Mat4::Orthographic(-4,4,-4,4,-4,4));
shader->Disable();
GLfloat data[24] = {0,0,0,0,1,0,1,0,0,1,1,0, -1,-1,0,-1,0,0,0,-1,0,0,0,0};
GLfloat uv[16] = {0,0,0,1,1,0,1,1, 0,0,0,1,1,0,1,1};
GLfloat tid[8] = {0,0,0,0, 1,1,1,1}; // 0s going into GL_TEXTURE0, 1s to GL_TEXTURE1
GLuint ind[12] = {0,1,2,2,1,3, 4,5,6,6,5,7};
// For buffers & vertices
GLuint vao, vbo, vbouv, vbotid, ibo;
Texture* tex1 = new Texture("data/body2.png"); // yellow square
Texture* tex2 = new Texture("data/head2.png"); // blue square
cout << endl << tex1->GetTID() << " " << tex2->GetTID(); // spits out "1 2"
glGenVertexArrays(1, &vao); // Vertex Array Object
glBindVertexArray(vao);
glGenBuffers(1, &vbo); // Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &vbouv); // Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, vbouv);
glBufferData(GL_ARRAY_BUFFER, sizeof(uv), uv, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &vbotid); // Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, vbotid);
glBufferData(GL_ARRAY_BUFFER, sizeof(tid), tid, GL_STATIC_DRAW);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(GLfloat), 0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glGenBuffers(1, &ibo); // Index Buffer Object
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ind), ind, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//glEnable(GL_DEPTH_TEST);
while (!window.ShouldClose())
{
window.Clear();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// *********************************************************************
shader->Enable();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex1->GetTID());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex2->GetTID());
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, nullptr); // seeing two yellow squares (GL_TEXTURE0 worked but not 1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// *********************************************************************
window.Update();
}
window.Close();
return 0;
}
#include "texture.h"
namespace JDEngine
{
// ********************************************************************
Texture::Texture(const string& filename)
: mFileName(filename)
{
mTID = Load();
}
// ********************************************************************
GLuint Texture::Load()
{
BYTE* pixels = LoadImage(mFileName.c_str(), &mWidth, &mHeight);
GLuint result;
glGenTextures(1, &result);
glBindTexture(GL_TEXTURE_2D, result);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
glBindTexture(GL_TEXTURE_2D, 0);
free(pixels);
return result;
}
// ********************************************************************
}
#version 330 core
layout (location = 0) out vec4 color;
uniform sampler2D textures[32];
in DATA
{
vec4 pos;
vec2 uv;
float tid;
} fs_in;
void main()
{
color = texture(textures[int(fs_in.tid + 0.5)], fs_in.uv);
}
答案 0 :(得分:0)
textures[int(fs_in.tid + 0.5)]
是未定义的行为,因为textures
的类型为sampler2D
,而fs_in.tid
是片段着色器输入,而不是Dynamically uniform expression。
请参见OpenGL Shading Language 4.60 Specification - 4.1.7. Opaque Types
纹理组合的采样器类型是不透明类型,如上面对不透明类型所述进行声明和表现。当汇总到着色器中的数组中时,只能使用动态统一的整数表达式对它们进行索引,否则结果是不确定的。 [...]
我建议使用sampler2DArray
(请参阅Sampler),而不要使用sampler2D
的数组。
使用sampler2DArray
时,您根本不需要任何索引,因为在纹理查找时“索引”被编码在纹理坐标的第3个分量中(请参见texture
)。>