mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-26 04:12:41 +01:00
Refactored rendering into GTARenderer
This commit is contained in:
parent
cd154d5775
commit
b7da2815ad
@ -13,6 +13,9 @@ add_library(renderware
|
||||
GTAData.cpp
|
||||
|
||||
GTAEngine.cpp
|
||||
|
||||
# Rendering
|
||||
GTARenderer.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(renderware sfml-window)
|
||||
|
131
framework2/GTARenderer.cpp
Normal file
131
framework2/GTARenderer.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include "renderwure/render/GTARenderer.hpp"
|
||||
#include <renderwure/engine/GTAEngine.hpp>
|
||||
#define GLEW_STATIC
|
||||
#include <GL/glew.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
const char *vertexShaderSource = "#version 130\n"
|
||||
"in vec3 position;"
|
||||
"in vec2 texCoords;"
|
||||
"out vec2 TexCoords;"
|
||||
"uniform mat4 model;"
|
||||
"uniform mat4 view;"
|
||||
"uniform mat4 proj;"
|
||||
"void main()"
|
||||
"{"
|
||||
" TexCoords = texCoords;"
|
||||
" gl_Position = proj * view * model * vec4(position, 1.0);"
|
||||
"}";
|
||||
const char *fragmentShaderSource = "#version 130\n"
|
||||
"in vec2 TexCoords;"
|
||||
"uniform sampler2D texture;"
|
||||
"void main()"
|
||||
"{"
|
||||
" vec4 c = texture2D(texture, TexCoords);"
|
||||
" if(c.a < 0.9) discard;"
|
||||
" gl_FragColor = c;"
|
||||
"}";
|
||||
|
||||
GLuint uniModel, uniProj, uniView;
|
||||
GLuint posAttrib, texAttrib;
|
||||
GLuint worldProgram;
|
||||
|
||||
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) {
|
||||
GLint len;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
GLchar *buffer = new GLchar[len];
|
||||
glGetShaderInfoLog(shader, len, NULL, buffer);
|
||||
|
||||
std::cerr << "ERROR compiling shader: " << buffer << std::endl;
|
||||
delete[] buffer;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
GTARenderer::GTARenderer()
|
||||
: camera()
|
||||
{
|
||||
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
|
||||
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
|
||||
GLuint worldProgram = glCreateProgram();
|
||||
glAttachShader(worldProgram, vertexShader);
|
||||
glAttachShader(worldProgram, fragmentShader);
|
||||
glLinkProgram(worldProgram);
|
||||
glUseProgram(worldProgram);
|
||||
|
||||
posAttrib = glGetAttribLocation(worldProgram, "position");
|
||||
texAttrib = glGetAttribLocation(worldProgram, "texCoords");
|
||||
|
||||
uniModel = glGetUniformLocation(worldProgram, "model");
|
||||
uniView = glGetUniformLocation(worldProgram, "view");
|
||||
uniProj = glGetUniformLocation(worldProgram, "proj");
|
||||
}
|
||||
|
||||
void GTARenderer::renderWorld(GTAEngine* engine)
|
||||
{
|
||||
glm::mat4 proj = camera.frustum.projection();
|
||||
glm::mat4 view = camera.view;
|
||||
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
|
||||
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
|
||||
|
||||
camera.frustum.update();
|
||||
|
||||
auto& textureLoader = engine->gameData.textureLoader;
|
||||
|
||||
for (size_t i = 0; i < engine->instances.size(); ++i) {
|
||||
auto &obj = engine->instances[i];
|
||||
std::string modelname = obj.model;
|
||||
if (modelname.substr(0, 3) == "LOD")
|
||||
continue;
|
||||
auto &model = engine->gameData.models[modelname];
|
||||
// std::cout << "Rendering " << modelname << std::endl;
|
||||
|
||||
if(!model)
|
||||
{
|
||||
std::cout << "model " << modelname << " not there (" << engine->gameData.models.size() << " models loaded)" << std::endl;
|
||||
}
|
||||
|
||||
for (size_t g = 0; g < model->geometries.size(); g++) {
|
||||
|
||||
// This is a hack I have no idea why negating the quaternion fixes the issue but it does.
|
||||
glm::quat rot(-obj.rotW, obj.rotX, obj.rotY, obj.rotZ);
|
||||
glm::mat4 matrixModel;
|
||||
matrixModel = glm::translate(matrixModel, glm::vec3(obj.posX, obj.posY, obj.posZ));
|
||||
matrixModel = glm::scale(matrixModel, glm::vec3(obj.scaleX, obj.scaleY, obj.scaleZ));
|
||||
matrixModel = matrixModel * glm::mat4_cast(rot);
|
||||
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(matrixModel));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->geometries[g].VBO);
|
||||
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)(model->geometries[g].vertices.size() * sizeof(float) * 3));
|
||||
glEnableVertexAttribArray(posAttrib);
|
||||
glEnableVertexAttribArray(texAttrib);
|
||||
|
||||
for(size_t sg = 0; sg < model->geometries[g].subgeom.size(); ++sg)
|
||||
{
|
||||
if (model->geometries[g].materials.size() > model->geometries[g].subgeom[sg].material) {
|
||||
// std::cout << model->geometries[g].textures.size() << std::endl;
|
||||
// std::cout << "Looking for " << model->geometries[g].textures[0].name << std::endl;
|
||||
if(model->geometries[g].materials[model->geometries[g].subgeom[sg].material].textures.size() > 0) {
|
||||
textureLoader.bindTexture(model->geometries[g].materials[model->geometries[g].subgeom[sg].material].textures[0].name);
|
||||
}
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].subgeom[sg].EBO);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, model->geometries[g].subgeom[sg].indices.size(), GL_UNSIGNED_INT, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <renderwure/engine/GTAData.hpp>
|
||||
#include <renderwure/loaders/LoaderIPL.hpp>
|
||||
#include <renderwure/render/GTARenderer.hpp>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
@ -40,6 +41,11 @@ public:
|
||||
*/
|
||||
GTAData gameData;
|
||||
|
||||
/**
|
||||
* Renderer
|
||||
*/
|
||||
GTARenderer renderer;
|
||||
|
||||
/**
|
||||
* Until we have a real "object" class, just store a list of loaed instances.
|
||||
*/
|
||||
|
17
framework2/include/renderwure/render/GTARenderer.hpp
Normal file
17
framework2/include/renderwure/render/GTARenderer.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _GTARENDERER_HPP_
|
||||
#define _GTARENDERER_HPP_
|
||||
#include "ViewCamera.hpp"
|
||||
|
||||
class GTAEngine;
|
||||
class GTARenderer
|
||||
{
|
||||
public:
|
||||
|
||||
GTARenderer();
|
||||
|
||||
ViewCamera camera;
|
||||
|
||||
void renderWorld(GTAEngine* engine);
|
||||
};
|
||||
|
||||
#endif
|
21
framework2/include/renderwure/render/ViewCamera.hpp
Normal file
21
framework2/include/renderwure/render/ViewCamera.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _VIEWCAMERA_HPP_
|
||||
#define _VIEWCAMERA_HPP_
|
||||
#include "ViewFrustum.hpp"
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
class ViewCamera
|
||||
{
|
||||
public:
|
||||
|
||||
ViewFrustum frustum;
|
||||
|
||||
glm::mat4 view;
|
||||
|
||||
ViewCamera()
|
||||
: frustum({0.1f, 5000.f, 80.f, 1.f})
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
65
framework2/include/renderwure/render/ViewFrustum.hpp
Normal file
65
framework2/include/renderwure/render/ViewFrustum.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef _VIEWFRUSTUM_HPP_
|
||||
#define _VIEWFRUSTUM_HPP_
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
class ViewFrustum
|
||||
{
|
||||
public:
|
||||
|
||||
class ViewPlane
|
||||
{
|
||||
public:
|
||||
glm::vec3 normal;
|
||||
float distance;
|
||||
};
|
||||
|
||||
float near;
|
||||
float far;
|
||||
float fov;
|
||||
float aspectRatio;
|
||||
|
||||
ViewPlane planes[6];
|
||||
|
||||
ViewFrustum(float near, float far, float fov, float aspect)
|
||||
: near(near), far(far), fov(fov), aspectRatio(aspect)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
glm::mat4 projection()
|
||||
{
|
||||
return glm::perspective(fov, aspectRatio, near, far);
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
auto proj = projection();
|
||||
for(size_t i = 0; i < 6; ++i)
|
||||
{
|
||||
float sign = (i%2==0) ? 1.f : -1.f;
|
||||
int r = i / 2;
|
||||
planes[i].normal.x = proj[0][3] + proj[0][r] * sign;
|
||||
planes[i].normal.y = proj[1][3] + proj[1][r] * sign;
|
||||
planes[i].normal.z = proj[2][3] + proj[2][r] * sign;
|
||||
planes[i].distance = proj[3][3] + proj[3][r] * sign;
|
||||
|
||||
auto l = glm::length(planes[i].normal);
|
||||
planes[i].normal /= l;
|
||||
planes[i].distance /= l;
|
||||
}
|
||||
}
|
||||
|
||||
bool intersects(glm::vec3 center, float radius)
|
||||
{
|
||||
float d;
|
||||
for(size_t i = 0; i < 6; ++i)
|
||||
{
|
||||
d = glm::dot(planes[i].normal, center) + planes[i].distance;
|
||||
if( -d < radius ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
118
viewer/main.cpp
118
viewer/main.cpp
@ -19,61 +19,12 @@ constexpr double PiOver180 = 3.1415926535897932384626433832795028/180;
|
||||
|
||||
sf::Window window;
|
||||
|
||||
const char *vertexShaderSource = "#version 130\n"
|
||||
"in vec3 position;"
|
||||
"in vec2 texCoords;"
|
||||
"out vec2 TexCoords;"
|
||||
"uniform mat4 model;"
|
||||
"uniform mat4 view;"
|
||||
"uniform mat4 proj;"
|
||||
"void main()"
|
||||
"{"
|
||||
" TexCoords = texCoords;"
|
||||
" gl_Position = proj * view * model * vec4(position, 1.0);"
|
||||
"}";
|
||||
const char *fragmentShaderSource = "#version 130\n"
|
||||
"in vec2 TexCoords;"
|
||||
"uniform sampler2D texture;"
|
||||
"void main()"
|
||||
"{"
|
||||
" vec4 c = texture2D(texture, TexCoords);"
|
||||
" if(c.a < 0.9) discard;"
|
||||
" gl_FragColor = c;"
|
||||
"}";
|
||||
|
||||
GLuint uniModel, uniProj, uniView;
|
||||
GLuint posAttrib, texAttrib;
|
||||
|
||||
LoaderDFF dffLoader;
|
||||
GTAEngine* gta = nullptr;
|
||||
|
||||
glm::vec3 selectedModelCenter;
|
||||
|
||||
glm::vec3 plyPos;
|
||||
glm::vec2 plyLook;
|
||||
|
||||
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) {
|
||||
GLint len;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
GLchar *buffer = new GLchar[len];
|
||||
glGetShaderInfoLog(shader, len, NULL, buffer);
|
||||
|
||||
std::cerr << "ERROR compiling shader: " << buffer << std::endl;
|
||||
delete[] buffer;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void handleEvent(sf::Event &event)
|
||||
{
|
||||
switch (event.type) {
|
||||
@ -94,24 +45,6 @@ void init(std::string gtapath)
|
||||
glClearColor(0.2, 0.2, 0.2, 1.0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
|
||||
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
|
||||
GLuint shaderProgram = glCreateProgram();
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
glLinkProgram(shaderProgram);
|
||||
glUseProgram(shaderProgram);
|
||||
|
||||
posAttrib = glGetAttribLocation(shaderProgram, "position");
|
||||
texAttrib = glGetAttribLocation(shaderProgram, "texCoords");
|
||||
|
||||
uniModel = glGetUniformLocation(shaderProgram, "model");
|
||||
uniView = glGetUniformLocation(shaderProgram, "view");
|
||||
uniProj = glGetUniformLocation(shaderProgram, "proj");
|
||||
|
||||
glm::mat4 proj = glm::perspective(80.f, (float) WIDTH/HEIGHT, 0.1f, 5000.f);
|
||||
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
|
||||
|
||||
// GTA GET
|
||||
gta = new GTAEngine(gtapath);
|
||||
|
||||
@ -172,7 +105,8 @@ void update()
|
||||
}
|
||||
|
||||
view = glm::translate(view, -plyPos);
|
||||
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
|
||||
|
||||
gta->renderer.camera.view = view;
|
||||
|
||||
i++;
|
||||
}
|
||||
@ -181,53 +115,7 @@ void render()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
auto& textureLoader = gta->gameData.textureLoader;
|
||||
|
||||
for (size_t i = 0; i < gta->instances.size(); ++i) {
|
||||
auto &obj = gta->instances[i];
|
||||
std::string modelname = obj.model;
|
||||
if (modelname.substr(0, 3) == "LOD")
|
||||
continue;
|
||||
auto &model = gta->gameData.models[modelname];
|
||||
// std::cout << "Rendering " << modelname << std::endl;
|
||||
|
||||
if(!model)
|
||||
{
|
||||
std::cout << "model " << modelname << " not there (" << gta->gameData.models.size() << " models loaded)" << std::endl;
|
||||
}
|
||||
|
||||
for (size_t g = 0; g < model->geometries.size(); g++) {
|
||||
|
||||
// This is a hack I have no idea why negating the quaternion fixes the issue but it does.
|
||||
glm::quat rot(-obj.rotW, obj.rotX, obj.rotY, obj.rotZ);
|
||||
glm::mat4 matrixModel;
|
||||
matrixModel = glm::translate(matrixModel, glm::vec3(obj.posX, obj.posY, obj.posZ));
|
||||
matrixModel = glm::scale(matrixModel, glm::vec3(obj.scaleX, obj.scaleY, obj.scaleZ));
|
||||
matrixModel = matrixModel * glm::mat4_cast(rot);
|
||||
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(matrixModel));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->geometries[g].VBO);
|
||||
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)(model->geometries[g].vertices.size() * sizeof(float) * 3));
|
||||
glEnableVertexAttribArray(posAttrib);
|
||||
glEnableVertexAttribArray(texAttrib);
|
||||
|
||||
for(size_t sg = 0; sg < model->geometries[g].subgeom.size(); ++sg)
|
||||
{
|
||||
if (model->geometries[g].materials.size() > model->geometries[g].subgeom[sg].material) {
|
||||
// std::cout << model->geometries[g].textures.size() << std::endl;
|
||||
// std::cout << "Looking for " << model->geometries[g].textures[0].name << std::endl;
|
||||
if(model->geometries[g].materials[model->geometries[g].subgeom[sg].material].textures.size() > 0) {
|
||||
textureLoader.bindTexture(model->geometries[g].materials[model->geometries[g].subgeom[sg].material].textures[0].name);
|
||||
}
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].subgeom[sg].EBO);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, model->geometries[g].subgeom[sg].indices.size(), GL_UNSIGNED_INT, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
gta->renderer.renderWorld(gta);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
Loading…
Reference in New Issue
Block a user