Hi! I am trying to render texture a texture. The quad draws well but texture does not want to attach.
Mesh class
void Mesh::CreateQuad(Rect destRect, Rect uvRect, ColorRGBA color, GLuint texture)
{
this->texture = texture;
//Vertex is a class that contains 3 structs: Position(float x and y), Color (Glubyte r and g, and b, and a), UV (float u and v)
Vertex vertex[6];
vertex[0].color = color;
vertex[0].setPosition(destRect.x, destRect.y + destRect.h);
vertex[0].setUV(uvRect.x, uvRect.y + uvRect.h);
vertex[1].color = color;
vertex[1].setPosition(destRect.x, destRect.y);
vertex[1].setUV(uvRect.x, uvRect.y);
vertex[2].color = color;
vertex[2].setPosition(destRect.x + destRect.w, destRect.y);
vertex[2].setUV(uvRect.x + uvRect.w, uvRect.y);
vertex[3].color = color;
vertex[3].setPosition(destRect.x + destRect.w, destRect.y + destRect.h);
vertex[3].setUV(uvRect.x + uvRect.w, uvRect.y + uvRect.h);
GLuint index[] = {
0, 1, 2,
0, 2, 3
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(Vertex), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(Vertex), vertex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 6 * sizeof(GLuint), index);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Mesh::CreateVertexArray()
{
if (vao == 0) {
glGenVertexArrays(1, &vao);
}
glBindVertexArray(vao);
if (vbo == 0) {
glGenBuffers(1, &vbo);
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
if (ebo == 0) {
glGenBuffers(1, &ebo);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
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));
glGenVertexArrays(1, 0);
}
void Mesh::DrawQuad()
{
glBindVertexArray(vao);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glFrontFace(GL_CW);
glBindTexture(GL_TEXTURE_2D, texture);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
std::cout << "Texture " << texture << std::endl;
}
texture class
void Texture::Init()
{
//Creates vbo vao ebo
mesh.CreateVertexArray();
}
void Texture::LoadFromFile(const std::string & filePath)
{
//attaches texture to the textureID
textureID = texture.getTexture(filePath);
}
void Texture::Draw(Rect destRect, Rect uvRect, ColorRGBA color)
{
//creates and draws a quad with texture ID
mesh.CreateQuad(destRect, uvRect, color, textureID);
mesh.DrawQuad();
}
GLuint TextureCache::loadFromFile(const std::string & filePath)
{
textureMap.clear();
SDL_Surface* surface = IMG_Load(filePath.c_str());
GLuint texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int format;
surface->format->BitsPerPixel == 4 ? format = GL_RGBA : format = GL_RGB;
w = surface->w;
h = surface->h;
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
SDL_FreeSurface(surface);
glBindTexture(GL_TEXTURE_2D, 0);
return texture;
}
GLuint TextureCache::getTexture(const std::string & filePath)
{
//finds texture
auto texMap = textureMap.find(filePath);
//if there is no texture create one
if (texMap == textureMap.end()) {
GLuint newTexture = loadFromFile(filePath);
textureMap[filePath] = newTexture;
return newTexture;
}
// else return existing one
return texMap->second;
}
and a bit of main.cpp
Texture texture;
texture.Init();
texture.LoadFromFile("MenuImage.png");
Shader shader;
std::string vertex = shader.LoadFromFile("vertex.shader");
std::string fragment = shader.LoadFromFile("fragment.shader");
shader.CreateShaderProgram(vertex.c_str(), fragment.c_str());
GLint u_textureSampler = shader.GetUniformLocation("u_textureSampler");
glUniform1f(u_textureSampler, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
bool quit = false;
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
SDL_Quit();
exit(0);
}
}
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Rect destRect = { -0.5, -0.5, 1.0, 1.0 };
Rect uvRect = { 0.0, 0.0, 1.0, 1.0f };
ColorRGBA color = { 255, 0, 255, 255 };
texture.Draw(destRect, uvRect, color);
SDL_GL_SwapWindow(window);
}
and shaders
#version 330 core
layout (location = 0) in vec2 aPosition;
layout (location = 1) in vec4 aColor;
layout (location = 2) in vec2 aUV;
out vec4 v_fragmentColor;
out vec2 v_fragmentUV;
void main()
{
gl_Position = vec4(aPosition, 0.0, 1.0);
v_fragmentColor = aColor;
v_fragmentUV = aUV;
}
#version 330 core
out vec4 outColor;
in vec2 v_fragmentUV;
in vec4 v_fragmentColor;
uniform sampler2D u_textureSampler;
void main()
{
vec4 textureColor = texture(u_textureSampler, v_fragmentUV);
outColor = v_fragmentColor * textureColor;
}
And still there is no texture on the screen. There is only nothing :c
Yes, so I know there is a lot of code and I almost said nothing but there is nothing to say. I think my comments attached to code are enough. If you have more questions ask, though. Maybe there is better way to do it. let me know, please.