I am confusion:confused:. Textures will render in main loop, but not when called by render function. If i try to pass program by value into the render method, the screen turns white (glGetError = 0 then 1281) and if I pass by reference the object remains solid black (glGetError = 0). If I take the object and render within the main loop without terrain class, the code runs correctly. I know for sure both vertex/frag shader are working along with everything else, but if you want to look at them just ask.
DOES NOT WORK
#include "Game.h"
#include "Viewport.h"
#include "Program.h"
#include "Terrain.h"
#include "Texture.h"
#include <glm.hpp>
#include <gtc\matrix_transform.hpp>
#include <iostream>
#include <vector>
void Game::run(void)
{
std::vector<Terrain> terrains;
glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
modelMatrix = glm::rotate(modelMatrix, glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 projMatrix = glm::perspective(glm::radians(45.0f), (GLfloat)Viewport::getWidth() / (GLfloat)Viewport::getHeight(), 0.1f, 100.0f);
terrains.push_back(Terrain(0, -1, "grass.jpg"));
while (_isActive)
{
while (SDL_PollEvent(&e))
{
handleEvent(e);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (Terrain t : terrains)
t.render(sample, modelMatrix, camera.getViewMatrix(), projMatrix);
Viewport::update();
}
Viewport::close();
}
Terrain.h
#ifndef TERRAIN_H
#define TERRAIN_H
#include <GL\glew.h>
#include <glm.hpp>
#include <iostream>
#include "Texture.h"
#include "Program.h"
class Terrain
{
GLuint _vao; //mesh data (We dont want to keep remaking the same vao)
GLuint _size; //vert count
Texture _texture;
public:
Terrain(GLint gridX, GLint gridZ, const char * texture) : _texture(GL_TEXTURE_2D, texture)
{
this->testSquare();
}
void testSquare(void)
{
GLfloat t[] =
{
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f
};
GLuint i[] =
{
0, 1, 2,
2, 3, 0
};
GLuint vao, vbo, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(t), t, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(i), i, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
_size = 6;
_vao = vao;
}
void render(Program program, glm::mat4 model, glm::mat4 view, glm::mat4 proj) //White Screen Or Passing program by reference draws solid black object instead...
{
glUseProgram(program.getId());
glUniformMatrix4fv(glGetUniformLocation(program.getId(), "model"), 1, GL_FALSE, &model[0][0]);
glUniformMatrix4fv(glGetUniformLocation(program.getId(), "view"), 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(glGetUniformLocation(program.getId(), "proj"), 1, GL_FALSE, &proj[0][0]);
glUniform1i(glGetUniformLocation(program.getId(), "texture1"), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _texture.getId());
glBindVertexArray(_vao);
glDrawElements(GL_TRIANGLES, _size, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glUseProgram(0);
}
};
#endif // !TERRAIN_H
EDIT:
Well :doh:. I partially solve the issue. I replaced the for each loop with a regular for loop and passed the program in as a reference. Not sure why I needed to do this. Can anyone clarify the reasoning for this issue? If I had to guess it has to do something with open gl and copy constructors?