mirror of
https://github.com/MichaelFisher1997/opengl-cpp.git
synced 2025-07-01 02:13:13 +00:00
Indexbuffer improvments
This commit is contained in:
parent
fd13d0ba63
commit
8920379ce3
58
Makefile
58
Makefile
@ -1,38 +1,38 @@
|
|||||||
CC=clang++
|
# Compiler and flags
|
||||||
current_directory=$(shell pwd)
|
CXX := g++
|
||||||
|
CXXFLAGS := -g #-O0 -Wall -Wextra
|
||||||
|
|
||||||
FRAMEWORKS=-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
|
# Libraries
|
||||||
|
LDFLAGS := -lSDL2 -lGLEW -lGL
|
||||||
|
|
||||||
CFLAGS=-std=c++11
|
# Source and output directories
|
||||||
CFLAGS+=-I$(current_directory)
|
SRC_DIR := src
|
||||||
CFLAGS+=-I$(current_directory)/../external
|
BUILD_DIR := build
|
||||||
|
TARGET := $(BUILD_DIR)/opengl
|
||||||
|
|
||||||
LDFLAGS=-L$(current_directory)/../lib
|
# Source files and object files
|
||||||
LDFLAGS+=-lglfw3
|
SRC := $(wildcard $(SRC_DIR)/*.cpp)
|
||||||
LDFLAGS+=-lGLEW
|
OBJ := $(SRC:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
|
||||||
|
|
||||||
SOURCES=$(wildcard *.cpp)
|
# Default target
|
||||||
OBJECTS=$(patsubst %.cpp, %.o, $(SOURCES))
|
all: $(TARGET)
|
||||||
|
|
||||||
|
# Build the target executable
|
||||||
|
$(TARGET): $(OBJ)
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
%.o: %.cpp
|
# Build object files
|
||||||
$(CC) $(CFLAGS) -c -o $@ $^
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
default: debug
|
# Clean up build files
|
||||||
|
|
||||||
app: $(OBJECTS)
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) $(FRAMEWORKS) -o $@ $(OBJECTS)
|
|
||||||
|
|
||||||
# Define debug and -g enables debug symbols
|
|
||||||
debug: CFLAGS+=-DDEBUG -g
|
|
||||||
debug: app
|
|
||||||
|
|
||||||
release: app
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o app
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
.PHONY: debugger
|
# Run the application
|
||||||
debugger: debug
|
run: $(TARGET)
|
||||||
PATH=/usr/bin /usr/bin/lldb ./app
|
./$(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean run
|
||||||
|
@ -12,10 +12,41 @@ IndexBuffer::IndexBuffer(const unsigned int* data, unsigned int count)
|
|||||||
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), data, GL_STATIC_DRAW)); // assigne buffer size, static as we use many times, but does not change
|
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), data, GL_STATIC_DRAW)); // assigne buffer size, static as we use many times, but does not change
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexBuffer::~IndexBuffer()
|
// Destructor
|
||||||
{
|
IndexBuffer::~IndexBuffer() {
|
||||||
std::cout << "m_RendererID: " << &m_RendererID << " " << m_RendererID << std::endl;
|
if (m_RendererID != 0) { // Only delete if valid
|
||||||
GLCall(glDeleteBuffers(1, &m_RendererID));
|
GLCall(glDeleteBuffers(1, &m_RendererID));
|
||||||
|
std::cout << "IndexBuffer destroyed with RendererID: " << m_RendererID << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move Constructor
|
||||||
|
IndexBuffer::IndexBuffer(IndexBuffer&& other) noexcept
|
||||||
|
: m_RendererID(other.m_RendererID), m_Count(other.m_Count) {
|
||||||
|
other.m_RendererID = 0; // Invalidate the moved-from object
|
||||||
|
other.m_Count = 0;
|
||||||
|
std::cout << "IndexBuffer moved (constructor)" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move Assignment Operator
|
||||||
|
IndexBuffer& IndexBuffer::operator=(IndexBuffer&& other) noexcept {
|
||||||
|
if (this != &other) {
|
||||||
|
// Free existing resources
|
||||||
|
if (m_RendererID != 0) {
|
||||||
|
GLCall(glDeleteBuffers(1, &m_RendererID));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer ownership
|
||||||
|
m_RendererID = other.m_RendererID;
|
||||||
|
m_Count = other.m_Count;
|
||||||
|
|
||||||
|
// Invalidate the moved-from object
|
||||||
|
other.m_RendererID = 0;
|
||||||
|
other.m_Count = 0;
|
||||||
|
|
||||||
|
std::cout << "IndexBuffer moved (assignment)" << std::endl;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexBuffer::Bind() const
|
void IndexBuffer::Bind() const
|
||||||
|
@ -6,11 +6,19 @@ public:
|
|||||||
IndexBuffer(const unsigned int* data, unsigned int count);
|
IndexBuffer(const unsigned int* data, unsigned int count);
|
||||||
~IndexBuffer();
|
~IndexBuffer();
|
||||||
|
|
||||||
|
// Disallow copy operations
|
||||||
|
IndexBuffer(const IndexBuffer&) = delete;
|
||||||
|
IndexBuffer& operator=(const IndexBuffer&) = delete;
|
||||||
|
|
||||||
|
// Enable move operations
|
||||||
|
IndexBuffer(IndexBuffer&& other) noexcept;
|
||||||
|
IndexBuffer& operator=(IndexBuffer&& other) noexcept;
|
||||||
|
|
||||||
void Bind() const;
|
void Bind() const;
|
||||||
void Unbind() const;
|
void Unbind() const;
|
||||||
|
|
||||||
inline unsigned int GetCount() const { return m_Count; }
|
inline unsigned int GetCount() const { return m_Count; }
|
||||||
private:
|
private:
|
||||||
unsigned int m_RendererID;
|
unsigned int m_RendererID = 0;
|
||||||
unsigned int m_Count;
|
unsigned int m_Count = 0;
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
|
|
||||||
void GLClearError() {
|
void GLClearError() {
|
||||||
//while (glGetError() != GL_NO_ERROR);
|
while (glGetError() != GL_NO_ERROR);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,11 @@
|
|||||||
|
|
||||||
VertexArray::VertexArray()
|
VertexArray::VertexArray()
|
||||||
{
|
{
|
||||||
GLCall(glGenVertexArrays(1, &m_RendererID));
|
std::cout << "VertexArray::VertexArray()" << std::endl;
|
||||||
|
std::cout << "m_RendererID: " << &m_RendererID << " " << m_RendererID << std::endl;
|
||||||
|
//GLCall(glGenVertexArrays(1, &m_RendererID));
|
||||||
|
glGenVertexArrays(1, &m_RendererID);
|
||||||
|
std::cout << "m_RendererID: " << &m_RendererID << " " << m_RendererID << std::endl;
|
||||||
if (!m_RendererID) {
|
if (!m_RendererID) {
|
||||||
std::cerr << "Failed to generate VAO" << std::endl;
|
std::cerr << "Failed to generate VAO" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
// Create an instance of our SdlWindow class
|
// Create an instance of our SdlWindow class
|
||||||
|
std::cout << "starting" << std::endl;
|
||||||
SdlWindow window("My SDL2 Window", 800, 600);
|
SdlWindow window("My SDL2 Window", 800, 600);
|
||||||
|
std::cout << "About to run: " << std::endl;
|
||||||
|
|
||||||
// Run the main loop
|
// Run the main loop
|
||||||
window.run();
|
window.run();
|
||||||
|
100
src/sdl.cpp
100
src/sdl.cpp
@ -51,25 +51,30 @@ struct ShaderProgramSource {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SdlWindow::SdlWindow(const char* title, int width, int height)
|
SdlWindow::SdlWindow(const char* title, int width, int height)
|
||||||
: m_window(nullptr),
|
: m_window(nullptr),
|
||||||
m_renderer(nullptr),
|
m_renderer(nullptr),
|
||||||
m_isRunning(false),
|
m_isRunning(false),
|
||||||
m_isFullscreen(false),
|
m_isFullscreen(false),
|
||||||
m_width(width),
|
m_width(width),
|
||||||
m_height(height),
|
m_height(height),
|
||||||
m_glContext(nullptr),
|
m_windowedWidth(width),
|
||||||
m_windowedWidth(width),
|
m_windowedHeight(height),
|
||||||
m_windowedHeight(height),
|
r(0.5f),
|
||||||
r(0.5f),
|
m_glContext(nullptr),
|
||||||
location(),
|
increment(0.05f),
|
||||||
increment(0.05f),
|
vao(0),
|
||||||
m_ib(nullptr, 0)
|
layout(nullptr),
|
||||||
|
va(nullptr),
|
||||||
|
m_ib(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
std::cout << "Step 0: hellow world" << std::endl;
|
||||||
|
|
||||||
// 1. Set attributes
|
// 1. Set attributes
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
|
std::cout << "Step 1: SDL_GL_SetAttribute completed" << std::endl;
|
||||||
// 2. Create the window with OpenGL flag
|
// 2. Create the window with OpenGL flag
|
||||||
m_window = SDL_CreateWindow(title,
|
m_window = SDL_CreateWindow(title,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
@ -79,30 +84,42 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
|
|||||||
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN| SDL_WINDOW_RESIZABLE);
|
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN| SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
if (!m_window) {
|
if (!m_window) {
|
||||||
std::cerr << "Failed to create window: " << SDL_GetError() << std::endl;
|
std::cerr << "Failed to create window: " << SDL_GetError() << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
std::cout << "Step 2: SDL_CreateWindow completed" << std::endl;
|
||||||
|
|
||||||
// 3. Create OpenGL context
|
|
||||||
m_glContext = SDL_GL_CreateContext(m_window);
|
m_glContext = SDL_GL_CreateContext(m_window);
|
||||||
if (!m_glContext) {
|
if (!m_glContext) {
|
||||||
std::cerr << "Failed to create GL context: " << SDL_GetError() << std::endl;
|
std::cerr << "Failed to create GL context: " << SDL_GetError() << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 4. Optionally init GLEW (if not on macOS core profile)
|
std::cout << "Step 3: SDL_GL_CreateContext completed" << std::endl;
|
||||||
|
|
||||||
|
if (SDL_GL_MakeCurrent(m_window, m_glContext) != 0) {
|
||||||
|
std::cerr << "Failed to make GL context current: " << SDL_GetError() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "Step 4: SDL_GL_MakeCurrent completed" << std::endl;
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
glewExperimental = GL_TRUE;
|
glewExperimental = GL_TRUE;
|
||||||
GLenum glewErr = glewInit();
|
GLenum glewErr = glewInit();
|
||||||
if (glewInit() != GLEW_OK) {
|
if (glewErr != GLEW_OK) {
|
||||||
std::cerr << "Failed to init GLEW" << glewGetErrorString(glewErr) << std::endl;
|
std::cerr << "Failed to init GLEW: " << glewGetErrorString(glewErr) << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
glGetError();
|
std::cout << "Step 5: GLEW initialized successfully" << std::endl;
|
||||||
|
glGetError(); // Clear GLEW's initial error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
|
||||||
|
std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
|
||||||
|
std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
|
||||||
|
|
||||||
|
|
||||||
// 5. Set vsync (optional)
|
// 5. Set vsync (optional)
|
||||||
SDL_GL_SetSwapInterval(1); //Vsync
|
SDL_GL_SetSwapInterval(1); //Vsync
|
||||||
SdlWindow::GLClearError();
|
|
||||||
|
|
||||||
// 6. Mark as running
|
// 6. Mark as running
|
||||||
m_isRunning = true;
|
m_isRunning = true;
|
||||||
@ -122,8 +139,9 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
|
|||||||
|
|
||||||
VertexArray va;
|
VertexArray va;
|
||||||
VertexBuffer vb(positions, 4 * 2 * sizeof(float));
|
VertexBuffer vb(positions, 4 * 2 * sizeof(float));
|
||||||
IndexBuffer ib(indices, 6);
|
m_ib = new IndexBuffer(indices, 6);
|
||||||
m_ib = ib;
|
|
||||||
|
|
||||||
|
|
||||||
VertexBufferLayout layout;
|
VertexBufferLayout layout;
|
||||||
layout.Push<float>(2);
|
layout.Push<float>(2);
|
||||||
@ -135,10 +153,11 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
|
|||||||
std::cout << "VERTEX" << std::endl << source.VertexSource << std::endl;
|
std::cout << "VERTEX" << std::endl << source.VertexSource << std::endl;
|
||||||
std::cout << "FRAGMENT" << std::endl << source.FragmentSource << std::endl;
|
std::cout << "FRAGMENT" << std::endl << source.FragmentSource << std::endl;
|
||||||
|
|
||||||
unsigned int m_ShaderID = createShader(source.VertexSource, source.FragmentSource);
|
unsigned int shader = createShader(source.VertexSource, source.FragmentSource);
|
||||||
GLCall(glUseProgram(m_ShaderID));
|
std::cout << "shader: " << shader << std::endl;
|
||||||
|
GLCall(glUseProgram(shader));
|
||||||
|
|
||||||
GLCall(unsigned int location = glGetUniformLocation(m_ShaderID, "u_Color"));
|
GLCall(unsigned int location = glGetUniformLocation(shader, "u_Color"));
|
||||||
ASSERT(location != -1); // -1 is an error
|
ASSERT(location != -1); // -1 is an error
|
||||||
|
|
||||||
GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f));
|
GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f));
|
||||||
@ -150,7 +169,6 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SdlWindow::~SdlWindow() {
|
SdlWindow::~SdlWindow() {
|
||||||
// If using SDL Renderer, destroy it. But if you’re purely using OpenGL, you might remove it.
|
// If using SDL Renderer, destroy it. But if you’re purely using OpenGL, you might remove it.
|
||||||
if (m_renderer) {
|
if (m_renderer) {
|
||||||
@ -172,11 +190,15 @@ SdlWindow::~SdlWindow() {
|
|||||||
glDeleteProgram(shader);
|
glDeleteProgram(shader);
|
||||||
shader = 0;
|
shader = 0;
|
||||||
}
|
}
|
||||||
|
if (m_ib) {
|
||||||
|
delete m_ib;
|
||||||
|
m_ib = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//
|
||||||
void SdlWindow::run() {
|
void SdlWindow::run() {
|
||||||
while (m_isRunning) {
|
while (m_isRunning) {
|
||||||
processEvents();
|
processEvents();
|
||||||
@ -185,7 +207,7 @@ void SdlWindow::run() {
|
|||||||
}
|
}
|
||||||
GLCall(glDeleteProgram(shader));
|
GLCall(glDeleteProgram(shader));
|
||||||
}
|
}
|
||||||
|
//
|
||||||
void SdlWindow::processEvents() {
|
void SdlWindow::processEvents() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
@ -231,7 +253,7 @@ SDL_Event event;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
void SdlWindow::update() {
|
void SdlWindow::update() {
|
||||||
// Update game/application logic here
|
// Update game/application logic here
|
||||||
if (r > 1.0f) {
|
if (r > 1.0f) {
|
||||||
@ -241,7 +263,7 @@ void SdlWindow::update() {
|
|||||||
}
|
}
|
||||||
r += increment;
|
r += increment;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
void SdlWindow::render() {
|
void SdlWindow::render() {
|
||||||
// Use GL calls instead of SDL’s renderer
|
// Use GL calls instead of SDL’s renderer
|
||||||
GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); //background
|
GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); //background
|
||||||
@ -249,10 +271,12 @@ void SdlWindow::render() {
|
|||||||
GLCall(glClear(GL_COLOR_BUFFER_BIT));
|
GLCall(glClear(GL_COLOR_BUFFER_BIT));
|
||||||
|
|
||||||
GLCall(glUseProgram(shader));
|
GLCall(glUseProgram(shader));
|
||||||
|
std::cout << "shader: " << shader << std::endl;
|
||||||
|
std::cout << "location: " << location << std::endl;
|
||||||
GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
|
GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
|
||||||
|
|
||||||
va.Bind();
|
va->Bind();
|
||||||
m_ib.Bind();
|
m_ib->Bind();
|
||||||
// TODO: Draw with OpenGL here (shaders, triangles, etc.)
|
// TODO: Draw with OpenGL here (shaders, triangles, etc.)
|
||||||
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
|
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
|
||||||
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr)); //macro assert for debugging
|
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr)); //macro assert for debugging
|
||||||
@ -260,7 +284,7 @@ void SdlWindow::render() {
|
|||||||
// Swap buffers
|
// Swap buffers
|
||||||
SDL_GL_SwapWindow(m_window);
|
SDL_GL_SwapWindow(m_window);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
void SdlWindow::setFullscreen(bool fullscreen) {
|
void SdlWindow::setFullscreen(bool fullscreen) {
|
||||||
if (m_window) {
|
if (m_window) {
|
||||||
m_isFullscreen = fullscreen;
|
m_isFullscreen = fullscreen;
|
||||||
@ -283,7 +307,7 @@ void SdlWindow::setFullscreen(bool fullscreen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
unsigned int SdlWindow::compileShader(unsigned int type, const std::string& source) {
|
unsigned int SdlWindow::compileShader(unsigned int type, const std::string& source) {
|
||||||
GLCall(unsigned int id = glCreateShader(type));
|
GLCall(unsigned int id = glCreateShader(type));
|
||||||
const char* src = source.c_str(); // <--- this string needs to exist when compiling/running
|
const char* src = source.c_str(); // <--- this string needs to exist when compiling/running
|
||||||
@ -360,7 +384,7 @@ SdlWindow::ShaderProgramSource SdlWindow::parseShader(const std::string& filepat
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SdlWindow::GLClearError() {
|
void SdlWindow::GLClearError() {
|
||||||
//while (glGetError() != GL_NO_ERROR);
|
while (glGetError() != GL_NO_ERROR);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ private:
|
|||||||
float r;
|
float r;
|
||||||
SDL_GLContext m_glContext;
|
SDL_GLContext m_glContext;
|
||||||
float increment;
|
float increment;
|
||||||
// temp shader stuff
|
// // temp shader stuff
|
||||||
std::string vetexShader;
|
std::string vetexShader;
|
||||||
std::string fragmentShader;
|
std::string fragmentShader;
|
||||||
unsigned int buffer;
|
unsigned int buffer;
|
||||||
@ -64,9 +64,9 @@ private:
|
|||||||
unsigned int vao;
|
unsigned int vao;
|
||||||
unsigned int shader;
|
unsigned int shader;
|
||||||
unsigned int location;
|
unsigned int location;
|
||||||
VertexBufferLayout layout;
|
VertexBufferLayout* layout;
|
||||||
VertexArray va;
|
VertexArray* va;
|
||||||
IndexBuffer m_ib;
|
IndexBuffer* m_ib;
|
||||||
|
|
||||||
// Private methods
|
// Private methods
|
||||||
void processEvents();
|
void processEvents();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user