OpenGL Move One Of My Two Shapes - c++

I'm creating a game in SDL where everything has to be drawn in OpenGL. I've drawn two shapes with different textures and added keyboard controls. My problem is only my Player textured shape should be controllable but instead both of my shapes are stuck together and the vector I thought controlled the enemy position doesn't. Is my problem when I draw? How do I make it so I my player controls only move the player shape.
//Declare transform and model matrix.
glm::mat4 Model; glm::mat4 Rotation; glm::mat4 View;
glm::mat4 Projection;
glm::vec3 Player = glm::vec3(2.0f, 0.5f, -1.0f);
GLfloat playermovespeed = 0.1f;
Projection = glm::ortho(0.0f, 4.0f, 0.0f, 3.0f, -1.0f, 100.0f);
Model = glm::translate(Model, Player);
GLint ProjectionLocation = glGetUniformLocation(shaderProgram, "ProjectionMat");
glUniformMatrix4fv(ProjectionLocation, 1, GL_FALSE, glm::value_ptr(Projection));
SDL_GetWindowSize(window, &w, &h); glViewport(0, 0, w, h);
while (WindowOpen)
{
glBindVertexArray(VAO);
glBindTexture(GL_TEXTURE_2D, texture[0]);
Model = glm::mat4();
Model = glm::translate(Model, glm::vec3(0.0f, 15.0f, 5.0f)); //Position of enemy shape
GLint ModelLocation = glGetUniformLocation(shaderProgram, "ModelMat");
GLint ViewLocation = glGetUniformLocation(shaderProgram, "ViewMat");
//glUniformMatrix4fv(ModelLocation, 1, GL_FALSE, glm::value_ptr(Model*Rotation));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
//Player texture
glBindVertexArray(VAO);
glBindTexture(GL_TEXTURE_2D, textureA);
Model = glm::mat4(); //y
Model = glm::translate(Model, Player); //Position control of ship.
ModelLocation = glGetUniformLocation(shaderProgram, "ModelMat");
glUniformMatrix4fv(ModelLocation, 1, GL_FALSE, glm::value_ptr(Model));
glUniformMatrix4fv(ViewLocation, 1, GL_FALSE, glm::value_ptr(View));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
SDL_GL_SwapWindow(window);
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
WindowOpen = false;
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_RIGHT:
Player.x += playermovespeed;
break;
case SDLK_LEFT:
Player.x -= playermovespeed;
break;
default:
break;
}
}
}
}
}
But just in case here is also how I set up everything.
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // Top Right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
};
GLuint indices[] = { start from 0!
0, 1, 3,
1, 2, 3,
};
//Load image Enemy; //Load image Player; //Load shaders;
GLuint VBO;
glGenBuffers(1, &VBO);
GLuint EBO;
glGenBuffers(1, &EBO);
GLuint texture[2];
glGenTextures(2, texture);
glBindTexture(GL_TEXTURE_2D, texture[0]);
//set texture parameters. First texture.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
SDL_FreeSurface(image);
//Second texture same way as first; //Set texture parameters
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);

Related

How to draw a line along the Z axis in openGL

I'm stuck drawing a line along the Z-axis. I have checked the related topic that OpenGL Can't draw z axis but even if I change my camera position, I still can't see my line; meanwhile, I can see a square draw in XZ-plane.
here is my code:
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
GLFWwindow* window = glfwCreateWindow(1024, 768, "some program", NULL, NULL);
glfwMakeContextCurrent(window);
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
std::cerr << "Failed to create GLEW" << std::endl;
glfwTerminate();
return -1;
}
glClearColor(0.2f, 0.298f, 0.298f, 1.0f);
// Compile and link shaders here ...
int shaderProgram = compileAndLinkShaders();
int lineVao = createLineVertexArrayObject(LineArray, sizeof(LineArray));
while (!glfwWindowShouldClose(window))
{
GLuint worldMatrixLocation = glGetUniformLocation(shaderProgram, "worldMatrix");
// Each frame, reset color of each pixel to glClearColor
glClear(GL_COLOR_BUFFER_BIT);
glm::mat4 translationMatrix = glm::mat4(1.0f);
glUniformMatrix4fv(worldMatrixLocation, 1, GL_FALSE, &translationMatrix[0][0]);
glUseProgram(shaderProgram);
glBindVertexArray(lineVao);
glDrawArrays(GL_LINES, 0, 2);
glBindVertexArray(0);
glfwSwapBuffers(window);
// Detect inputs
glfwPollEvents();
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS)//see the object in other direction
{
glm::mat4 viewMatrix = glm::lookAt(glm::vec3(0.0f, 1.0f, 0.0f), // eye
glm::vec3(0.0f, 0.0f, -1.0f), // center
glm::vec3(0.0f, 1.0f, 0.0f));// up
GLuint viewMatrixLocation = glGetUniformLocation(shaderProgram, "viewMatrix");
glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]);
}
}
// Shutdown GLFW
glfwTerminate();
return 0;
}
int createLineVertexArrayObject()
int createLineVertexArrayObject(const glm::vec3* vertexArray, int arraySize)
{
// Create a vertex array
GLuint vertexArrayObject;
glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject);
// Upload Vertex Buffer to the GPU, keep a reference to it (vertexBufferObject)
GLuint vertexBufferObject;
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, arraySize, vertexArray, GL_STATIC_DRAW);
glVertexAttribPointer(0, // attribute 0 matches aPos in Vertex Shader
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
2 * sizeof(glm::vec3), // stride - each vertex contain 2 vec3 (position, color)
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, // attribute 1 matches aColor in Vertex Shader
2,
GL_FLOAT,
GL_FALSE,
2 * sizeof(glm::vec3),
(void*)sizeof(glm::vec3) // color is offseted a vec3 (comes after position)
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
return vertexArrayObject;
}
my lineArray[] was like this
glm::vec3 LineArray[] = {
glm::vec3(-0.5f, 0.0f, -0.5f), // position
glm::vec3(1.0f, 0.0f, 0.0f), // color (yellow)
glm::vec3(0.0f, 0.0f, 0.0f), // position
glm::vec3(1.0f, 0.0f, 0.0f), // color (yellow)
};
But I can only see a horizontal line if I change my camera position.
Assuming that you want to draw a 3D line, the size argument of glVertexAttribPointer is wrong. By setting it to two, you tell OpenGL to read only two values and add 0 for z.
Set the size to 3 as in
glVertexAttribPointer(0, // attribute 0 matches aPos in Vertex Shader
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
2 * sizeof(glm::vec3), // stride - each vertex contain 2 vec3 (position, color)
(void*)0 // array buffer offset
);
and the z-value will also be read.
Note, that your color binding has the same problem. You only read the read and green value, but not the blue value.

Texture Not Showing Up

I am trying to add a texture onto my triangle but it just shows up as a black triangle. Here is my starting function that gets called:
GLuint vao;
GLuint shader_programme;
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API createSimpleWindow()
{
if (std::this_thread::get_id() == MAIN_THREAD_ID)
{
oldContext = glfwGetCurrentContext();
newContext = glfwCreateWindow(640, 480, "window", NULL, oldContext);
glfwMakeContextCurrent(newContext);
// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit();
glEnable(GL_DEPTH_TEST); // enable depth-testing
glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
//triangle pts
float points[] = {
0.0f, 0.5f, 0.0f, 0.5f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f
};
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW);
vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
glUseProgram(shader_programme);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int width, height, nrComponents;
unsigned char *data = stbi_load("/Users/roma/Desktop/Escape Tech/BitBucketRepos/blankpluginGLFW/BlankPlugin/PluginSource/source/container2.png", &width, &height, &nrComponents, 0);
writeToLog("before data");
if (data) {
writeToLog("data contained!!!!!!");
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
glUniform1i(glGetUniformLocation(shader_programme, "texture1"), 0);
//glfwCreateWindow(640, 480, "My Title", NULL, NULL);
glfwSetKeyCallback(newContext, key_callback);
}
else
{
writeToLog("not main thread");
}
}
Here is the function that gets called in a while loop:
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API windowMainLoop()
{
writeToLog("render loop");
glfwMakeContextCurrent(newContext);
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
// loop until the window closed
if (!glfwWindowShouldClose(newContext)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (std::this_thread::get_id() == MAIN_THREAD_ID)
{
// bind Texture
glBindTexture(GL_TEXTURE_2D, texture);
glUseProgram(shader_programme);
glBindVertexArray(vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(newContext);
// poll the events
glfwPollEvents();
}
//switch back to old context
glfwMakeContextCurrent(oldContext);
writeToLog("finished render loop");
}
}
My "if (data)" statement results in the text begin written to the log so I know the image is being loaded properly but I cannot figure out why the triangle is black.
Any help would be greatly appreciated!
The issue is the setup arrays of generic vertex attribute data. Each attribute tuple consist of 5 components (x, y, z, u, v):
float points[] = {
0.0f, 0.5f, 0.0f, 0.5f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f
};
So the stride parameter has to be 5 * siezof(GLfloat) rather than 6 * siezof(GLfloat):
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
The 2nd parameter of glBufferData is the size of the buffer in bytes. Your buffer consists of 15 (5 * 3) elements of type GLfloat. So the size is 15 * sizeof(float) rather than 9 * sizeof(float):
glBufferData(GL_ARRAY_BUFFER, 15 * sizeof(float), points, GL_STATIC_DRAW);
Since the format of the file is .png the last parameter of stbi_load should be set 4, to ensure that a 4 channels of the texture are get:
unsigned char *data = stbi_load("?.png", &width, &height, &nrComponents, 4);
The format and internal format of glTexImage2D have to be GL_RGBA.
By default the texture minifying function (GL_TEXTURE_MIN_FILTER) is GL_NEAREST_MIPMAP_LINEAR (see glTexParameteri). Since you don't use mip mapping, the parameter has to be changed to GL_LINEAR:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

C++: OpenGL: Drawing multiple geometries

i am programming a Super-Hyper-Mega-Lydian-Über-3D-Game and i am struggling to draw multiple geometries one after another.
Drawing a single geometrie works fine, however if i am trying to draw more than one the geometries switch their vertex-data and their shader-program; or they switch positions and rotational-axis. This is how it looks if i draw one cube:
http://i.imgur.com/zmTPc0h.png
This is how it looks like if i draw a spaceship after that cube:
http://i.imgur.com/10HDjm9.png
Here is my code for this application:
void MainLoop::loop()
{
VisibleObject cube("cube.obj", "vertexShader.glsl", "fragmentShaderCube.glsl");
cube.coordinates = glm::vec3(0.0f, 5.0f, -10.0f);
VisibleObject spaceship("spaceship.obj", "vertexShader.glsl", "fragmentShader.glsl");
spaceship.actualAxisOfRotation = glm::vec3(1.0f, 0.0f, 0.0f);
while (gameState != GAMESTATE_EXITING)
{
//check for input
while (SDL_PollEvent(&evnt))
{
switch (evnt.type)
{
case SDL_QUIT:
gameState = GAMESTATE_EXITING;
break;
default:
break;
}
}
//clear depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
spaceship.draw();
cube.draw();
//display result
SDL_GL_SwapWindow(window);
}
}
class VisibleObject
{
public:
VisibleObject(std::string modelPath, std::string vertexShaderPath, std::string fragmentShaderPath);
~VisibleObject();
void cleanup();
void draw();
glm::vec3 coordinates; //1.0f = 1.0 meter
glm::vec3 actualAxisOfRotation;
GLfloat actualRotation; //radians off the originposition
glm::vec3 velocity; //meters per second
glm::vec3 axisOfRotation;
GLfloat rotationSpeed; //radians per second
private:
short numberOfIndices;
std::vector<short> indices;
short numberOfVertices;
std::vector<glm::vec3> vertices;
glm::mat4 fullMatrix;
GLuint fullMatrixUniformLocation;
GLuint shaderProgramID;
GLuint vertexBufferID;
GLuint indexBufferID;
GLuint vertexArrayObjectID;
};
VisibleObject::VisibleObject(std::string modelPath, std::string vertexShaderPath, std::string fragmentShaderPath)
{
coordinates = glm::vec3(0.0f, 0.0f, -10.0f);
actualAxisOfRotation = glm::vec3(0.0f, 1.0f, 0.0f);
actualRotation = 2.0f;
velocity = glm::vec3(0.0f, 0.0f, 0.0f);
axisOfRotation = glm::vec3(0.0f, 1.0f, 0.0f);
rotationSpeed = 0.0f;
//create shader-program
shaderProgramID = GlslUtilities::installShader(vertexShaderPath, fragmentShaderPath);
//create transformation-matrix-uniform
fullMatrixUniformLocation = glGetUniformLocation(shaderProgramID, "f_matrix");
//load model data
numberOfIndices = 0;
numberOfVertices = 0;
indices.clear();
vertices.clear();
something_that_works_and_loads_the_vertex_and_index_data_from_an_obj-file_into_the_vectors();
//sending data to opengl
glGenVertexArrays(1, &vertexArrayObjectID);
glGenBuffers(1, &indexBufferID);
glGenBuffers(1, &vertexBufferID);
glBindVertexArray(vertexArrayObjectID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(indices[0]), &indices[0], GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
VisibleObject::~VisibleObject()
{
}
void VisibleObject::cleanup()
{
glUseProgram(0);
glDeleteProgram(shaderProgramID);
glDeleteBuffers(1, &vertexBufferID);
glDeleteBuffers(1, &indexBufferID);
glDeleteBuffers(1, &vertexArrayObjectID);
}
void VisibleObject::draw()
{
glBindVertexArray(vertexArrayObjectID);
fullMatrix = glm::perspective(glm::radians(85.0f), 800.0f / 600, 0.1f, 150.0f);
fullMatrix = glm::translate(fullMatrix, coordinates);
fullMatrix = glm::rotate(fullMatrix, glm::radians(((float)SDL_GetTicks())/10), actualAxisOfRotation);
glUniformMatrix4fv(fullMatrixUniformLocation, 1, GL_FALSE, &fullMatrix[0][0]);
glUseProgram(shaderProgramID);
glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_SHORT, 0);
}
You are uploading the fullMatrix to the shader before binding the shader. Since glMatrix4fv calls always operate on the currently bound shader, you are using wrong matrices when drawing.
Solution: Call the functions in the correct order
glUseProgram(shaderProgramID);
glUniformMatrix4fv(fullMatrixUniformLocation, 1, GL_FALSE, &fullMatrix[0][0]);
glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_SHORT, 0);

Setting up a second vertex array object has led to odd rendering

So i have a couple classes. A renderer and box2drenderer. Now both use their own vertex buffer and their own vertex array object. The Renderer is instantiated first with the following code:
glGenBuffers(1, &ebo);
glGenBuffers(1, &vbo);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLfloat vertices[] = {
// Position(2) Color(3) Texcoords(2)
0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Top-left
1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, // Top-right
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
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)));
glBindVertexArray(0);
glUseProgram(shaderProgram);
projection = glm::ortho(0.0f, width, height, 0.0f);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUseProgram(0);
Then I call the setup function for the box2d:
void Box2DRenderer::setRenderer(Renderer * r) {
this->renderer = r;
const GLchar * fragSource =
"#version 150 core\n\
precision mediump float;\n\
uniform vec4 u_color;\n\
out vec4 Color;\n\
\n\
void main()\n\
{\n\
Color = u_color;\n\
}";
const GLchar * vertSource =
"#version 150 core\n\
uniform mediump mat4 u_projection;\n\
uniform mediump float u_pointSize;\n\
in vec2 a_position;\n\
\n\
void main()\n\
{\n\
gl_PointSize = u_pointSize;\n\
gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n\
}";
this->renderer->compileProgram(vertSource, fragSource, vertShader, fragShader, shaderProgram);
glUseProgram(shaderProgram);
glGenBuffers(1, &vbo);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "u_projection"), 1, GL_FALSE, glm::value_ptr(this->renderer->getProjectionMatrix()));
GLuint positionLocation = glGetAttribLocation(shaderProgram, "a_position");
glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
glBindVertexArray(0);
colorLocation = glGetUniformLocation(shaderProgram, "u_color");
pointSizeLocation = glGetUniformLocation(shaderProgram, "u_pointSize");
glUseProgram(0);
}
The Renderer for now just draws textures. So i draw the player via the method:
void Renderer::renderTexture(sf::FloatRect &bounds, Texture &texture, Region *region) {
glm::mat4 model;
model = glm::translate(model, glm::vec3(bounds.left, bounds.top, 0.0f));
model = glm::scale(model, glm::vec3(bounds.width, bounds.height, 0.0f));
GLint modelMat = glGetUniformLocation(shaderProgram, "mMatrix");
glUniformMatrix4fv(modelMat, 1, GL_FALSE, glm::value_ptr(model));
float x = region->pos.x / texture.getWidth();
float y = region->pos.y / texture.getHeight();
float rx = (region->width + region->pos.x) / texture.getWidth();
float ry = (region->height + region->pos.y) / texture.getHeight();
GLfloat vertices[] = {
// Position(2) Color(3) Texcoords(2)
0.0f, 0.0f, 1.0f, 1.0f, 1.0f, x, y, // Top-left
1.0f, 0.0f, 1.0f, 1.0f, 1.0f, rx, y, // Top-right
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, rx, ry, // Bottom-right
0.0f, 1.0f, 1.0f, 1.0f, 1.0f, x, ry // Bottom-left
};
glBindTexture(GL_TEXTURE_2D, texture.getTextureId());
glBindVertexArray(vao);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
Now, if i don't initialize the box2d renderer, it works fine. If i have the box2d renderer, the texture coords are getting messed up. The whole texture seems to get drawn across the screen instead of regions at their correct place.
Given i'm turning on and off the BindVertexArray, I feel like I shouldn't have an issue, but for the life of me I can't figure it out. I can post screenshots of the difference if you'd like.
You probably fell victim to a fairly common misconception: Contrary to what you might have expected, the GL_ARRAY_BUFFER binding is not part of the VAO state.
At the tail end of the posted code you have this sequence:
glBindVertexArray(vao);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
The glBufferSubData() call will modify data in the currently bound GL_ARRAY_BUFFER, which is the buffer that you last made a glBindBuffer(GL_ARRAY_BUFFER, ...) call for. This is unrelated to the buffer you had bound when you previously used the VAO.
For additional illustration, here is a typical call sequence:
glBindVertexArray(vaoA);
glBindBuffer(GL_ARRAY_BUFFER, vboA);
glBindVertexArray(vaoB);
glBindBuffer(GL_ARRAY_BUFFER, vboB);
glBindVertexArray(vaoA);
The current GL_ARRAY_BUFFER binding at the end of this sequence is vboB. Since the binding is not part of the VAO state, it is simply based on the most recent glBindBuffer() call.
All you need to do to fix this is to add the glBindBuffer() call before glBufferSubData().
Note that the GL_ELEMENT_ARRAY_BUFFER binding is part of the VAO state. This may seem inconsistent, but it's not. The VAO bundles all the vertex setup state that is used by draw commands. The GL_ELEMENT_ARRAY_BUFFER binding controls which index buffer is used by draw commands, so it is part of this state. On the other hand, the current GL_ARRAY_BUFFER binding has no effect on the draw command, and is therefore not part of the VAO state.

OpenGL Vertex Buffer Object not Showing

I have changed 3 GLFloat arrays (aka GLfloat[]) into vectors (aka vector) and my triangles stopped working! Here is my init function:
void initialize(GLuint &vao) {
// Use a Vertex Array Object
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Projection = perspective(45.0f, 16.0f / 9.0f, 0.1f, 100.0f);
//ortho(-4.0f/3.0f, 4.0f/3.0f, -1.0f, 1.0f, -1.0f, 1.0f);
Model = translate(Model, vec3(0.f, 0.f, 0.f));
Model = rotate(Model, 45.0f, vec3(0.0f, 0.0f, 1.0f));
//pos + textures array
GLuint vboId;
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, (vertices_position.size() + texture_coord.size() ) * sizeof(GLfloat), NULL, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_position.size() * sizeof(GLfloat), &vertices_position[0]);
glBufferSubData(GL_ARRAY_BUFFER, vertices_position.size() * sizeof(GLfloat), texture_coord.size() * sizeof(GLfloat), &texture_coord[0]);
//Indices
GLuint eabId;
glGenBuffers(1, &eabId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eabId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLfloat), &indices[0], GL_DYNAMIC_DRAW);
//Textures
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
load_image("../squirrel.jpg");
shaderProgram = create_program("../shaders/vert.shader", "../shaders/frag.shader");
//Position attribute
positionAttrId = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(positionAttrId, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(positionAttrId);
//Texture attribute
textureCoordId = glGetAttribLocation(shaderProgram, "texture_coord");
glVertexAttribPointer(textureCoordId, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(vertices_position.size() * sizeof(GLfloat)));
glEnableVertexAttribArray(textureCoordId);
modelId = glGetUniformLocation(shaderProgram, "Model");
cameraId = glGetUniformLocation(shaderProgram, "Camera");
}
And below is my render function:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
glUniformMatrix4fv(modelId, 1, GL_FALSE, glm::value_ptr(Model));
glUniformMatrix4fv(cameraId, 1, GL_FALSE, glm::value_ptr(cam.matrix()));
//VAO
glBindVertexArray(vao);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glUseProgram(0);
You are using floating-point elements in your Index Buffer Object, that is not a valid data type.
OpenGL requires either GLubyte (not hardware accelerated on most desktop GPUs), GLushort or GLuint indices.
For best performance, you should use an array of GLushort and pass GL_UNSIGNED_SHORT as the element type in your call to glDrawElements (...).