c++ - OpenGL 纹理几乎不可见(非常暗)
问题描述
我已经开始在 opengl 中处理纹理,并且在渲染我的第一个纹理时,我看到了一个黑屏。然后我意识到屏幕不是黑色的,而是纹理非常暗淡。为什么会这样?这是代码:
纹理类(.cpp):
Texture::Texture(void* data, unsigned int width, unsigned int height)
:texture(0), curslot(32), width(width), height(height)
{
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, this->width, this->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
}
Texture::~Texture(){
glDeleteTextures(1, &texture);
}
void Texture::bind(unsigned char slot){
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, texture);
curslot = slot;
}
纹理类声明(如果需要):
class Texture{
private:
unsigned int texture;
unsigned char curslot;
unsigned int width;
unsigned int height;
public:
Texture(void* data, unsigned int width, unsigned int height);
~Texture();
void bind(unsigned char slot=0);
};
着色器:顶点着色器:
#version 330 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texpos;
out vec2 texCoord;
void main(){
gl_Position = position;
texCoord = texpos;
}
片段着色器:
#version 330 core
layout(location=0) out vec4 color;
uniform sampler2D u_Texture;
in vec2 texCoord;
void main(){
vec4 texColor = texture(u_Texture, texCoord);
color = texColor;
}
渲染器类声明(你不需要实现,但如果你想要它,我很乐意添加它,只是问):
class Renderer{
private:
Renderer(){}
public:
static Renderer* renderer;
Renderer(const Renderer& r) = delete;
void draw(VertexArray* va, IndexBuffer* ib, Shader* shader, void (*uniformCallback)(Shader*, void*), void* uniformCallbackParams) const; //Fourth parameter is a function pointer that executes every time the draw function is called. It enables the user of the class to declare their uniforms. First three parameters are abstracted classes. Final parameter is a void pointer that is passed into the uniform function
};
主要应用(简化):
typedef struct{
float x;
float y;
float texCoord_x;
float texCoord_y;
} vertex_t;
static GLFWwindow* window;
static void uniformCallback(Shader* program, void* params){
program->useUniform1i("u_Texture", 0); //Setting the sampler2D uniform for the texture slot
}
int main(){
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(500, 500, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
VertexArray* va = new VertexArray(); //Abstracted vertex array
va->bind();
VertexBuffer* vb = new VertexBuffer(); //Abstracted vertex buffer
IndexBuffer* ib = new IndexBuffer(); //Abstracted index buffer
unsigned char t[16] = { //Texture pixels, RGBA form. Made this simple 'image' just for testing purposes
1, 0, 0, 1,
1, 1, 1, 1,
1, 1, 1, 1,
1, 0, 0, 1
};
Texture* texture = new Texture(t, 2, 2); //Texture class (abstracted)
texture->bind();
Shader* program = new Shader(2, "vs.glsl", "fs.glsl"); //Abstracted shader
vertex_t data[4] = {
{-0.5, 0.5, 0.0f, 1.0f},
{ 0.5, 0.5, 1.0f, 1.0f},
{-0.5, -0.5, 0.0f, 0.0f},
{ 0.5, -0.5, 1.0f, 0.0f}
};
unsigned int indicies[6] = {
0, 1, 2,
1, 2, 3
};
vb->setBufferData(data, 4*sizeof(vertex_t));
ib->setBufferData(indicies, 6);
vb->bind();
ib->bind();
va->addAttrib(GL_FLOAT, 2); //equivalent of glEnableAttribArray and glVertexAttribPointer
va->addAttrib(GL_FLOAT, 2);
while(!glfwWindowShouldClose(window)){
glClear(GL_COLOR_BUFFER_BIT);
Renderer::renderer->draw(va, ib, program, uniformCallback, NULL); //Refer to renderer class declaration
glfwSwapBuffers(window);
glfwPollEvents();
}
//Clean-up code (freeing pointers, etc.)
glfwTerminate();
return 0;
}
解决方案
纹理的每个颜色通道都以一个字节编码。因此,颜色值在 [0, 255] 范围内。更改 的值t[16]
:
unsigned char t[16] = {
255, 0, 0, 255,
255, 255, 255, 255,
255, 255, 255, 255,
255, 0, 0, 255
};
注意,在指定二维纹理图像时,像素数据的数据类型由 指定GL_UNSIGNED_BYTE
:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, this->width, this->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
推荐阅读
- javascript - How to make an AJAX delete request in a Vue JS component?
- powershell - 创建 Powershell 脚本以增强用户输入
- url - 从 URL 获取值到 sharepoint 表单文本框中
- c++ - C++ 等价于 C99 复合文字
- android - 如何将数据从服务发送到 Android Studio 中的活动?
- javascript - 如何在 ExtJS 中使用 math.js
- java - 为什么字符串中的双等于的工作方式如此不同?
- android - 当我在 Android Studio 的 gradle 中添加 viewBinding 时,出现错误
- javascript - (0 , _reactNavigation.createAppContaner) 不是一个函数 Evaluating App.js Loading App.js
- dart - PayPal Orders v2 创建响应:请求的操作无法执行、语义不正确或业务验证失败