I have made simple OpenGL 2D wrapper GLobj, it works good, so I wanted to make Scene class with a vector containing these OpenGL objects, but when I try to draw any of these objects it gives me 1282 error.
I have found very similar problem in common problems at:
- Common_Mistakes # RAII_and_hidden_destructor_calls (OpenGL Wiki)
but adding move constructor and removying copy constructor didn’t help me.
Here is my code(also, if you have any advices how to make my GLobj class better, then please mention it):
GLobj.hpp:
#pragma once
#include <glad/glad.h>
#include <stb/stb_image.h>
#include <iostream>
class GLobj {
public:
GLobj(GLfloat vertices[], GLsizeiptr verticesSize, GLuint indices[], GLsizeiptr indicesSize);
void draw();
void addTexture(const char * filePath);
~GLobj();
private:
GLuint VBO,VAO,EBO,texture0,indices_size;
unsigned char * bytes;
};
GLobj.cpp:
#include "GLobj.hpp"
GLobj::GLobj (GLfloat vertices[], GLsizeiptr verticesSize, GLuint indices[], GLsizeiptr indicesSize) {
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, verticesSize, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices, GL_STATIC_DRAW);
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);
indices_size = indicesSize/sizeof(GLuint);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}
void GLobj::addTexture(const char * filePath) {
int widthImg, heightImg, numColCh;
unsigned char * bytes = stbi_load(filePath, & widthImg, & heightImg, & numColCh, 0);
glGenTextures(1, & texture0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texture0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
if (numColCh == 3) glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,widthImg,heightImg,0,GL_RGB,GL_UNSIGNED_BYTE,bytes);
else glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,widthImg,heightImg,0,GL_RGBA,GL_UNSIGNED_BYTE,bytes);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(bytes);
glBindTexture(GL_TEXTURE_2D,0);
}
void GLobj::draw() {
if (texture0 != 0) {
glBindTexture(GL_TEXTURE_2D,texture0);
}
std::cout << "glBindTexture: " << glGetError() << std::endl;
glBindVertexArray(VAO);
std::cout << "glBindVertexArray: " << glGetError() << std::endl;
glDrawElements(GL_TRIANGLES, indices_size, GL_UNSIGNED_INT, 0);
std::cout << "glDrawElements: " << glGetError() << std::endl;
}
GLobj::~GLobj() {
glDeleteBuffers(1,& VBO);
glDeleteVertexArrays(1,& VAO);
glDeleteBuffers(1, & EBO);
glDeleteTextures(1, & texture0);
}
Scene.hpp:
#pragma once
#include "GLobj.hpp"
#include <vector>
#include <optional>
class Scene {
private:
std::vector<GLobj> objects;
public:
void renderAll();
template<size_t vertices_size,size_t indices_size>
void createObject (GLfloat (&vertices)[vertices_size],GLuint (&indices)[indices_size],const char * filepath = "notexture") {
GLobj nObj(vertices,sizeof(vertices),indices,sizeof(indices));
if (filepath != "notexture") {
nObj.addTexture(filepath);
}
objects.push_back(std::move(nObj));
}
};
Scene.cpp:
#include "Scene.hpp"
void Scene::renderAll() {
for (auto it = objects.begin(); it != objects.end(); it++) {
it->draw();
}
}
main.cpp:
#define STB_IMAGE_IMPLEMENTATION
#include "include/Scene.hpp"
#include "include/shaderClass.hpp"
#include <GLFW/glfw3.h>
#include <iostream>
int main () {
//init GLFW
glfwInit();
//GLFW hints. Profile in OpenGL is package of functions we want to use
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
//Creating Window
GLFWwindow* window = glfwCreateWindow(1280,720,"OpenGL Test Window",NULL,NULL);
if (window == nullptr) {
std::cout << "Failed to create window" << std::endl;
glfwTerminate();
return -1;
}
//glfwMakeContextCurrent(GLFWwindow*) makes window current used object
glfwMakeContextCurrent(window);
//if you make different amount of windows in while loop you shoold target other window by that function.
//Graphic while loop to keep window updated. glfwWindowShouldClose returns true shaderProgra0.5if window where closed.
//start OpenGL
gladLoadGL();
glViewport(0,0,1280,720);
Shader shaderProgram("default.vert","default.frag");
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLuint tex0Uni = glGetUniformLocation(shaderProgram.ID,"tex0");
glUniform1i(tex0Uni,0);
std::cout << glGetError() << std::endl;
stbi_set_flip_vertically_on_load(true);
GLfloat vertices[] =
{ // COORDINATES / COLORS / TexCoord //
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // Lower left corner
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Upper left corner
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Upper right corner
1.0f, -1.0f, 0.0f, 1.0f, 0.0f // Lower right corner
};
GLuint indices[] =
{
0, 2, 1, // Upper triangle
0, 3, 2 // Lower triangle
};
GLfloat verticesField[] =
{ // COORDINATES / COLORS / TexCoord //
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // Lower left corner
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Upper left corner
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Upper right corner
1.0f, -1.0f, 0.0f, 1.0f, 0.0f // Lower right corner
};
GLuint indicesField[] =
{
0, 2, 1, // Upper triangle
0, 3, 2 // Lower triangle
};
GLfloat verticesTitle[] =
{ // COORDINATES / COLORS / TexCoord //
-1.0f, 0.2f, 0.0f, 0.0f, 0.0f, // Lower left corner
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Upper left corner
0.1f, 1.0f, 0.0f, 1.0f, 1.0f, // Upper right corner
0.1f, 0.2f, 0.0f, 1.0f, 0.0f // Lower right corner
};
GLuint indicesTitle[] =
{
0, 2, 1, // Upper triangle
0, 3, 2 // Lower triangle
};
// GLobj sky(vertices,sizeof(vertices),indices,sizeof(indices));
// sky.addTexture("sky.png");
// GLobj field(verticesField,sizeof(verticesField),indicesField,sizeof(indicesField));
// field.addTexture("field.png");
// GLobj title(verticesTitle,sizeof(verticesTitle),indicesTitle,sizeof(indicesTitle));
// title.addTexture("title.png");
Scene MyScene;
MyScene.createObject(vertices,indices,"sky.png");
// GLobj d(vertices,sizeof(vertices),indices,sizeof(indices));
// d.addTexture("sky.png");
// insertObject(std::move(d));
glClearColor(0.07F,0.13F,0.17F,1.0F);
glClear(GL_COLOR_BUFFER_BIT);
shaderProgram.Activate();
MyScene.renderAll();
glfwSwapBuffers(window);
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
}
// Delete window before ending the program
glfwDestroyWindow(window);
// Terminate GLFW before ending the program
glfwTerminate();
return 0;
}