|
@@ -1,34 +1,36 @@
|
|
|
#include "Wrapper.h"
|
|
|
-#include <fstream>
|
|
|
-#include <cstring>
|
|
|
-#include <iostream>
|
|
|
-
|
|
|
-using namespace std;
|
|
|
|
|
|
DummyClient DummyClient::dummy;
|
|
|
|
|
|
IClient* Engine::client = &DummyClient::dummy;
|
|
|
GLFWwindow* Engine::window = nullptr;
|
|
|
|
|
|
-GLuint Engine::vShader = 0;
|
|
|
-GLuint Engine::fShader = 0;
|
|
|
-GLuint Engine::program = 0;
|
|
|
+
|
|
|
+GLuint Engine::activeProgram = 0;
|
|
|
+
|
|
|
+
|
|
|
+ShaderProgram Engine::worldShader;
|
|
|
+GLuint Engine::worldFrameBuffer = 0;
|
|
|
+GLuint Engine::worldPositionTexture = 0;
|
|
|
+GLuint Engine::worldNormalTexture = 0;
|
|
|
+GLuint Engine::worldColorTexture = 0;
|
|
|
+GLuint Engine::worldDepthRenderBuffer = 0;
|
|
|
|
|
|
+
|
|
|
GLuint Engine::postVba = 0;
|
|
|
GLuint Engine::postVbo = 0;
|
|
|
-GLuint Engine::postVShader = 0;
|
|
|
-GLuint Engine::postFShader = 0;
|
|
|
-GLuint Engine::postProgram = 0;
|
|
|
+ShaderProgram Engine::postShader;
|
|
|
|
|
|
-GLuint Engine::frameBuffer = 0;
|
|
|
-GLuint Engine::frameTexture = 0;
|
|
|
-GLuint Engine::depthTexture = 0;
|
|
|
int Engine::scale = 1;
|
|
|
int Engine::width = 0;
|
|
|
int Engine::height = 0;
|
|
|
|
|
|
bool Engine::lineMode = false;
|
|
|
|
|
|
+float Engine::testX = 0;
|
|
|
+float Engine::testY = 0;
|
|
|
+float Engine::testZ = 0;
|
|
|
+
|
|
|
bool Engine::init(int width, int height, const char* name)
|
|
|
{
|
|
|
Engine::width = width;
|
|
@@ -65,39 +67,18 @@ bool Engine::init(int width, int height, const char* name)
|
|
|
}
|
|
|
cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl;
|
|
|
|
|
|
- vShader = 0;
|
|
|
- fShader = 0;
|
|
|
- program = createProgram("shader/vertex.vs", "shader/fragment.fs", vShader, program);
|
|
|
-
|
|
|
- if(program == 0)
|
|
|
+ worldShader.compile("shader/worldVertex.vs", "shader/worldFragment.fs");
|
|
|
+ if(!worldShader.isValid())
|
|
|
{
|
|
|
- if(vShader != 0)
|
|
|
- {
|
|
|
- glDeleteShader(vShader);
|
|
|
- }
|
|
|
- if(fShader != 0)
|
|
|
- {
|
|
|
- glDeleteShader(fShader);
|
|
|
- }
|
|
|
glfwDestroyWindow(window);
|
|
|
glfwTerminate();
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
- postVShader = 0;
|
|
|
- postFShader = 0;
|
|
|
- postProgram = createProgram("shader/postVertex.vs", "shader/postFragment.fs", postVShader, postFShader);
|
|
|
-
|
|
|
- if(postProgram == 0)
|
|
|
+ activeProgram = worldShader.getProgram();
|
|
|
+
|
|
|
+ postShader.compile("shader/postVertex.vs", "shader/postFragment.fs");
|
|
|
+ if(!postShader.isValid())
|
|
|
{
|
|
|
- if(postVShader != 0)
|
|
|
- {
|
|
|
- glDeleteShader(postVShader);
|
|
|
- }
|
|
|
- if(postFShader != 0)
|
|
|
- {
|
|
|
- glDeleteShader(postFShader);
|
|
|
- }
|
|
|
glfwDestroyWindow(window);
|
|
|
glfwTerminate();
|
|
|
return false;
|
|
@@ -118,8 +99,7 @@ void Engine::start(IClient* client)
|
|
|
Engine::client = client;
|
|
|
}
|
|
|
|
|
|
- generateFramebuffer();
|
|
|
- generatePostData();
|
|
|
+ onInit();
|
|
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
@@ -153,51 +133,13 @@ void Engine::start(IClient* client)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- glActiveTexture(GL_TEXTURE0);
|
|
|
- glUseProgram(program);
|
|
|
- glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
|
|
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
- glEnable(GL_DEPTH_TEST);
|
|
|
- if(lineMode)
|
|
|
- {
|
|
|
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
|
- Engine::client->renderTick((float) lag / NANOS_PER_TICK);
|
|
|
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Engine::client->renderTick((float) lag / NANOS_PER_TICK);
|
|
|
- }
|
|
|
+ onRenderTick((float) lag / NANOS_PER_TICK);
|
|
|
|
|
|
-
|
|
|
- glActiveTexture(GL_TEXTURE1);
|
|
|
- glBindTexture(GL_TEXTURE_2D, frameTexture);
|
|
|
-
|
|
|
- glActiveTexture(GL_TEXTURE2);
|
|
|
- glBindTexture(GL_TEXTURE_2D, depthTexture);
|
|
|
-
|
|
|
- glUseProgram(postProgram);
|
|
|
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
- glClear(GL_COLOR_BUFFER_BIT);
|
|
|
- glDisable(GL_DEPTH_TEST);
|
|
|
- glBindVertexArray(postVba);
|
|
|
- glBindBuffer(GL_ARRAY_BUFFER, postVbo);
|
|
|
- glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
|
-
|
|
|
-
|
|
|
glfwSwapBuffers(window);
|
|
|
glfwPollEvents();
|
|
|
}
|
|
|
|
|
|
- destroyPostData();
|
|
|
- glDeleteFramebuffers(1, &frameBuffer);
|
|
|
- glDeleteShader(vShader);
|
|
|
- glDeleteShader(fShader);
|
|
|
- glDeleteProgram(program);
|
|
|
- glDeleteShader(postVShader);
|
|
|
- glDeleteShader(postFShader);
|
|
|
- glDeleteProgram(postProgram);
|
|
|
+ onTerm();
|
|
|
glfwDestroyWindow(window);
|
|
|
glfwTerminate();
|
|
|
}
|
|
@@ -207,162 +149,6 @@ void Engine::stop()
|
|
|
glfwSetWindowShouldClose(window, 1);
|
|
|
}
|
|
|
|
|
|
-GLchar* Engine::readFile(const char* name)
|
|
|
-{
|
|
|
- ifstream in;
|
|
|
- in.open(name);
|
|
|
- if(!in.fail())
|
|
|
- {
|
|
|
- int size = 128;
|
|
|
- int index = 0;
|
|
|
- GLchar* content = new GLchar[size];
|
|
|
-
|
|
|
- while(true)
|
|
|
- {
|
|
|
- GLchar c = in.get();
|
|
|
- if(in.eof())
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- if(index >= size - 1)
|
|
|
- {
|
|
|
- GLchar* newContent = new GLchar[size * 2];
|
|
|
- memcpy(newContent, content, size);
|
|
|
- size *= 2;
|
|
|
- delete[] content;
|
|
|
- content = newContent;
|
|
|
- }
|
|
|
- content[index] = c;
|
|
|
- index++;
|
|
|
- }
|
|
|
-
|
|
|
- content[index] = '\0';
|
|
|
- index++;
|
|
|
-
|
|
|
- in.close();
|
|
|
- return content;
|
|
|
- }
|
|
|
- return nullptr;
|
|
|
-}
|
|
|
-
|
|
|
-bool Engine::checkShaderErrors(const char* name, GLuint shader)
|
|
|
-{
|
|
|
- bool returnValue = false;
|
|
|
-
|
|
|
- cout << "compiling " << name << " shader ..." << endl;
|
|
|
- GLenum error = glGetError();
|
|
|
- if(error)
|
|
|
- {
|
|
|
- cout << "error: " << glGetError() << endl;
|
|
|
- returnValue = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cout << "no error occured ..." << endl;
|
|
|
- }
|
|
|
-
|
|
|
- GLint compiled[1];
|
|
|
- glGetShaderiv(shader, GL_COMPILE_STATUS, compiled);
|
|
|
- if(compiled[0])
|
|
|
- {
|
|
|
- cout << name << " shader successfully compiled" << endl;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cout << name << "compiling of " << name << " failed:" << endl;
|
|
|
- GLchar buffer[512];
|
|
|
- GLsizei bufferSize = 512;
|
|
|
- GLsizei charsUsed = 0;
|
|
|
- glGetShaderInfoLog(shader, bufferSize, &charsUsed, buffer);
|
|
|
-
|
|
|
- buffer[bufferSize - 1] = '\0';
|
|
|
- cout << buffer << endl;
|
|
|
- returnValue = true;
|
|
|
- }
|
|
|
- return returnValue;
|
|
|
-}
|
|
|
-
|
|
|
-GLuint Engine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* v, const GLchar* f)
|
|
|
-{
|
|
|
- vShader = glCreateShader(GL_VERTEX_SHADER);
|
|
|
- glShaderSource(vShader, 1, &v, nullptr);
|
|
|
- glCompileShader(vShader);
|
|
|
-
|
|
|
- if(checkShaderErrors("vertex", vShader))
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- fShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
- glShaderSource(fShader, 1, &f, nullptr);
|
|
|
- glCompileShader(fShader);
|
|
|
-
|
|
|
- if(checkShaderErrors("fragment", fShader))
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- GLuint program = glCreateProgram();
|
|
|
- glAttachShader(program, vShader);
|
|
|
- glAttachShader(program, fShader);
|
|
|
- glLinkProgram(program);
|
|
|
-
|
|
|
- cout << "linking shaders to program ..." << endl;
|
|
|
-
|
|
|
- GLenum error = glGetError();
|
|
|
- if(error)
|
|
|
- {
|
|
|
- cout << "error: " << glGetError() << endl;
|
|
|
- return 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cout << "no error occured ..." << endl;
|
|
|
- }
|
|
|
-
|
|
|
- GLint compiled[1];
|
|
|
- glGetProgramiv(program, GL_LINK_STATUS, compiled);
|
|
|
- if(compiled[0])
|
|
|
- {
|
|
|
- cout << "shaders successfully linked" << endl;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cout << "linking of shaders failed:" << endl;
|
|
|
- GLchar buffer[512];
|
|
|
- GLsizei bufferSize = 512;
|
|
|
- GLsizei charsUsed = 0;
|
|
|
- glGetProgramInfoLog(program, bufferSize, &charsUsed, buffer);
|
|
|
-
|
|
|
- buffer[bufferSize - 1] = '\0';
|
|
|
- cout << buffer << endl;
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return program;
|
|
|
-}
|
|
|
-
|
|
|
-GLuint Engine::createProgram(const char* v, const char* f, GLuint& vShader, GLuint& fShader)
|
|
|
-{
|
|
|
- GLchar* vertex = readFile(v);
|
|
|
- if(vertex == nullptr)
|
|
|
- {
|
|
|
- cout << "cannot read " << v << endl;
|
|
|
- return 0;
|
|
|
- }
|
|
|
- GLchar* fragment = readFile(f);
|
|
|
- if(fragment == nullptr)
|
|
|
- {
|
|
|
- cout << "cannot read " << f << endl;
|
|
|
- delete[] vertex;
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- GLuint program = compileProgram(vShader, fShader, vertex, fragment);
|
|
|
- delete[] vertex;
|
|
|
- delete[] fragment;
|
|
|
- return program;
|
|
|
-}
|
|
|
-
|
|
|
void Engine::onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mods)
|
|
|
{
|
|
|
client->onKeyEvent(key, scancode, action, mods);
|
|
@@ -380,14 +166,14 @@ void Engine::onWindowResize(GLFWwindow* w, int width, int height)
|
|
|
Engine::height = height;
|
|
|
updateScale();
|
|
|
|
|
|
- glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
|
|
+
|
|
|
glBindTexture(GL_TEXTURE_2D, frameTexture);
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, depthTexture);
|
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);*/
|
|
|
}
|
|
|
|
|
|
void Engine::updateScale()
|
|
@@ -416,7 +202,7 @@ int Engine::getHeight()
|
|
|
|
|
|
GLint Engine::getUniformLocation(const GLchar* name)
|
|
|
{
|
|
|
- return glGetUniformLocation(program, name);
|
|
|
+ return glGetUniformLocation(activeProgram, name);
|
|
|
}
|
|
|
|
|
|
void Engine::setMatrix(GLint location, const GLfloat* m)
|
|
@@ -468,40 +254,52 @@ void Engine::printError()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Engine::generateFramebuffer()
|
|
|
+void Engine::onInit()
|
|
|
{
|
|
|
- glGenFramebuffers(1, &frameBuffer);
|
|
|
- glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
|
|
-
|
|
|
- glGenTextures(1, &frameTexture);
|
|
|
- glBindTexture(GL_TEXTURE_2D, frameTexture);
|
|
|
-
|
|
|
+
|
|
|
+ glGenFramebuffers(1, &worldFrameBuffer);
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, worldFrameBuffer);
|
|
|
+
|
|
|
+ glGenTextures(1, &worldPositionTexture);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, worldPositionTexture);
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, worldPositionTexture, 0);
|
|
|
+
|
|
|
+ glGenTextures(1, &worldNormalTexture);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, worldNormalTexture);
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, worldNormalTexture, 0);
|
|
|
+
|
|
|
+ glGenTextures(1, &worldColorTexture);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, worldColorTexture);
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
|
|
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
- glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
-
|
|
|
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameTexture, 0);
|
|
|
-
|
|
|
- glGenTextures(1, &depthTexture);
|
|
|
- glBindTexture(GL_TEXTURE_2D, depthTexture);
|
|
|
-
|
|
|
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
|
|
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
- glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
-
|
|
|
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
|
|
|
-
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, worldColorTexture, 0);
|
|
|
+
|
|
|
+ GLuint attachments[3] =
|
|
|
+ {
|
|
|
+ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2
|
|
|
+ };
|
|
|
+ glDrawBuffers(3, attachments);
|
|
|
+
|
|
|
+ glGenRenderbuffers(1, &worldDepthRenderBuffer);
|
|
|
+ glBindRenderbuffer(GL_RENDERBUFFER, worldDepthRenderBuffer);
|
|
|
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
|
|
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, worldDepthRenderBuffer);
|
|
|
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
+
|
|
|
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
|
{
|
|
|
- cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
|
|
|
+ cout << "world frame buffer is not complete!" << endl;
|
|
|
}
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
-}
|
|
|
-
|
|
|
-void Engine::generatePostData()
|
|
|
-{
|
|
|
+
|
|
|
+
|
|
|
glGenVertexArrays(1, &postVba);
|
|
|
glBindVertexArray(postVba);
|
|
|
|
|
@@ -527,10 +325,63 @@ void Engine::generatePostData()
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 24, data, GL_STATIC_DRAW);
|
|
|
}
|
|
|
|
|
|
-void Engine::destroyPostData()
|
|
|
+void Engine::onRenderTick(float lag)
|
|
|
+{
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ glActiveTexture(GL_TEXTURE0);
|
|
|
+
|
|
|
+ activeProgram = worldShader.getProgram();
|
|
|
+ glUseProgram(activeProgram);
|
|
|
+
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, worldFrameBuffer);
|
|
|
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
|
+ glEnable(GL_DEPTH_TEST);
|
|
|
+ if(lineMode)
|
|
|
+ {
|
|
|
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
|
+ Engine::client->renderTick(lag);
|
|
|
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Engine::client->renderTick(lag);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ glActiveTexture(GL_TEXTURE1);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, worldPositionTexture);
|
|
|
+ glActiveTexture(GL_TEXTURE2);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, worldNormalTexture);
|
|
|
+ glActiveTexture(GL_TEXTURE3);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, worldColorTexture);
|
|
|
+
|
|
|
+ activeProgram = postShader.getProgram();
|
|
|
+ glUseProgram(activeProgram);
|
|
|
+
|
|
|
+ glUniform3f(glGetUniformLocation(activeProgram, "viewPos"), testX, testY, testZ);
|
|
|
+
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
+ glClear(GL_COLOR_BUFFER_BIT);
|
|
|
+ glDisable(GL_DEPTH_TEST);
|
|
|
+ glBindVertexArray(postVba);
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, postVbo);
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
|
+}
|
|
|
+
|
|
|
+void Engine::onTerm()
|
|
|
{
|
|
|
glDeleteVertexArrays(1, &postVba);
|
|
|
glDeleteBuffers(1, &postVbo);
|
|
|
+
|
|
|
+ glDeleteFramebuffers(1, &worldFrameBuffer);
|
|
|
+ glDeleteTextures(1, &worldPositionTexture);
|
|
|
+ glDeleteTextures(1, &worldNormalTexture);
|
|
|
+ glDeleteTextures(1, &worldColorTexture);
|
|
|
+ glDeleteRenderbuffers(1, &worldDepthRenderBuffer);
|
|
|
}
|
|
|
|
|
|
void Engine::setLineMode(bool mode)
|