【发布时间】:2018-02-22 15:07:30
【问题描述】:
我正在尝试将纹理加载到现代 NVIDIA openGL 中的对象
我有一个要加载纹理的正方形,我使用 stb_image 作为我的加载器
这里是主要代码:
float position1[16]{
0.0f , 0.0f, 0.0f , 0.0f,
0.8f , 0.0f, 1.0f , 0.0f,
0.0f , 0.8f, 0.0f , 1.0f,
0.8f , 0.8f, 1.0f , 1.0f ,
};
unsigned int Indexs[6]{
0 , 1 , 2 ,
2 , 1 , 3
};
VertexBuffer buffer(position1, sizeof(position1));
IndexBuffer Index(Indexs, 6);
Texture Tex("Smile.png");
Tex.Bind();
buffer.Bind();
Index.Bind();
Shader BasicShader("basic.shader");
Renderer renderer;
glfwSwapInterval(0);
//! MAIN LOOP !!!
BasicShader.Uniform1i("u_Texture ", 0);
BasicShader.Uniform4f("u_Color", 0.0f, 1.0f, 1.0f, 1.0f );
while (!glfwWindowShouldClose(window) )
{
//! RENDER
renderer.Clear();
glEnable(GL_TEXTURE_2D);
BasicShader.Uniform1i("u_Texture ", 0);
BasicShader.Uniform4f("u_Color", 0.f, 1.0f, 1.0f, 1.0f);
Tex.Bind();
BasicShader.Bind();
renderer.Draw(buffer, Index, Layout::D4Vertex, BasicShader);
//! FRAME
glfwSwapBuffers(window);
//! EVENTS
glfwPollEvents();
}
glfwTerminate();
return 0;
};
这是我的着色器,它当然是按预期正确编译的,没有错误:
#shader vertex
#version 410 core
layout(location = 0 ) in vec4 position;
layout(location = 1) in vec2 texCoord;
out vec2 v_TexCoord;
void main()
{
gl_Position = position;
v_TexCoord = texCoord;
};
#shader fragment
#version 410 core
layout(location = 0 ) out vec4 color;
uniform vec4 u_Color;
uniform sampler2D u_Texture;
in vec2 v_TexCoord;
void main()
{
vec4 texColor = texture2D(u_Texture, v_TexCoord);
color = texColor;
};
这是我的绘图调用:
void Renderer::Draw(VertexBuffer& vb, IndexBuffer& iv,
Layout layout,Shader& shader)
{
BufferLayout bufferLayout;
shader.Bind();
vb.Bind();
iv.Bind();
bufferLayout.SetLayout(layout);
glDrawElements(GL_TRIANGLES, iv.GetCount(), GL_UNSIGNED_INT, nullptr);
}
这就是我设置缓冲区布局的方式:
void BufferLayout::SetLayout(Layout l)
{
switch (l) {
case Layout::NONE :
glEnableVertexAttribArray(0);
case Layout::D2Vertex :
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) *
2,0);
case Layout::D4Vertex:
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) *
4,0);
}
}
这是我的纹理类(处理加载参数和绑定):
#include "Texture.h"
#include "stb_image.h";
#include "Renderer.h"
Texture::Texture(string path)
: m_RendererID(0) , m_BPP(0) , m_Height (0) , m_Width (0),
m_LocalBuffer(nullptr) , m_FilePath(path)
{
stbi_set_flip_vertically_on_load(1);
m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4);
//seems like the image is there
glEnable(GL_TEXTURE_2D);
glGenTextures(1, & m_RendererID);
glBindTexture(GL_TEXTURE_2D, m_RendererID);
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);
GLenum temp = glGetError();
if (temp != GL_NO_ERROR) throw std::invalid_argument("OPENGL ERROR");
// I Get no erros
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, m_LocalBuffer);
}
Texture::~Texture()
{
glDeleteTextures(1, &m_RendererID);
}
void Texture::Bind(unsigned int slot)
{
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, m_RendererID);
}
void Texture::Unbind()
{
glBindTexture(GL_TEXTURE_2D, 0);
}
还有我的 texture.h 文件:
#pragma once
#include "Renderer.h"
class Texture {
private :
unsigned int m_RendererID;
string m_FilePath;
unsigned char * m_LocalBuffer;
int m_Width, m_Height, m_BPP;
public:
Texture(string path);
~Texture();
void Bind(unsigned int slot = 0);
void Unbind();
inline int GetWidth()const { return m_Width; }
inline int GetHeight()const { return m_Height; }
};
基本上我很确定问题一定出在我发布的代码中,并且所有其他代码都按预期工作。
谁能发现问题? 结果应该是一个带有纹理“Smile.png”的正方形,我得到一个白色纹理。我的项目目录中确实有文件“Smile.png”,在我看来,stb_image 可以找到并加载它。
*glGetError(); 没有错误
【问题讨论】:
-
我必须承认,很难在 OpenGL 上制作一个 small MCVE。但是,您至少可以正确格式化您的代码...
-
我没有看到任何将数据绑定到
texCoord属性的代码。 -
@BDL
case Layout::D4Vertex: glEnableVertexAttribArray(0); glVertexAttribPointer(0,2,GL_FLOAT , GL_FALSE , sizeof(float)*4 , 0);应该这样做......对吗?这段代码在渲染器中调用到 BufferLayout 类 -
这是属性 0 的设置。您缺少属性 1 的类似代码。
-
@BDL 谢谢! :) 你能用一个例子来做一个完整的答案吗?因为我不完全理解如何做到这一点......
标签: c++ windows opengl graphics textures