mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 20:02:40 +01:00
Initial rendering refactor
This commit is contained in:
parent
4d78cacd84
commit
668848952b
@ -203,7 +203,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* The vehicle colour palettes
|
* The vehicle colour palettes
|
||||||
*/
|
*/
|
||||||
std::vector<glm::vec3> vehicleColours;
|
std::vector<glm::u8vec3> vehicleColours;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The vehicle colours for each vehicle type
|
* The vehicle colours for each vehicle type
|
||||||
|
@ -21,8 +21,8 @@ public:
|
|||||||
|
|
||||||
VehicleDataHandle vehicle;
|
VehicleDataHandle vehicle;
|
||||||
VehicleInfoHandle info;
|
VehicleInfoHandle info;
|
||||||
glm::vec3 colourPrimary;
|
glm::u8vec3 colourPrimary;
|
||||||
glm::vec3 colourSecondary;
|
glm::u8vec3 colourSecondary;
|
||||||
|
|
||||||
std::map<size_t, GameObject*> seatOccupants;
|
std::map<size_t, GameObject*> seatOccupants;
|
||||||
|
|
||||||
@ -44,8 +44,8 @@ public:
|
|||||||
ModelHandle* model,
|
ModelHandle* model,
|
||||||
VehicleDataHandle data,
|
VehicleDataHandle data,
|
||||||
VehicleInfoHandle info,
|
VehicleInfoHandle info,
|
||||||
const glm::vec3& prim,
|
const glm::u8vec3& prim,
|
||||||
const glm::vec3& sec);
|
const glm::u8vec3& sec);
|
||||||
|
|
||||||
virtual ~VehicleObject();
|
virtual ~VehicleObject();
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include <render/ViewCamera.hpp>
|
#include <render/ViewCamera.hpp>
|
||||||
|
|
||||||
|
#include <render/OpenGLRenderer.hpp>
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
class ModelFrame;
|
class ModelFrame;
|
||||||
class GameWorld;
|
class GameWorld;
|
||||||
@ -24,6 +26,8 @@ class CutsceneObject;
|
|||||||
class Animator;
|
class Animator;
|
||||||
class InventoryItem;
|
class InventoryItem;
|
||||||
|
|
||||||
|
class Renderer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implements high level drawing logic and low level draw commands
|
* @brief Implements high level drawing logic and low level draw commands
|
||||||
*
|
*
|
||||||
@ -35,13 +39,16 @@ class GameRenderer
|
|||||||
/** Pointer to the world instance */
|
/** Pointer to the world instance */
|
||||||
GameWorld* engine;
|
GameWorld* engine;
|
||||||
|
|
||||||
/** Data required to queue transparent objects for delayed rendering */
|
/** The low-level drawing interface to use */
|
||||||
|
Renderer* renderer;
|
||||||
|
|
||||||
|
/** Stores data for deferring transparent objects */
|
||||||
struct RQueueEntry {
|
struct RQueueEntry {
|
||||||
Model* model;
|
Model* model;
|
||||||
size_t g;
|
size_t g;
|
||||||
size_t sg;
|
size_t sg;
|
||||||
glm::mat4 matrix;
|
glm::mat4 matrix;
|
||||||
float opacity;
|
Renderer::DrawParameters dp;
|
||||||
GameObject* object;
|
GameObject* object;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,18 +63,6 @@ class GameRenderer
|
|||||||
*/
|
*/
|
||||||
bool renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix, GameObject* object, float opacity, bool queueTransparent = true);
|
bool renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix, GameObject* object, float opacity, bool queueTransparent = true);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief renders a model's subgeometry
|
|
||||||
* @param model
|
|
||||||
* @param g
|
|
||||||
* @param sg
|
|
||||||
* @param matrix
|
|
||||||
* @param object
|
|
||||||
* @param queueTransparent
|
|
||||||
* @return @see renderFrame(
|
|
||||||
*/
|
|
||||||
bool renderSubgeometry(Model* model, size_t g, size_t sg, const glm::mat4& matrix, float opacity, GameObject* object, bool queueTransparent = true);
|
|
||||||
|
|
||||||
/** Transparent objects are queued into this list */
|
/** Transparent objects are queued into this list */
|
||||||
std::vector<RQueueEntry> transparentDrawQueue;
|
std::vector<RQueueEntry> transparentDrawQueue;
|
||||||
|
|
||||||
@ -149,14 +144,10 @@ public:
|
|||||||
size_t geoms;
|
size_t geoms;
|
||||||
|
|
||||||
/** @todo Clean up all these shader program and location variables */
|
/** @todo Clean up all these shader program and location variables */
|
||||||
GLuint worldProgram;
|
Renderer::ShaderProgram* worldProg;
|
||||||
GLint uniTexture;
|
Renderer::ShaderProgram* skyProg;
|
||||||
GLuint ubiScene, ubiObject;
|
Renderer::ShaderProgram* waterProg;
|
||||||
GLuint uboScene, uboObject;
|
|
||||||
|
|
||||||
GLuint skyProgram;
|
|
||||||
GLuint waterProgram, waterMVP, waterHeight, waterTexture, waterSize, waterTime, waterPosition, waterWave;
|
|
||||||
GLint skyUniView, skyUniProj, skyUniTop, skyUniBottom;
|
|
||||||
GLuint particleProgram;
|
GLuint particleProgram;
|
||||||
|
|
||||||
GLuint ssRectProgram;
|
GLuint ssRectProgram;
|
||||||
@ -165,6 +156,9 @@ public:
|
|||||||
GLuint skydomeVBO, skydomeIBO, debugVBO;
|
GLuint skydomeVBO, skydomeIBO, debugVBO;
|
||||||
GLuint debugTex;
|
GLuint debugTex;
|
||||||
|
|
||||||
|
DrawBuffer skyDbuff;
|
||||||
|
GeometryBuffer skyGbuff;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the world using the parameters of the passed Camera.
|
* Renders the world using the parameters of the passed Camera.
|
||||||
* Note: The camera's near and far planes are overriden by weather effects.
|
* Note: The camera's near and far planes are overriden by weather effects.
|
||||||
@ -233,38 +227,6 @@ public:
|
|||||||
|
|
||||||
/** Adds a particle to the rendering */
|
/** Adds a particle to the rendering */
|
||||||
void addParticle(const FXParticle& particle);
|
void addParticle(const FXParticle& particle);
|
||||||
|
|
||||||
static GLuint currentUBO;
|
|
||||||
/**
|
|
||||||
* Uploads data from T into the specified UBO
|
|
||||||
*/
|
|
||||||
template<class T> void uploadUBO(GLuint buffer, const T& data)
|
|
||||||
{
|
|
||||||
if( currentUBO != buffer ) {
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
|
|
||||||
currentUBO = buffer;
|
|
||||||
}
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(T), &data, GL_DYNAMIC_DRAW);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SceneUniformData {
|
|
||||||
glm::mat4 projection;
|
|
||||||
glm::mat4 view;
|
|
||||||
glm::vec4 ambient;
|
|
||||||
glm::vec4 dynamic;
|
|
||||||
glm::vec4 fogColour;
|
|
||||||
glm::vec4 campos;
|
|
||||||
float fogStart;
|
|
||||||
float fogEnd;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ObjectUniformData {
|
|
||||||
glm::mat4 model;
|
|
||||||
glm::vec4 colour;
|
|
||||||
float diffuse;
|
|
||||||
float ambient;
|
|
||||||
float visibility;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
169
rwengine/include/render/OpenGLRenderer.hpp
Normal file
169
rwengine/include/render/OpenGLRenderer.hpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _OPENGLRENDERER_HPP_
|
||||||
|
#define _OPENGLRENDERER_HPP_
|
||||||
|
|
||||||
|
#include <engine/RWTypes.hpp>
|
||||||
|
#include <render/DrawBuffer.hpp>
|
||||||
|
#include <render/GeometryBuffer.hpp>
|
||||||
|
|
||||||
|
typedef std::uint32_t RenderIndex;
|
||||||
|
|
||||||
|
struct VertexP3
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
|
||||||
|
static const AttributeList vertex_attributes() {
|
||||||
|
return {
|
||||||
|
{ATRS_Position, 3, sizeof(VertexP3), 0ul},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @todo normalize this to have the same interface as VertexP3
|
||||||
|
struct VertexP2 {
|
||||||
|
static const AttributeList vertex_attributes() {
|
||||||
|
return {
|
||||||
|
{ATRS_Position, 2, sizeof(VertexP2), 0ul}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
float x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Renderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct DrawParameters
|
||||||
|
{
|
||||||
|
GLuint texture; /// @todo replace with texture handle.
|
||||||
|
glm::u8vec4 colour;
|
||||||
|
float ambient;
|
||||||
|
float diffuse;
|
||||||
|
|
||||||
|
size_t count; /// The number of indicies to draw
|
||||||
|
unsigned int start; /// Start index.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectUniformData {
|
||||||
|
glm::mat4 model;
|
||||||
|
glm::vec4 colour;
|
||||||
|
float diffuse;
|
||||||
|
float ambient;
|
||||||
|
float visibility;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceneUniformData {
|
||||||
|
glm::mat4 projection;
|
||||||
|
glm::mat4 view;
|
||||||
|
glm::vec4 ambient;
|
||||||
|
glm::vec4 dynamic;
|
||||||
|
glm::vec4 fogColour;
|
||||||
|
glm::vec4 campos;
|
||||||
|
float fogStart;
|
||||||
|
float fogEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderProgram {
|
||||||
|
// This just provides an opaque handle for external users.
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual std::string getIDString() const = 0;
|
||||||
|
|
||||||
|
virtual ShaderProgram* createShader(const std::string& vert, const std::string& frag) = 0;
|
||||||
|
|
||||||
|
virtual void useProgram(ShaderProgram* p) = 0;
|
||||||
|
|
||||||
|
/// @todo dont use GLint in the interface.
|
||||||
|
virtual void setProgramBlockBinding(ShaderProgram* p, const std::string& name, GLint point) = 0;
|
||||||
|
virtual void setUniformTexture(ShaderProgram*p, const std::string& name, GLint tex) = 0;
|
||||||
|
virtual void setUniform(ShaderProgram*p, const std::string& name, const glm::vec4& v) = 0;
|
||||||
|
virtual void setUniform(ShaderProgram*p, const std::string& name, const glm::vec3& v) = 0;
|
||||||
|
virtual void setUniform(ShaderProgram*p, const std::string& name, const glm::vec2& v) = 0;
|
||||||
|
virtual void setUniform(ShaderProgram*p, const std::string& name, float f) = 0;
|
||||||
|
|
||||||
|
virtual void clear(const glm::vec4& colour, bool clearColour = true, bool clearDepth = true) = 0;
|
||||||
|
|
||||||
|
virtual void setSceneParameters(const SceneUniformData& data) = 0;
|
||||||
|
|
||||||
|
virtual void draw(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) = 0;
|
||||||
|
virtual void drawArrays(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenGLRenderer : public Renderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
class OpenGLShaderProgram : public ShaderProgram {
|
||||||
|
GLuint program;
|
||||||
|
std::map<std::string, GLint> uniforms;
|
||||||
|
public:
|
||||||
|
OpenGLShaderProgram(GLuint p)
|
||||||
|
: program(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
GLuint getName() const { return program; }
|
||||||
|
|
||||||
|
GLint getUniformLocation(const std::string& name) {
|
||||||
|
auto c = uniforms.find(name.c_str());
|
||||||
|
GLint loc = -1;
|
||||||
|
if( c == uniforms.end() ) {
|
||||||
|
loc = glGetUniformLocation(program, name.c_str());
|
||||||
|
uniforms[name] = loc;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
loc = c->second;
|
||||||
|
}
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OpenGLRenderer();
|
||||||
|
|
||||||
|
std::string getIDString() const;
|
||||||
|
|
||||||
|
ShaderProgram* createShader(const std::string &vert, const std::string &frag);
|
||||||
|
void setProgramBlockBinding(ShaderProgram* p, const std::string &name, GLint point);
|
||||||
|
void setUniformTexture(ShaderProgram* p, const std::string &name, GLint tex);
|
||||||
|
void setUniform(ShaderProgram* p, const std::string& name, const glm::vec4& m);
|
||||||
|
void setUniform(ShaderProgram* p, const std::string& name, const glm::vec3& m);
|
||||||
|
void setUniform(ShaderProgram* p, const std::string& name, const glm::vec2& m);
|
||||||
|
void setUniform(ShaderProgram* p, const std::string& name, float f);
|
||||||
|
void useProgram(ShaderProgram* p);
|
||||||
|
|
||||||
|
void clear(const glm::vec4 &colour, bool clearColour, bool clearDepth);
|
||||||
|
|
||||||
|
void setSceneParameters(const SceneUniformData &data);
|
||||||
|
|
||||||
|
void draw(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p);
|
||||||
|
void drawArrays(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DrawBuffer* currentDbuff;
|
||||||
|
|
||||||
|
void useDrawBuffer(DrawBuffer* dbuff);
|
||||||
|
|
||||||
|
GLuint currentTexture;
|
||||||
|
void useTexture(GLuint tex);
|
||||||
|
|
||||||
|
OpenGLShaderProgram* currentProgram;
|
||||||
|
|
||||||
|
GLuint currentUBO;
|
||||||
|
template<class T> void uploadUBO(GLuint buffer, const T& data)
|
||||||
|
{
|
||||||
|
if( currentUBO != buffer ) {
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
|
||||||
|
currentUBO = buffer;
|
||||||
|
}
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(T), &data, GL_DYNAMIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint UBOObject;
|
||||||
|
GLuint UBOScene;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @todo remove these from here
|
||||||
|
GLuint compileShader(GLenum type, const char *source);
|
||||||
|
GLuint compileProgram(const char* vertex, const char* fragment);
|
||||||
|
|
||||||
|
#endif
|
@ -280,10 +280,10 @@ void GameData::loadCarcols(const std::string& path)
|
|||||||
std::stringstream ss(line);
|
std::stringstream ss(line);
|
||||||
|
|
||||||
if( std::getline(ss, r, ',') && std::getline(ss, g, ',') && std::getline(ss, b)) {
|
if( std::getline(ss, r, ',') && std::getline(ss, g, ',') && std::getline(ss, b)) {
|
||||||
vehicleColours.push_back(glm::vec3(
|
vehicleColours.push_back(glm::u8vec3(
|
||||||
atoi(r.c_str())/255.f,
|
atoi(r.c_str()),
|
||||||
atoi(g.c_str())/255.f,
|
atoi(g.c_str()),
|
||||||
atoi(b.c_str())/255.f
|
atoi(b.c_str())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@ bool GameWorld::load()
|
|||||||
void GameWorld::logInfo(const std::string& info)
|
void GameWorld::logInfo(const std::string& info)
|
||||||
{
|
{
|
||||||
log.push_back({LogEntry::Info, gameTime, info});
|
log.push_back({LogEntry::Info, gameTime, info});
|
||||||
|
std::cout << info << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameWorld::logError(const std::string& error)
|
void GameWorld::logError(const std::string& error)
|
||||||
@ -418,7 +419,7 @@ VehicleObject *GameWorld::createVehicle(const uint16_t id, const glm::vec3& pos,
|
|||||||
gameData.loadTXD(vti->second->textureName + ".txd");
|
gameData.loadTXD(vti->second->textureName + ".txd");
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 prim = glm::vec3(1.f), sec = glm::vec3(0.5f);
|
glm::u8vec3 prim(255), sec(128);
|
||||||
auto palit = gameData.vehiclePalettes.find(vti->second->modelName); // modelname is conveniently lowercase (usually)
|
auto palit = gameData.vehiclePalettes.find(vti->second->modelName); // modelname is conveniently lowercase (usually)
|
||||||
if(palit != gameData.vehiclePalettes.end() && palit->second.size() > 0 ) {
|
if(palit != gameData.vehiclePalettes.end() && palit->second.size() > 0 ) {
|
||||||
std::uniform_int_distribution<int> uniform(0, palit->second.size()-1);
|
std::uniform_int_distribution<int> uniform(0, palit->second.size()-1);
|
||||||
|
@ -246,6 +246,7 @@ void LoaderDFF::readGeometry(Model *model, const RWBStream &stream)
|
|||||||
sizeof(uint32_t) * sg.numIndices,
|
sizeof(uint32_t) * sg.numIndices,
|
||||||
sg.indices.data());
|
sg.indices.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoaderDFF::readMaterialList(Model *model, const RWBStream &stream)
|
void LoaderDFF::readMaterialList(Model *model, const RWBStream &stream)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <render/Model.hpp>
|
#include <render/Model.hpp>
|
||||||
#include <engine/Animator.hpp>
|
#include <engine/Animator.hpp>
|
||||||
|
|
||||||
VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, ModelHandle* model, VehicleDataHandle data, VehicleInfoHandle info, const glm::vec3& prim, const glm::vec3& sec)
|
VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, ModelHandle* model, VehicleDataHandle data, VehicleInfoHandle info, const glm::u8vec3& prim, const glm::u8vec3& sec)
|
||||||
: GameObject(engine, pos, rot, model),
|
: GameObject(engine, pos, rot, model),
|
||||||
steerAngle(0.f), throttle(0.f), brake(0.f), handbrake(false),
|
steerAngle(0.f), throttle(0.f), brake(0.f), handbrake(false),
|
||||||
vehicle(data), info(info), colourPrimary(prim),
|
vehicle(data), info(info), colourPrimary(prim),
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
GLuint GameRenderer::currentUBO = 0;
|
|
||||||
|
|
||||||
const size_t skydomeSegments = 8, skydomeRows = 10;
|
const size_t skydomeSegments = 8, skydomeRows = 10;
|
||||||
|
|
||||||
struct WaterVertex {
|
struct WaterVertex {
|
||||||
@ -69,16 +67,6 @@ struct ParticleVert {
|
|||||||
GeometryBuffer particleGeom;
|
GeometryBuffer particleGeom;
|
||||||
DrawBuffer particleDraw;
|
DrawBuffer particleDraw;
|
||||||
|
|
||||||
struct VertexP2 {
|
|
||||||
static const AttributeList vertex_attributes() {
|
|
||||||
return {
|
|
||||||
{ATRS_Position, 2, sizeof(VertexP2), 0ul}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
float x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<VertexP2> sspaceRect = {
|
std::vector<VertexP2> sspaceRect = {
|
||||||
{-1.f, -1.f},
|
{-1.f, -1.f},
|
||||||
{ 1.f, -1.f},
|
{ 1.f, -1.f},
|
||||||
@ -89,98 +77,18 @@ std::vector<VertexP2> sspaceRect = {
|
|||||||
GeometryBuffer ssRectGeom;
|
GeometryBuffer ssRectGeom;
|
||||||
DrawBuffer ssRectDraw;
|
DrawBuffer ssRectDraw;
|
||||||
|
|
||||||
GLuint compileShader(GLenum type, const char *source)
|
|
||||||
{
|
|
||||||
GLuint shader = glCreateShader(type);
|
|
||||||
glShaderSource(shader, 1, &source, NULL);
|
|
||||||
glCompileShader(shader);
|
|
||||||
|
|
||||||
GLint status;
|
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
|
||||||
|
|
||||||
if( status != GL_TRUE ) {
|
|
||||||
std::cerr << "[OGL] Shader Compilation Failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint len;
|
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
|
||||||
if( len > 1 ) {
|
|
||||||
GLchar *buffer = new GLchar[len];
|
|
||||||
glGetShaderInfoLog(shader, len, NULL, buffer);
|
|
||||||
|
|
||||||
GLint sourceLen;
|
|
||||||
glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLen);
|
|
||||||
GLchar *sourceBuff = new GLchar[sourceLen];
|
|
||||||
glGetShaderSource(shader, sourceLen, nullptr, sourceBuff);
|
|
||||||
|
|
||||||
std::cerr << "[OGL] Shader InfoLog(" << shader << "):\n" << buffer << "\nSource:\n" << sourceBuff << std::endl;
|
|
||||||
|
|
||||||
delete[] buffer;
|
|
||||||
delete[] sourceBuff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != GL_TRUE) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint compileProgram(const char* vertex, const char* fragment)
|
|
||||||
{
|
|
||||||
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertex);
|
|
||||||
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragment);
|
|
||||||
GLuint prog = glCreateProgram();
|
|
||||||
glAttachShader(prog, vertexShader);
|
|
||||||
glAttachShader(prog, fragmentShader);
|
|
||||||
glLinkProgram(prog);
|
|
||||||
|
|
||||||
GLint status;
|
|
||||||
glGetProgramiv(prog, GL_LINK_STATUS, &status);
|
|
||||||
|
|
||||||
if( status != GL_TRUE ) {
|
|
||||||
std::cerr << "[OGL] Program Link Failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint len;
|
|
||||||
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
|
|
||||||
if( len > 1 ) {
|
|
||||||
GLchar *buffer = new GLchar[len];
|
|
||||||
glGetProgramInfoLog(prog, len, NULL, buffer);
|
|
||||||
|
|
||||||
std::cerr << "[OGL] Program InfoLog(" << prog << "):\n" << buffer << std::endl;
|
|
||||||
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != GL_TRUE) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDeleteShader(vertexShader);
|
|
||||||
glDeleteShader(fragmentShader);
|
|
||||||
|
|
||||||
return prog;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameRenderer::GameRenderer(GameWorld* engine)
|
GameRenderer::GameRenderer(GameWorld* engine)
|
||||||
: engine(engine), _renderAlpha(0.f)
|
: engine(engine), renderer(new OpenGLRenderer), _renderAlpha(0.f)
|
||||||
{
|
{
|
||||||
worldProgram = compileProgram(GameShaders::WorldObject::VertexShader,
|
engine->logInfo("[DRAW] " + renderer->getIDString());
|
||||||
GameShaders::WorldObject::FragmentShader);
|
|
||||||
|
|
||||||
uniTexture = glGetUniformLocation(worldProgram, "texture");
|
worldProg = renderer->createShader(
|
||||||
ubiScene = glGetUniformBlockIndex(worldProgram, "SceneData");
|
GameShaders::WorldObject::VertexShader,
|
||||||
ubiObject = glGetUniformBlockIndex(worldProgram, "ObjectData");
|
GameShaders::WorldObject::FragmentShader);
|
||||||
|
|
||||||
glGenBuffers(1, &uboScene);
|
renderer->setUniformTexture(worldProg, "texture", 0);
|
||||||
glGenBuffers(1, &uboObject);
|
renderer->setProgramBlockBinding(worldProg, "SceneData", 1);
|
||||||
|
renderer->setProgramBlockBinding(worldProg, "ObjectData", 2);
|
||||||
glUniformBlockBinding(worldProgram, ubiScene, 1);
|
|
||||||
glUniformBlockBinding(worldProgram, ubiObject, 2);
|
|
||||||
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 1, uboScene);
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 2, uboObject);
|
|
||||||
|
|
||||||
particleProgram = compileProgram(GameShaders::WorldObject::VertexShader,
|
particleProgram = compileProgram(GameShaders::WorldObject::VertexShader,
|
||||||
GameShaders::Particle::FragmentShader);
|
GameShaders::Particle::FragmentShader);
|
||||||
@ -189,27 +97,23 @@ GameRenderer::GameRenderer(GameWorld* engine)
|
|||||||
ubiScene = glGetUniformBlockIndex(particleProgram, "SceneData");
|
ubiScene = glGetUniformBlockIndex(particleProgram, "SceneData");
|
||||||
ubiObject = glGetUniformBlockIndex(particleProgram, "ObjectData");*/
|
ubiObject = glGetUniformBlockIndex(particleProgram, "ObjectData");*/
|
||||||
|
|
||||||
glUniformBlockBinding(particleProgram, ubiScene, 1);
|
//glUniformBlockBinding(particleProgram, ubiScene, 1);
|
||||||
glUniformBlockBinding(particleProgram, ubiObject, 2);
|
//glUniformBlockBinding(particleProgram, ubiObject, 2);
|
||||||
|
|
||||||
skyProgram = compileProgram(GameShaders::Sky::VertexShader,
|
skyProg = renderer->createShader(
|
||||||
GameShaders::Sky::FragmentShader);
|
GameShaders::Sky::VertexShader,
|
||||||
|
GameShaders::Sky::FragmentShader);
|
||||||
|
|
||||||
skyUniView = glGetUniformLocation(skyProgram, "view");
|
renderer->setProgramBlockBinding(skyProg, "SceneData", 1);
|
||||||
skyUniProj = glGetUniformLocation(skyProgram, "proj");
|
|
||||||
skyUniTop = glGetUniformLocation(skyProgram, "TopColor");
|
|
||||||
skyUniBottom = glGetUniformLocation(skyProgram, "BottomColor");
|
|
||||||
|
|
||||||
waterProgram = compileProgram(GameShaders::WaterHQ::VertexShader,
|
waterProg = renderer->createShader(
|
||||||
GameShaders::WaterHQ::FragmentShader);
|
GameShaders::WaterHQ::VertexShader,
|
||||||
|
GameShaders::WaterHQ::FragmentShader);
|
||||||
|
|
||||||
waterHeight = glGetUniformLocation(waterProgram, "height");
|
renderer->setUniformTexture(waterProg, "texture", 0);
|
||||||
waterTexture = glGetUniformLocation(waterProgram, "texture");
|
|
||||||
waterSize = glGetUniformLocation(waterProgram, "size");
|
renderer->setProgramBlockBinding(waterProg, "SceneData", 1);
|
||||||
waterMVP = glGetUniformLocation(waterProgram, "MVP");
|
renderer->setProgramBlockBinding(waterProg, "ObjectData", 2);
|
||||||
waterTime = glGetUniformLocation(waterProgram, "time");
|
|
||||||
waterPosition = glGetUniformLocation(waterProgram, "worldP");
|
|
||||||
waterWave = glGetUniformLocation(waterProgram, "waveParams");
|
|
||||||
|
|
||||||
glGenVertexArrays( 1, &vao );
|
glGenVertexArrays( 1, &vao );
|
||||||
|
|
||||||
@ -240,28 +144,29 @@ GameRenderer::GameRenderer(GameWorld* engine)
|
|||||||
waterHQDraw.setFaceType(GL_TRIANGLES);
|
waterHQDraw.setFaceType(GL_TRIANGLES);
|
||||||
|
|
||||||
|
|
||||||
// And our skydome while we're at it.
|
// Create the skydome
|
||||||
glGenBuffers(1, &skydomeVBO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, skydomeVBO);
|
|
||||||
size_t segments = skydomeSegments, rows = skydomeRows;
|
size_t segments = skydomeSegments, rows = skydomeRows;
|
||||||
|
|
||||||
float R = 1.f/(float)(rows-1);
|
float R = 1.f/(float)(rows-1);
|
||||||
float S = 1.f/(float)(segments-1);
|
float S = 1.f/(float)(segments-1);
|
||||||
std::vector<glm::vec3> skydomeBuff;
|
std::vector<VertexP3> skydomeVerts;
|
||||||
skydomeBuff.resize(rows * segments);
|
skydomeVerts.resize(rows * segments);
|
||||||
for( size_t r = 0, i = 0; r < rows; ++r) {
|
for( size_t r = 0, i = 0; r < rows; ++r) {
|
||||||
for( size_t s = 0; s < segments; ++s) {
|
for( size_t s = 0; s < segments; ++s) {
|
||||||
skydomeBuff[i++] = glm::vec3(
|
skydomeVerts[i++].position = glm::vec3(
|
||||||
cos(2.f * M_PI * s * S) * cos(M_PI_2 * r * R),
|
cos(2.f * M_PI * s * S) * cos(M_PI_2 * r * R),
|
||||||
sin(2.f * M_PI * s * S) * cos(M_PI_2 * r * R),
|
sin(2.f * M_PI * s * S) * cos(M_PI_2 * r * R),
|
||||||
sin(M_PI_2 * r * R)
|
sin(M_PI_2 * r * R)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(skydomeBuff), skydomeBuff.data(), GL_STATIC_DRAW);
|
skyGbuff.uploadVertices(skydomeVerts);
|
||||||
|
skyDbuff.addGeometry(&skyGbuff);
|
||||||
|
skyDbuff.setFaceType(GL_TRIANGLES);
|
||||||
|
|
||||||
glGenBuffers(1, &skydomeIBO);
|
glGenBuffers(1, &skydomeIBO);
|
||||||
GLushort skydomeIndBuff[rows*segments*6];
|
GLuint skydomeIndBuff[rows*segments*6];
|
||||||
for( size_t r = 0, i = 0; r < (rows-1); ++r ) {
|
for( size_t r = 0, i = 0; r < (rows-1); ++r ) {
|
||||||
for( size_t s = 0; s < (segments-1); ++s ) {
|
for( size_t s = 0; s < (segments-1); ++s ) {
|
||||||
skydomeIndBuff[i++] = r * segments + s;
|
skydomeIndBuff[i++] = r * segments + s;
|
||||||
@ -275,6 +180,8 @@ GameRenderer::GameRenderer(GameWorld* engine)
|
|||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skydomeIBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skydomeIBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(skydomeIndBuff), skydomeIndBuff, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(skydomeIndBuff), skydomeIndBuff, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glGenBuffers(1, &debugVBO);
|
glGenBuffers(1, &debugVBO);
|
||||||
glGenTextures(1, &debugTex);
|
glGenTextures(1, &debugTex);
|
||||||
glGenVertexArrays(1, &debugVAO);
|
glGenVertexArrays(1, &debugVAO);
|
||||||
@ -341,33 +248,31 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
|
|||||||
_camera.frustum.near = engine->state.cameraNear;
|
_camera.frustum.near = engine->state.cameraNear;
|
||||||
_camera.frustum.far = weather.farClipping;
|
_camera.frustum.far = weather.farClipping;
|
||||||
|
|
||||||
glUseProgram(worldProgram);
|
|
||||||
|
|
||||||
auto view = _camera.getView();
|
auto view = _camera.getView();
|
||||||
auto proj = _camera.frustum.projection();
|
auto proj = _camera.frustum.projection();
|
||||||
|
|
||||||
uploadUBO<SceneUniformData>(
|
Renderer::SceneUniformData sceneParams {
|
||||||
uboScene,
|
proj,
|
||||||
{
|
view,
|
||||||
proj,
|
glm::vec4{ambient, 0.0f},
|
||||||
view,
|
glm::vec4{dynamic, 0.0f},
|
||||||
glm::vec4{ambient, 0.0f},
|
glm::vec4(skyBottom, 1.f),
|
||||||
glm::vec4{dynamic, 0.0f},
|
glm::vec4(camera.position, 0.f),
|
||||||
glm::vec4(skyBottom, 1.f),
|
weather.fogStart,
|
||||||
glm::vec4(camera.position, 0.f),
|
camera.frustum.far
|
||||||
weather.fogStart,
|
};
|
||||||
camera.frustum.far
|
|
||||||
});
|
|
||||||
|
|
||||||
glClearColor(skyBottom.r, skyBottom.g, skyBottom.b, 1.f);
|
renderer->setSceneParameters(sceneParams);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
renderer->clear(glm::vec4(skyBottom, 1.f));
|
||||||
|
|
||||||
_camera.frustum.update(proj * view);
|
_camera.frustum.update(proj * view);
|
||||||
|
|
||||||
rendered = culled = geoms = frames = 0;
|
rendered = culled = geoms = frames = 0;
|
||||||
|
|
||||||
|
renderer->useProgram(worldProg);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glUniform1i(uniTexture, 0);
|
|
||||||
|
|
||||||
for( GameObject* object : engine->objects ) {
|
for( GameObject* object : engine->objects ) {
|
||||||
switch(object->type()) {
|
switch(object->type()) {
|
||||||
@ -398,36 +303,36 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
|
|||||||
it != transparentDrawQueue.end();
|
it != transparentDrawQueue.end();
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
glBindVertexArray(it->model->geometries[it->g]->dbuff.getVAOName());
|
renderer->draw(it->matrix, &it->model->geometries[it->g]->dbuff, it->dp);
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->model->geometries[it->g]->EBO);
|
|
||||||
|
|
||||||
renderSubgeometry(it->model, it->g, it->sg, it->matrix, it->opacity, it->object, false);
|
|
||||||
}
|
}
|
||||||
transparentDrawQueue.clear();
|
transparentDrawQueue.clear();
|
||||||
|
|
||||||
// Draw the water.
|
// Draw the water.
|
||||||
glUseProgram( waterProgram );
|
renderer->useProgram( waterProg );
|
||||||
|
|
||||||
// TODO: Add some kind of draw distance
|
|
||||||
|
|
||||||
float blockLQSize = WATER_WORLD_SIZE/WATER_LQ_DATA_SIZE;
|
float blockLQSize = WATER_WORLD_SIZE/WATER_LQ_DATA_SIZE;
|
||||||
float blockHQSize = WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE;
|
float blockHQSize = WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE;
|
||||||
|
|
||||||
glm::vec2 waterOffset { -WATER_WORLD_SIZE/2.f, -WATER_WORLD_SIZE/2.f };
|
glm::vec2 waterOffset { -WATER_WORLD_SIZE/2.f, -WATER_WORLD_SIZE/2.f };
|
||||||
glUniform1i(waterTexture, 0);
|
|
||||||
glUniform2f(waterWave, WATER_SCALE, WATER_HEIGHT);
|
|
||||||
auto waterTex = engine->gameData.textures[{"water_old",""}];
|
auto waterTex = engine->gameData.textures[{"water_old",""}];
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, waterTex.texName);
|
glBindTexture(GL_TEXTURE_2D, waterTex.texName);
|
||||||
|
|
||||||
auto camposFlat = glm::vec2(camera.position);
|
auto camposFlat = glm::vec2(camera.position);
|
||||||
|
|
||||||
glBindVertexArray( waterHQDraw.getVAOName() );
|
Renderer::DrawParameters wdp;
|
||||||
|
wdp.start = 0;
|
||||||
|
wdp.count = waterHQVerts.size();
|
||||||
|
wdp.texture = waterTex.texName;
|
||||||
|
|
||||||
|
renderer->useProgram(waterProg);
|
||||||
|
renderer->setSceneParameters(sceneParams);
|
||||||
|
|
||||||
// Draw High detail water
|
// Draw High detail water
|
||||||
glUniform1f(waterSize, blockHQSize);
|
renderer->setUniform(waterProg, "size", blockHQSize);
|
||||||
glUniform1f(waterTime, engine->gameTime);
|
renderer->setUniform(waterProg, "time", engine->gameTime);
|
||||||
|
renderer->setUniform(waterProg, "waveParams", glm::vec2(WATER_SCALE, WATER_HEIGHT));
|
||||||
|
|
||||||
for( int x = 0; x < WATER_HQ_DATA_SIZE; x++ ) {
|
for( int x = 0; x < WATER_HQ_DATA_SIZE; x++ ) {
|
||||||
for( int y = 0; y < WATER_HQ_DATA_SIZE; y++ ) {
|
for( int y = 0; y < WATER_HQ_DATA_SIZE; y++ ) {
|
||||||
auto waterWS = waterOffset + glm::vec2(blockHQSize) * glm::vec2(x, y);
|
auto waterWS = waterOffset + glm::vec2(blockHQSize) * glm::vec2(x, y);
|
||||||
@ -441,18 +346,18 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
|
|||||||
if( hI >= NO_WATER_INDEX ) continue;
|
if( hI >= NO_WATER_INDEX ) continue;
|
||||||
float h = engine->gameData.waterHeights[hI];
|
float h = engine->gameData.waterHeights[hI];
|
||||||
|
|
||||||
glUniform1f(waterHeight, h);
|
glm::mat4 m;
|
||||||
auto MVP = proj * view;
|
m = glm::translate(m, glm::vec3(waterWS, h));
|
||||||
glUniform2fv(waterPosition, 1, glm::value_ptr(waterWS));
|
|
||||||
glUniformMatrix4fv(waterMVP, 1, GL_FALSE, glm::value_ptr(MVP));
|
renderer->drawArrays(m, &waterHQDraw, wdp);
|
||||||
glDrawArrays(waterHQDraw.getFaceType(), 0, waterHQVerts.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindVertexArray( waterLQDraw.getVAOName() );
|
|
||||||
glUniform2f(waterWave, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
glUniform1f(waterSize, blockLQSize);
|
wdp.count = waterLQVerts.size();
|
||||||
|
renderer->setUniform(waterProg, "size", blockLQSize);
|
||||||
|
renderer->setUniform(waterProg, "waveParams", glm::vec2(0.f));
|
||||||
|
|
||||||
for( int x = 0; x < WATER_LQ_DATA_SIZE; x++ ) {
|
for( int x = 0; x < WATER_LQ_DATA_SIZE; x++ ) {
|
||||||
for( int y = 0; y < WATER_LQ_DATA_SIZE; y++ ) {
|
for( int y = 0; y < WATER_LQ_DATA_SIZE; y++ ) {
|
||||||
auto waterWS = waterOffset + glm::vec2(blockLQSize) * glm::vec2(x, y);
|
auto waterWS = waterOffset + glm::vec2(blockLQSize) * glm::vec2(x, y);
|
||||||
@ -467,28 +372,24 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
|
|||||||
if( hI >= NO_WATER_INDEX ) continue;
|
if( hI >= NO_WATER_INDEX ) continue;
|
||||||
float h = engine->gameData.waterHeights[hI];
|
float h = engine->gameData.waterHeights[hI];
|
||||||
|
|
||||||
glUniform1f(waterHeight, h);
|
glm::mat4 m;
|
||||||
auto MVP = proj * view;
|
m = glm::translate(m, glm::vec3(waterWS, h));
|
||||||
glUniform2fv(waterPosition, 1, glm::value_ptr(waterWS));
|
|
||||||
glUniformMatrix4fv(waterMVP, 1, GL_FALSE, glm::value_ptr(MVP));
|
renderer->drawArrays(m, &waterLQDraw, wdp);
|
||||||
glDrawArrays(waterLQDraw.getFaceType(), 0, 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindVertexArray( vao );
|
glBindVertexArray( vao );
|
||||||
|
|
||||||
glUseProgram(skyProgram);
|
Renderer::DrawParameters dp;
|
||||||
|
dp.start = 0;
|
||||||
|
dp.count = skydomeSegments * skydomeRows * 6;
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, skydomeVBO);
|
renderer->useProgram(skyProg);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skydomeIBO);
|
renderer->setUniform(skyProg, "TopColor", glm::vec4(skyTop, 1.f));
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
renderer->setUniform(skyProg, "BottomColor", glm::vec4(skyBottom, 1.f));
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glUniformMatrix4fv(skyUniView, 1, GL_FALSE, glm::value_ptr(view));
|
|
||||||
glUniformMatrix4fv(skyUniProj, 1, GL_FALSE, glm::value_ptr(proj));
|
|
||||||
glUniform4f(skyUniTop, skyTop.r, skyTop.g, skyTop.b, 1.f);
|
|
||||||
glUniform4f(skyUniBottom, skyBottom.r, skyBottom.g, skyBottom.b, 1.f);
|
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, skydomeSegments * skydomeRows * 6, GL_UNSIGNED_SHORT, NULL);
|
renderer->draw(glm::mat4(), &skyDbuff, dp);
|
||||||
|
|
||||||
renderParticles();
|
renderParticles();
|
||||||
|
|
||||||
@ -871,18 +772,70 @@ void GameRenderer::renderItem(InventoryItem *item, const glm::mat4 &modelMatrix)
|
|||||||
void GameRenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelMatrix, float opacity, GameObject* object)
|
void GameRenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelMatrix, float opacity, GameObject* object)
|
||||||
{
|
{
|
||||||
geoms++;
|
geoms++;
|
||||||
glBindVertexArray(model->geometries[g]->dbuff.getVAOName());
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g]->EBO);
|
|
||||||
|
|
||||||
for(size_t sg = 0; sg < model->geometries[g]->subgeom.size(); ++sg)
|
for(size_t sg = 0; sg < model->geometries[g]->subgeom.size(); ++sg)
|
||||||
{
|
{
|
||||||
if(opacity < 1.f || ! renderSubgeometry(model, g, sg, modelMatrix, opacity, object)) {
|
Model::SubGeometry& subgeom = model->geometries[g]->subgeom[sg];
|
||||||
// If rendering was rejected, queue for later.
|
|
||||||
|
bool abortTransparent = false;
|
||||||
|
|
||||||
|
Renderer::DrawParameters dp;
|
||||||
|
|
||||||
|
dp.colour = {255, 255, 255, 255};
|
||||||
|
dp.count = subgeom.numIndices;
|
||||||
|
dp.start = subgeom.start;
|
||||||
|
dp.texture = 0;
|
||||||
|
|
||||||
|
if (model->geometries[g]->materials.size() > subgeom.material) {
|
||||||
|
Model::Material& mat = model->geometries[g]->materials[subgeom.material];
|
||||||
|
|
||||||
|
if(mat.textures.size() > 0 ) {
|
||||||
|
auto& tC = mat.textures[0].name;
|
||||||
|
auto& tA = mat.textures[0].alphaName;
|
||||||
|
auto t = engine->gameData.textures.find({tC, tA});
|
||||||
|
if(t != engine->gameData.textures.end()) {
|
||||||
|
TextureInfo& tex = t->second;
|
||||||
|
if(tex.transparent) {
|
||||||
|
abortTransparent = true;
|
||||||
|
}
|
||||||
|
dp.texture = tex.texName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (model->geometries[g]->flags & RW::BSGeometry::ModuleMaterialColor) == RW::BSGeometry::ModuleMaterialColor) {
|
||||||
|
dp.colour = mat.colour;
|
||||||
|
|
||||||
|
if( object && object->type() == GameObject::Vehicle ) {
|
||||||
|
auto vehicle = static_cast<VehicleObject*>(object);
|
||||||
|
if( dp.colour.r == 60 && dp.colour.g == 255 && dp.colour.b == 0 ) {
|
||||||
|
dp.colour = glm::u8vec4(vehicle->colourPrimary, 255);
|
||||||
|
}
|
||||||
|
else if( dp.colour.r == 255 && dp.colour.g == 0 && dp.colour.b == 175 ) {
|
||||||
|
dp.colour = glm::u8vec4(vehicle->colourSecondary, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dp.colour.a *= opacity;
|
||||||
|
|
||||||
|
if( dp.colour.a < 255 ) {
|
||||||
|
abortTransparent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dp.diffuse = mat.diffuseIntensity;
|
||||||
|
dp.ambient = mat.ambientIntensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered++;
|
||||||
|
|
||||||
|
if( abortTransparent ) {
|
||||||
transparentDrawQueue.push_back(
|
transparentDrawQueue.push_back(
|
||||||
{model, g, sg, modelMatrix, opacity, object}
|
{model, g, sg, modelMatrix, dp, object}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
renderer->draw(modelMatrix, &model->geometries[g]->dbuff, dp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,12 +896,12 @@ void GameRenderer::renderParticles()
|
|||||||
m[3][2] =-glm::dot(u, p);
|
m[3][2] =-glm::dot(u, p);
|
||||||
|
|
||||||
m = glm::scale(glm::inverse(m), glm::vec3(part.size, 1.f));
|
m = glm::scale(glm::inverse(m), glm::vec3(part.size, 1.f));
|
||||||
uploadUBO<ObjectUniformData>(
|
/*uploadUBO<ObjectUniformData>(
|
||||||
uboObject, {
|
uboObject, {
|
||||||
m,
|
m,
|
||||||
part.colour,
|
part.colour,
|
||||||
1.f, 1.f, 1.f
|
1.f, 1.f, 1.f
|
||||||
});
|
});*/
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
@ -963,6 +916,7 @@ bool GameRenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
|
|||||||
{
|
{
|
||||||
frames++;
|
frames++;
|
||||||
auto localmatrix = matrix;
|
auto localmatrix = matrix;
|
||||||
|
bool vis = true;
|
||||||
|
|
||||||
if(object && object->animator) {
|
if(object && object->animator) {
|
||||||
bool animFixed = false;
|
bool animFixed = false;
|
||||||
@ -970,26 +924,26 @@ bool GameRenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
|
|||||||
animFixed = static_cast<CharacterObject*>(object)->isAnimationFixed();
|
animFixed = static_cast<CharacterObject*>(object)->isAnimationFixed();
|
||||||
}
|
}
|
||||||
localmatrix *= object->animator->getFrameMatrix(f, _renderAlpha, animFixed);
|
localmatrix *= object->animator->getFrameMatrix(f, _renderAlpha, animFixed);
|
||||||
|
|
||||||
|
vis = object->animator->getFrameVisibility(f);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
localmatrix *= f->getTransform();
|
localmatrix *= f->getTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vis = (object == nullptr || object->animator == nullptr) ||
|
if( vis ) {
|
||||||
object->animator->getFrameVisibility(f);
|
for(size_t g : f->getGeometries()) {
|
||||||
|
RW::BSGeometryBounds& bounds = m->geometries[g]->geometryBounds;
|
||||||
|
/// @todo fix culling animating objects?
|
||||||
|
|
||||||
for(size_t g : f->getGeometries()) {
|
glm::vec3 boundpos = bounds.center + glm::vec3(matrix[3]);
|
||||||
if(!vis ) continue;
|
if(! _camera.frustum.intersects(boundpos, bounds.radius)) {
|
||||||
|
culled++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
RW::BSGeometryBounds& bounds = m->geometries[g]->geometryBounds;
|
renderGeometry(m, g, localmatrix, opacity, object);
|
||||||
/// @todo fix culling animating objects?
|
|
||||||
|
|
||||||
glm::vec3 boundpos = bounds.center + glm::vec3(matrix[3]);
|
|
||||||
if( (!object || !object->animator) && ! _camera.frustum.intersects(boundpos, bounds.radius)) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderGeometry(m, g, localmatrix, opacity, object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ModelFrame* c : f->getChildren()) {
|
for(ModelFrame* c : f->getChildren()) {
|
||||||
@ -998,78 +952,6 @@ bool GameRenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameRenderer::renderSubgeometry(Model* model, size_t g, size_t sg, const glm::mat4& matrix, float opacity, GameObject* object, bool queueTransparent)
|
|
||||||
{
|
|
||||||
auto& subgeom = model->geometries[g]->subgeom[sg];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* model matrix,
|
|
||||||
* material diffuse
|
|
||||||
* material ambient
|
|
||||||
* materialcolour
|
|
||||||
*/
|
|
||||||
ObjectUniformData oudata {
|
|
||||||
matrix,
|
|
||||||
glm::vec4(1.f),
|
|
||||||
1.f, 1.f, opacity
|
|
||||||
};
|
|
||||||
|
|
||||||
if (model->geometries[g]->materials.size() > subgeom.material) {
|
|
||||||
Model::Material& mat = model->geometries[g]->materials[subgeom.material];
|
|
||||||
|
|
||||||
if(mat.textures.size() > 0 ) {
|
|
||||||
auto& tC = mat.textures[0].name;
|
|
||||||
auto& tA = mat.textures[0].alphaName;
|
|
||||||
auto t = engine->gameData.textures.find({tC, tA});
|
|
||||||
if(t != engine->gameData.textures.end()) {
|
|
||||||
TextureInfo& tex = t->second;
|
|
||||||
if(tex.transparent && queueTransparent) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex.texName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Texture pair is missing?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( (model->geometries[g]->flags & RW::BSGeometry::ModuleMaterialColor) == RW::BSGeometry::ModuleMaterialColor) {
|
|
||||||
auto col = mat.colour;
|
|
||||||
|
|
||||||
if(col.a < 255 && queueTransparent) return false;
|
|
||||||
if( object && object->type() == GameObject::Vehicle ) {
|
|
||||||
auto vehicle = static_cast<VehicleObject*>(object);
|
|
||||||
if( col.r == 60 && col.g == 255 && col.b == 0 ) {
|
|
||||||
oudata.colour = glm::vec4(vehicle->colourPrimary, 1.f);
|
|
||||||
}
|
|
||||||
else if( col.r == 255 && col.g == 0 && col.b == 175 ) {
|
|
||||||
oudata.colour = glm::vec4(vehicle->colourSecondary, 1.f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
oudata.colour = {col.r/255.f, col.g/255.f, col.b/255.f, col.a/255.f};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
oudata.colour = {col.r/255.f, col.g/255.f, col.b/255.f, col.a/255.f};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
oudata.diffuse = mat.diffuseIntensity;
|
|
||||||
oudata.ambient = mat.ambientIntensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadUBO(uboObject, oudata);
|
|
||||||
|
|
||||||
rendered++;
|
|
||||||
|
|
||||||
glDrawElements(model->geometries[g]->dbuff.getFaceType(),
|
|
||||||
subgeom.numIndices, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * subgeom.start));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GameObject* object, Animator *animator)
|
void GameRenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GameObject* object, Animator *animator)
|
||||||
{
|
{
|
||||||
renderFrame(model, model->frames[model->rootFrameIdx], modelMatrix, object, 1.f);
|
renderFrame(model, model->frames[model->rootFrameIdx], modelMatrix, object, 1.f);
|
||||||
@ -1077,7 +959,7 @@ void GameRenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GameO
|
|||||||
|
|
||||||
void GameRenderer::renderPaths()
|
void GameRenderer::renderPaths()
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
/*glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, debugTex);
|
glBindTexture(GL_TEXTURE_2D, debugTex);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
@ -1152,7 +1034,7 @@ void GameRenderer::renderPaths()
|
|||||||
|
|
||||||
pedlines.clear();
|
pedlines.clear();
|
||||||
carlines.clear();
|
carlines.clear();
|
||||||
glBindVertexArray( 0 );
|
glBindVertexArray( 0 );*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameRenderer::renderLetterbox()
|
void GameRenderer::renderLetterbox()
|
||||||
|
@ -9,18 +9,38 @@ const char* WaterHQ::VertexShader = R"(
|
|||||||
|
|
||||||
layout(location = 0) in vec2 position;
|
layout(location = 0) in vec2 position;
|
||||||
out vec2 TexCoords;
|
out vec2 TexCoords;
|
||||||
uniform float height;
|
|
||||||
|
layout(std140) uniform SceneData {
|
||||||
|
mat4 projection;
|
||||||
|
mat4 view;
|
||||||
|
vec4 ambient;
|
||||||
|
vec4 dynamic;
|
||||||
|
vec4 fogColor;
|
||||||
|
vec4 campos;
|
||||||
|
float fogStart;
|
||||||
|
float fogEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform ObjectData {
|
||||||
|
mat4 model;
|
||||||
|
vec4 colour;
|
||||||
|
float diffusefac;
|
||||||
|
float ambientfac;
|
||||||
|
float visibility;
|
||||||
|
};
|
||||||
|
|
||||||
uniform float size;
|
uniform float size;
|
||||||
uniform mat4 MVP;
|
|
||||||
uniform float time;
|
uniform float time;
|
||||||
uniform vec2 worldP;
|
|
||||||
uniform vec2 waveParams;
|
uniform vec2 waveParams;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec2 p = worldP + position * size;
|
mat4 MVP = projection * view;
|
||||||
float waveHeight = (1.0+sin(time + (p.x + p.y) * waveParams.x)) * waveParams.y;
|
vec4 vp = model * vec4(position * size, 0.0, 1.0);
|
||||||
|
vp.z = (1.0+sin(time + (vp.x + vp.y) * waveParams.x)) * waveParams.y;
|
||||||
TexCoords = position * 2.0;
|
TexCoords = position * 2.0;
|
||||||
gl_Position = MVP * vec4(p, height + waveHeight, 1.0);
|
gl_Position = MVP * vp;
|
||||||
})";
|
})";
|
||||||
|
|
||||||
const char* WaterHQ::FragmentShader = R"(
|
const char* WaterHQ::FragmentShader = R"(
|
||||||
@ -36,14 +56,26 @@ void main() {
|
|||||||
|
|
||||||
const char* Sky::VertexShader = R"(
|
const char* Sky::VertexShader = R"(
|
||||||
#version 130
|
#version 130
|
||||||
in vec3 position;
|
#extension GL_ARB_explicit_attrib_location : enable
|
||||||
uniform mat4 view;
|
#extension GL_ARB_uniform_buffer_object : enable
|
||||||
uniform mat4 proj;
|
|
||||||
|
layout(std140) uniform SceneData {
|
||||||
|
mat4 projection;
|
||||||
|
mat4 view;
|
||||||
|
vec4 ambient;
|
||||||
|
vec4 dynamic;
|
||||||
|
vec4 fogColor;
|
||||||
|
vec4 campos;
|
||||||
|
float fogStart;
|
||||||
|
float fogEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 position;
|
||||||
out vec3 Position;
|
out vec3 Position;
|
||||||
uniform float Far;
|
|
||||||
void main() {
|
void main() {
|
||||||
Position = position;
|
Position = position;
|
||||||
vec4 viewsp = proj * mat4(mat3(view)) * vec4(position, 1.0);
|
vec4 viewsp = projection * mat4(mat3(view)) * vec4(position, 1.0);
|
||||||
viewsp.z = viewsp.w - 0.000001;
|
viewsp.z = viewsp.w - 0.000001;
|
||||||
gl_Position = viewsp;
|
gl_Position = viewsp;
|
||||||
})";
|
})";
|
||||||
@ -67,7 +99,6 @@ const char* WorldObject::VertexShader = R"(
|
|||||||
#version 130
|
#version 130
|
||||||
#extension GL_ARB_explicit_attrib_location : enable
|
#extension GL_ARB_explicit_attrib_location : enable
|
||||||
#extension GL_ARB_uniform_buffer_object : enable
|
#extension GL_ARB_uniform_buffer_object : enable
|
||||||
#extension GL_ARB_gpu_shader5 : enable
|
|
||||||
layout(location = 0) in vec3 position;
|
layout(location = 0) in vec3 position;
|
||||||
layout(location = 1) in vec3 normal;
|
layout(location = 1) in vec3 normal;
|
||||||
layout(location = 2) in vec4 _colour;
|
layout(location = 2) in vec4 _colour;
|
||||||
|
231
rwengine/src/render/OpenGLRenderer.cpp
Normal file
231
rwengine/src/render/OpenGLRenderer.cpp
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
#include <render/OpenGLRenderer.hpp>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
GLuint compileShader(GLenum type, const char *source)
|
||||||
|
{
|
||||||
|
GLuint shader = glCreateShader(type);
|
||||||
|
glShaderSource(shader, 1, &source, NULL);
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||||
|
|
||||||
|
if( status != GL_TRUE ) {
|
||||||
|
std::cerr << "[OGL] Shader Compilation Failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint len;
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||||
|
if( len > 1 ) {
|
||||||
|
GLchar *buffer = new GLchar[len];
|
||||||
|
glGetShaderInfoLog(shader, len, NULL, buffer);
|
||||||
|
|
||||||
|
GLint sourceLen;
|
||||||
|
glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLen);
|
||||||
|
GLchar *sourceBuff = new GLchar[sourceLen];
|
||||||
|
glGetShaderSource(shader, sourceLen, nullptr, sourceBuff);
|
||||||
|
|
||||||
|
std::cerr << "[OGL] Shader InfoLog(" << shader << "):\n" << buffer << "\nSource:\n" << sourceBuff << std::endl;
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
delete[] sourceBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != GL_TRUE) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint compileProgram(const char* vertex, const char* fragment)
|
||||||
|
{
|
||||||
|
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertex);
|
||||||
|
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragment);
|
||||||
|
GLuint prog = glCreateProgram();
|
||||||
|
glAttachShader(prog, vertexShader);
|
||||||
|
glAttachShader(prog, fragmentShader);
|
||||||
|
glLinkProgram(prog);
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
glGetProgramiv(prog, GL_LINK_STATUS, &status);
|
||||||
|
|
||||||
|
if( status != GL_TRUE ) {
|
||||||
|
std::cerr << "[OGL] Program Link Failed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint len;
|
||||||
|
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
|
||||||
|
if( len > 1 ) {
|
||||||
|
GLchar *buffer = new GLchar[len];
|
||||||
|
glGetProgramInfoLog(prog, len, NULL, buffer);
|
||||||
|
|
||||||
|
std::cerr << "[OGL] Program InfoLog(" << prog << "):\n" << buffer << std::endl;
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != GL_TRUE) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(fragmentShader);
|
||||||
|
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void OpenGLRenderer::useDrawBuffer(DrawBuffer* dbuff)
|
||||||
|
{
|
||||||
|
if( dbuff != currentDbuff )
|
||||||
|
{
|
||||||
|
glBindVertexArray(dbuff->getVAOName());
|
||||||
|
currentDbuff = dbuff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::useTexture(GLuint tex)
|
||||||
|
{
|
||||||
|
if( tex != currentTexture )
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
currentTexture = tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::useProgram(Renderer::ShaderProgram* p)
|
||||||
|
{
|
||||||
|
if( p != currentProgram )
|
||||||
|
{
|
||||||
|
currentProgram = static_cast<OpenGLShaderProgram*>(p);
|
||||||
|
glUseProgram( currentProgram->getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLRenderer::OpenGLRenderer()
|
||||||
|
: currentDbuff(nullptr), currentTexture(0), currentProgram(nullptr)
|
||||||
|
{
|
||||||
|
glGenBuffers(1, &UBOScene);
|
||||||
|
glGenBuffers(1, &UBOObject);
|
||||||
|
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, 1, UBOScene);
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, 2, UBOObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OpenGLRenderer::getIDString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "OpenGL Renderer";
|
||||||
|
ss << " Version: " << glGetString(GL_VERSION);
|
||||||
|
ss << " (GLSL " << glGetString(GL_SHADING_LANGUAGE_VERSION) << ")";
|
||||||
|
ss << " Vendor: " << glGetString(GL_VENDOR);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::ShaderProgram* OpenGLRenderer::createShader(const std::string& vert, const std::string& frag)
|
||||||
|
{
|
||||||
|
return new OpenGLShaderProgram(
|
||||||
|
compileProgram(vert.c_str(), frag.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::setProgramBlockBinding(Renderer::ShaderProgram* p, const std::string& name, GLint point)
|
||||||
|
{
|
||||||
|
OpenGLShaderProgram* glsh = static_cast<OpenGLShaderProgram*>(p);
|
||||||
|
|
||||||
|
auto ubi = glGetUniformBlockIndex(glsh->getName(), name.c_str());
|
||||||
|
glUniformBlockBinding(glsh->getName(), ubi, point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::setUniformTexture(Renderer::ShaderProgram* p, const std::string& name, GLint tex)
|
||||||
|
{
|
||||||
|
useProgram(p);
|
||||||
|
|
||||||
|
glUniform1i(currentProgram->getUniformLocation(name), tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, const glm::vec4& m)
|
||||||
|
{
|
||||||
|
useProgram(p);
|
||||||
|
|
||||||
|
glUniform4fv(currentProgram->getUniformLocation(name.c_str()), 1, glm::value_ptr(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, const glm::vec3& m)
|
||||||
|
{
|
||||||
|
useProgram(p);
|
||||||
|
|
||||||
|
glUniform3fv(currentProgram->getUniformLocation(name.c_str()), 1, glm::value_ptr(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, const glm::vec2& m)
|
||||||
|
{
|
||||||
|
useProgram(p);
|
||||||
|
|
||||||
|
glUniform2fv(currentProgram->getUniformLocation(name.c_str()), 1, glm::value_ptr(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, float f)
|
||||||
|
{
|
||||||
|
glUniform1fv(currentProgram->getUniformLocation(name.c_str()), 1, &f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::clear(const glm::vec4& colour, bool clearColour, bool clearDepth)
|
||||||
|
{
|
||||||
|
auto flags = 0;
|
||||||
|
if( clearColour ) {
|
||||||
|
flags |= GL_COLOR_BUFFER_BIT;
|
||||||
|
glClearColor(colour.r, colour.g, colour.b, colour.a);
|
||||||
|
}
|
||||||
|
if( clearDepth ) {
|
||||||
|
flags |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
glClear(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::setSceneParameters(const Renderer::SceneUniformData& data)
|
||||||
|
{
|
||||||
|
uploadUBO(UBOScene, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::draw(const glm::mat4& model, DrawBuffer* draw, const Renderer::DrawParameters& p)
|
||||||
|
{
|
||||||
|
useDrawBuffer(draw);
|
||||||
|
useTexture(p.texture);
|
||||||
|
|
||||||
|
ObjectUniformData oudata {
|
||||||
|
model,
|
||||||
|
glm::vec4(p.colour.r/255.f, p.colour.g/255.f, p.colour.b/255.f, 1.f),
|
||||||
|
1.f,
|
||||||
|
1.f,
|
||||||
|
p.colour.a/255.f
|
||||||
|
};
|
||||||
|
uploadUBO(UBOObject, oudata);
|
||||||
|
|
||||||
|
glDrawElements(draw->getFaceType(), p.count, GL_UNSIGNED_INT,
|
||||||
|
(void*) (sizeof(RenderIndex) * p.start));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::drawArrays(const glm::mat4& model, DrawBuffer* draw, const Renderer::DrawParameters& p)
|
||||||
|
{
|
||||||
|
|
||||||
|
useDrawBuffer(draw);
|
||||||
|
useTexture(p.texture);
|
||||||
|
|
||||||
|
ObjectUniformData oudata {
|
||||||
|
model,
|
||||||
|
glm::vec4(p.colour.r/255.f, p.colour.g/255.f, p.colour.b/255.f, 1.f),
|
||||||
|
1.f,
|
||||||
|
1.f,
|
||||||
|
p.colour.a/255.f
|
||||||
|
};
|
||||||
|
uploadUBO(UBOObject, oudata);
|
||||||
|
|
||||||
|
glDrawArrays(draw->getFaceType(), p.start, p.count);
|
||||||
|
}
|
@ -185,7 +185,7 @@ void init(std::string gtapath)
|
|||||||
gta->gameTime = 0.f;
|
gta->gameTime = 0.f;
|
||||||
|
|
||||||
debugDrawer = new DebugDraw;
|
debugDrawer = new DebugDraw;
|
||||||
debugDrawer->setShaderProgram(gta->renderer.worldProgram);
|
//debugDrawer->setShaderProgram(gta->renderer.worldProgram);
|
||||||
debugDrawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
debugDrawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
||||||
gta->dynamicsWorld->setDebugDrawer(debugDrawer);
|
gta->dynamicsWorld->setDebugDrawer(debugDrawer);
|
||||||
|
|
||||||
@ -302,24 +302,24 @@ void render(float alpha)
|
|||||||
case 0: break;
|
case 0: break;
|
||||||
|
|
||||||
case 1: {
|
case 1: {
|
||||||
glUseProgram(gta->renderer.worldProgram);
|
//glUseProgram(gta->renderer.worldProgram);
|
||||||
gta->renderer.uploadUBO<ObjectUniformData>(
|
/*gta->renderer.uploadUBO<ObjectUniformData>(
|
||||||
gta->renderer.uboObject, {
|
gta->renderer.uboObject, {
|
||||||
glm::mat4(),
|
glm::mat4(),
|
||||||
glm::vec4(1.f),
|
glm::vec4(1.f),
|
||||||
1.f, 1.f
|
1.f, 1.f
|
||||||
});
|
});*/
|
||||||
gta->renderer.renderPaths();
|
gta->renderer.renderPaths();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
glUseProgram(gta->renderer.worldProgram);
|
//glUseProgram(gta->renderer.worldProgram);
|
||||||
gta->renderer.uploadUBO<ObjectUniformData>(
|
/*gta->renderer.uploadUBO<ObjectUniformData>(
|
||||||
gta->renderer.uboObject, {
|
gta->renderer.uboObject, {
|
||||||
glm::mat4(),
|
glm::mat4(),
|
||||||
glm::vec4(1.f),
|
glm::vec4(1.f),
|
||||||
1.f, 1.f
|
1.f, 1.f
|
||||||
});
|
});*/
|
||||||
gta->dynamicsWorld->debugDrawWorld();
|
gta->dynamicsWorld->debugDrawWorld();
|
||||||
debugDrawer->drawAllLines();
|
debugDrawer->drawAllLines();
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ void ViewerWidget::paintGL()
|
|||||||
|
|
||||||
glm::mat4 m;
|
glm::mat4 m;
|
||||||
|
|
||||||
glUseProgram(r.worldProgram);
|
//glUseProgram(r.worldProgram);
|
||||||
|
|
||||||
ViewCamera vc;
|
ViewCamera vc;
|
||||||
|
|
||||||
@ -97,8 +97,8 @@ void ViewerWidget::paintGL()
|
|||||||
glm::vec3 eye(sin(viewAngles.x) * cos(viewAngles.y), cos(viewAngles.x) * cos(viewAngles.y), sin(viewAngles.y));
|
glm::vec3 eye(sin(viewAngles.x) * cos(viewAngles.y), cos(viewAngles.x) * cos(viewAngles.y), sin(viewAngles.y));
|
||||||
glm::mat4 view = glm::lookAt(eye * viewDistance, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f));
|
glm::mat4 view = glm::lookAt(eye * viewDistance, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f));
|
||||||
|
|
||||||
r.uploadUBO<SceneUniformData>(r.uboScene,
|
//r.uploadUBO<SceneUniformData>(r.uboScene,
|
||||||
{ proj, view, glm::vec4(1.f), glm::vec4(1.f), glm::vec4(1.f), glm::vec4(0.f), 90.f, vc.frustum.far });
|
//{ proj, view, glm::vec4(1.f), glm::vec4(1.f), glm::vec4(1.f), glm::vec4(0.f), 90.f, vc.frustum.far });
|
||||||
|
|
||||||
if( dummyObject->model->model ) {
|
if( dummyObject->model->model ) {
|
||||||
gworld->renderer.renderModel(dummyObject->model->model, m, dummyObject);
|
gworld->renderer.renderModel(dummyObject->model->model, m, dummyObject);
|
||||||
|
Loading…
Reference in New Issue
Block a user