I've been dabbling in OpenGL for a past few days, and I've made a simple renderer which can display textures. Then after some time I realized that that will be too slow for a full game so i started researching Batching. I have successfully rendered a triangle/rect and managed to get it colored (whilst batching), but the texture have stumped me for a day. For my texture loading reference I used this OpenGL tutorial. This is the picture I'm trying to render:
When I start my project, this is what happens:
I have tried to change the RGB to RGBA settings and so and nothing seemed to work. Also when i remove the
glBindTexture()
, the result is the same.
Here is my code:
Main.cpp
There is some initialization, but I doubt that'll be necessary.
VertexData one;
one.vertex = glm::vec2(-0.5f, 0.5f);
one.color = glm::vec3(1.0f, 0.0f, 0.0f);
one.texcoord = glm::vec2(0.0f, 0.0f);
VertexData two;
two.vertex = glm::vec2(0.5f, 0.5f);
two.color = glm::vec3(0.0f, 1.0f, 0.0f);
one.texcoord = glm::vec2(1.0f, 0.0f);
VertexData three;
three.vertex = glm::vec2(0.5f, -0.5f);
three.color = glm::vec3(0.0f, 0.0f, 1.0f);
one.texcoord = glm::vec2(1.0f, 1.0f);
VertexData four;
four.vertex = glm::vec2(-0.5f, -0.5f);
four.color = glm::vec3(1.0f, 1.0f, 1.0f);
one.texcoord = glm::vec2(0.0f, 1.0f);
Shader shader(vertexSource, fragmentSource);
Batch renderer(shader);
while (!glfwWindowShouldClose(game.getWindow())) {
glfwPollEvents();
if (glfwGetKey(game.getWindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(game.getWindow(), GL_TRUE);
renderer.Begin();
renderer.Submit(&one);
renderer.Submit(&two);
renderer.Submit(&three);
renderer.Submit(&three);
renderer.Submit(&four);
renderer.Submit(&one);
renderer.End();
glfwSwapBuffers(game.getWindow());
}
Batch.h
#pragma once
#include <GL\glew.h>
#include <iostream>
#include <SOIL2\SOIL2.h>
#include "Renderer.h"
#include "Shader.h"
#include "VertexArray.h"
#include "VertexBuffer.h"
#include "VertexBufferLayout.h"
#define RENDERER_MAX_VERTICES 10
#define WINWIDTH 800
#define WINHEIGHT 600
struct VertexData
{
glm::vec2 vertex;
glm::vec3 color;
glm::vec2 texcoord;
};
class Batch
{
private:
Renderer m_Renderer;
unsigned int shaderProgram;
unsigned int _vbo;
unsigned int _vao;
VertexData *_buffer;
unsigned int _vertexCount;
bool m_Drawing;
public:
Batch(Shader &shader)
:_vertexCount(0), shaderProgram(shader.getProgram())
{
glGenBuffers(1, &_vbo);
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, RENDERER_MAX_VERTICES * sizeof(VertexData), NULL, GL_DYNAMIC_DRAW);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), (void*)(5 * sizeof(GLfloat)));
// Load texture
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
int width, height;
unsigned char* image = SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
~Batch()
{
}
void Begin()
{
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
_buffer = (VertexData*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
}
void Submit(VertexData* data)
{
*_buffer = *data;
_buffer++;
_vertexCount++;
}
void End()
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(_vao);
glUseProgram(shaderProgram);
glDrawArrays(GL_TRIANGLES, 0, _vertexCount);
glBindVertexArray(0);
_vertexCount = 0;
}
};
Vertex and Fragment shaders
// Shader sources
const GLchar* vertexSource = R"glsl(
#version 150 core
in vec2 position;
in vec3 color;
in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
Color = color;
Texcoord = texcoord;
gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";
const GLchar* fragmentSource = R"glsl(
#version 150 core
in vec3 Color;
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D tex;
void main()
{
outColor = texture(tex, Texcoord) * vec4(Color, 1.0);
}
)glsl";
I thank everyone in advance who tries to help :-), also im open to some optimization or better technique suggestions.