restructured some files
This commit is contained in:
389
tools/gl/main.cpp
Executable file
389
tools/gl/main.cpp
Executable file
@ -0,0 +1,389 @@
|
||||
#include "rwtest.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int screenWidth = 640, screenHeight= 480;
|
||||
bool running = true;
|
||||
Camera *camera;
|
||||
|
||||
GLint program;
|
||||
GLuint vbo;
|
||||
|
||||
rw::Clump *clump;
|
||||
|
||||
char *filename;
|
||||
|
||||
void
|
||||
renderAtomic(rw::Atomic *atomic)
|
||||
{
|
||||
using namespace rw;
|
||||
static GLenum prim[] = {
|
||||
GL_TRIANGLES, GL_TRIANGLE_STRIP
|
||||
};
|
||||
Geometry *geo = atomic->geometry;
|
||||
atomic->getPipeline()->instance(atomic);
|
||||
gl::InstanceDataHeader *inst = (gl::InstanceDataHeader*)geo->instData;
|
||||
MeshHeader *meshHeader = geo->meshHeader;
|
||||
|
||||
Frame *frm = atomic->frame;
|
||||
frm->updateLTM();
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "worldMat"),
|
||||
1, GL_FALSE, frm->ltm);
|
||||
|
||||
glVertexAttrib4f(3, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glVertexAttrib3f(2, 0.0f, 0.0f, 0.0f);
|
||||
if(inst->vbo == 0 && inst->ibo == 0)
|
||||
gl::uploadGeo(geo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, inst->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, inst->ibo);
|
||||
gl::setAttribPointers(inst);
|
||||
|
||||
uint64 offset = 0;
|
||||
for(uint32 i = 0; i < meshHeader->numMeshes; i++){
|
||||
Mesh *mesh = &meshHeader->mesh[i];
|
||||
Material *mat = mesh->material;
|
||||
float color[4];
|
||||
uint8 *col = mat->color;
|
||||
color[0] = col[0] / 255.0f;
|
||||
color[1] = col[1] / 255.0f;
|
||||
color[2] = col[2] / 255.0f;
|
||||
color[3] = col[3] / 255.0f;
|
||||
glUniform4fv(glGetUniformLocation(program, "matColor"),
|
||||
1, color);
|
||||
rw::gl::Texture *tex =(rw::gl::Texture*)mat->texture;
|
||||
if(tex)
|
||||
tex->bind(0);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDrawElements(prim[meshHeader->flags], mesh->numIndices,
|
||||
GL_UNSIGNED_SHORT, (void*)offset);
|
||||
offset += mesh->numIndices*2;
|
||||
}
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glDisableVertexAttribArray(2);
|
||||
glDisableVertexAttribArray(3);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void
|
||||
render(void)
|
||||
{
|
||||
static Mat4 worldMat(1.0f);
|
||||
glUseProgram(program);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
camera->look();
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "projMat"),
|
||||
1, GL_FALSE, camera->projMat.cr);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "viewMat"),
|
||||
1, GL_FALSE, camera->viewMat.cr);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "worldMat"),
|
||||
1, GL_FALSE, worldMat.cr);
|
||||
|
||||
glVertexAttrib3f(2, -0.5f, 0.5f, 0.70710f);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 28, (GLvoid*)0);
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 28, (GLvoid*)12);
|
||||
glDrawArrays(GL_LINES, 0, 6);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(3);
|
||||
|
||||
for(rw::uint32 i = 0; i < clump->numAtomics; i++){
|
||||
char *name = PLUGINOFFSET(char, clump->atomicList[i]->frame,
|
||||
gta::nodeNameOffset);
|
||||
if(strstr(name, "_dam") || strstr(name, "_vlo"))
|
||||
continue;
|
||||
renderAtomic(clump->atomicList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init(void)
|
||||
{
|
||||
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GEQUAL, 0.5f);
|
||||
const char *shadersrc =
|
||||
"#ifdef VERTEX\n"
|
||||
"uniform mat4 projMat;"
|
||||
"uniform mat4 viewMat;"
|
||||
"uniform mat4 worldMat;"
|
||||
"uniform vec4 matColor;"
|
||||
"attribute vec3 in_vertex;"
|
||||
"attribute vec2 in_texCoord;"
|
||||
"attribute vec3 in_normal;"
|
||||
"attribute vec4 in_color;"
|
||||
"varying vec4 v_color;"
|
||||
"varying vec2 v_texCoord;"
|
||||
"vec3 lightdir = vec3(0.5, -0.5, -0.70710);"
|
||||
"vec4 amblight = vec4(20, 20, 20, 0)/255;"
|
||||
"void main()"
|
||||
"{"
|
||||
" gl_Position = projMat * viewMat * worldMat * vec4(in_vertex, 1.0);"
|
||||
|
||||
" vec3 N = normalize(mat3(viewMat * worldMat) * in_normal);"
|
||||
" vec3 P = vec3(viewMat * worldMat * vec4(in_vertex, 1.0));"
|
||||
" vec3 V = normalize(-P);"
|
||||
" float rim = 1.0 - max(dot(V, N), 0.0);"
|
||||
|
||||
" vec3 n = mat3(worldMat) * in_normal;"
|
||||
" float l = max(0.0, dot(n, -lightdir));"
|
||||
// " l = l*0.4 + rim;"
|
||||
" v_color = (in_color+vec4(l,l,l,0)+amblight)*matColor;"
|
||||
" v_texCoord = in_texCoord;"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#ifdef FRAGMENT\n"
|
||||
"uniform sampler2D u_texture0;"
|
||||
"varying vec4 v_color;"
|
||||
"varying vec2 v_texCoord;"
|
||||
"void main()"
|
||||
"{"
|
||||
" vec4 c0 = texture2D(u_texture0, v_texCoord/512.0);"
|
||||
" gl_FragColor = v_color*c0;"
|
||||
"}\n"
|
||||
"#endif\n";
|
||||
const char *srcarr[] = { "#version 120\n",
|
||||
"#define VERTEX\n", shadersrc };
|
||||
GLint vertshader = rw::gl::compileShader(srcarr, 3, GL_VERTEX_SHADER);
|
||||
assert(vertshader != 0);
|
||||
srcarr[1] = "#define FRAGMENT\n";
|
||||
GLint fragshader = rw::gl::compileShader(srcarr, 3, GL_FRAGMENT_SHADER);
|
||||
assert(fragshader != 0);
|
||||
program = rw::gl::linkProgram(vertshader, fragshader);
|
||||
assert(program != 0);
|
||||
|
||||
GLfloat vertarray[] = {
|
||||
0.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
};
|
||||
glGenBuffers(1, &vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertarray),
|
||||
vertarray, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
camera = new Camera;
|
||||
camera->setAspectRatio(1.0f*screenWidth/screenHeight);
|
||||
camera->setNearFar(0.1f, 450.0f);
|
||||
camera->setTarget(Vec3(0.0f, 0.0f, 0.0f));
|
||||
// camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
|
||||
camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||
|
||||
rw::currentTexDictionary = new rw::TexDictionary;
|
||||
// rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtasa/models/gta3_archive/txd_extracted/");
|
||||
// rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtavc/MODELS/gta3_archive/txd_extracted/");
|
||||
rw::Image::setSearchPath(
|
||||
"/home/aap/gamedata/ps2/gta3/MODELS/gta3_archive/txd_extracted/;//home/aap/gamedata/ps2/gtavc/MODELS/gta3_archive/txd_extracted/;/home/aap/gamedata/ps2/gtasa/models/gta3_archive/txd_extracted/");
|
||||
//"D:\\rockstargames\\ps2\\gtavc\\MODELS\\gta3_archive\\txd_extracted\\;D:\\rockstargames\\ps2\\gtasa\\models\\gta3_archive\\txd_extracted\\");
|
||||
|
||||
rw::gl::registerNativeRaster();
|
||||
gta::registerEnvSpecPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
gta::registerNodeNamePlugin();
|
||||
gta::registerBreakableModelPlugin();
|
||||
gta::registerExtraVertColorPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
rw::ps2::registerPDSPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
// rw::ps2::registerNativeDataPlugin();
|
||||
rw::registerMeshPlugin();
|
||||
rw::Atomic::init();
|
||||
|
||||
printf("platform: %d\n", rw::platform);
|
||||
|
||||
rw::StreamFile in;
|
||||
if(in.open(filename, "rb") == NULL)
|
||||
printf("couldn't open file\n");
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
assert(clump);
|
||||
in.close();
|
||||
}
|
||||
|
||||
void
|
||||
keypress(GLFWwindow *w, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if(action != GLFW_PRESS)
|
||||
return;
|
||||
|
||||
switch(key){
|
||||
case 'Q':
|
||||
case GLFW_KEY_ESCAPE:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int lastX, lastY;
|
||||
static int clickX, clickY;
|
||||
static bool isLDown, isMDown, isRDown;
|
||||
static bool isShiftDown, isCtrlDown, isAltDown;
|
||||
|
||||
void
|
||||
mouseButton(GLFWwindow *w, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
glfwGetCursorPos(w, &x, &y);
|
||||
if(action == GLFW_PRESS){
|
||||
lastX = clickX = x;
|
||||
lastY = clickY = y;
|
||||
if(button == GLFW_MOUSE_BUTTON_LEFT)
|
||||
isLDown = true;
|
||||
if(button == GLFW_MOUSE_BUTTON_MIDDLE)
|
||||
isMDown = true;
|
||||
if(button == GLFW_MOUSE_BUTTON_RIGHT)
|
||||
isRDown = true;
|
||||
}else if(action == GLFW_RELEASE){
|
||||
if(button == GLFW_MOUSE_BUTTON_LEFT)
|
||||
isLDown = false;
|
||||
if(button == GLFW_MOUSE_BUTTON_MIDDLE)
|
||||
isMDown = false;
|
||||
if(button == GLFW_MOUSE_BUTTON_RIGHT)
|
||||
isRDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mouseMotion(GLFWwindow *w, double x, double y)
|
||||
{
|
||||
GLfloat dx, dy;
|
||||
static int xoff = 0, yoff = 0;
|
||||
static bool wrappedLast = false;
|
||||
int width, height;
|
||||
|
||||
glfwGetWindowSize(w, &width, &height);
|
||||
|
||||
dx = float(lastX - x) / float(width);
|
||||
dy = float(lastY - y) / float(height);
|
||||
/* Wrap the mouse if it goes over the window border.
|
||||
* Unfortunately, after glfwSetMousePos is done, there can be old
|
||||
* events with an old mouse position,
|
||||
* hence the check if the pointer was wrapped the last time. */
|
||||
if((isLDown || isMDown || isRDown) &&
|
||||
(x < 0 || y < 0 || x >= width || y >= height)){
|
||||
if(wrappedLast){
|
||||
dx = float(lastX-xoff - x) / float(width);
|
||||
dy = float(lastY-yoff - y) / float(height);
|
||||
}
|
||||
xoff = yoff = 0;
|
||||
while (x+xoff >= width) xoff -= width;
|
||||
while (y+yoff >= height) yoff -= height;
|
||||
while (x+xoff < 0) xoff += width;
|
||||
while (y+yoff < 0) yoff += height;
|
||||
glfwSetCursorPos(w, x+xoff, y+yoff);
|
||||
wrappedLast = true;
|
||||
}else{
|
||||
wrappedLast = false;
|
||||
xoff = yoff = 0;
|
||||
}
|
||||
lastX = x+xoff;
|
||||
lastY = y+yoff;
|
||||
if(isLDown){
|
||||
if(isShiftDown)
|
||||
camera->turn(dx*2.0f, dy*2.0f);
|
||||
else
|
||||
camera->orbit(dx*2.0f, -dy*2.0f);
|
||||
}
|
||||
if(isMDown){
|
||||
if(isShiftDown)
|
||||
;
|
||||
else
|
||||
camera->pan(dx*8.0f, -dy*8.0f);
|
||||
}
|
||||
if(isRDown){
|
||||
if(isShiftDown)
|
||||
;
|
||||
else
|
||||
camera->zoom(dx*12.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
resize(GLFWwindow*, int width, int height)
|
||||
{
|
||||
screenWidth = width;
|
||||
screenHeight = height;
|
||||
glViewport(0, 0, screenWidth, screenHeight);
|
||||
camera->setAspectRatio(1.0f*screenWidth/screenHeight);
|
||||
}
|
||||
|
||||
void
|
||||
closewindow(GLFWwindow*)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
return 1;
|
||||
filename = argv[1];
|
||||
|
||||
if(!glfwInit()){
|
||||
fprintf(stderr, "Error: could not initialize GLFW\n");
|
||||
return 1;
|
||||
}
|
||||
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight,
|
||||
"OpenGL", 0, 0);
|
||||
if(!window){
|
||||
fprintf(stderr, "Error: could not create GLFW window\n");
|
||||
glfwTerminate();
|
||||
return 1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
GLenum status = glewInit();
|
||||
if(status != GLEW_OK){
|
||||
fprintf(stderr, "Error: %s\n", glewGetErrorString(status));
|
||||
return 1;
|
||||
}
|
||||
if(!GLEW_VERSION_2_0){
|
||||
fprintf(stderr, "Error: OpenGL 2.0 needed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
glfwSetWindowSizeCallback(window, resize);
|
||||
glfwSetWindowCloseCallback(window, closewindow);
|
||||
glfwSetMouseButtonCallback(window, mouseButton);
|
||||
glfwSetCursorPosCallback(window, mouseMotion);
|
||||
glfwSetKeyCallback(window, keypress);
|
||||
while(running){
|
||||
glfwPollEvents();
|
||||
isShiftDown = glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
|
||||
isCtrlDown = glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS;
|
||||
isAltDown = glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS;
|
||||
|
||||
render();
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user