• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
industrialgrok

OpenGL
Problem rendering Quake 3 BSP files

15 posts in this topic

Ok, so for the past week ive been working on a Quake 3 bsp veiwer this is what I have finished already

//standard librarys 
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <sstream>

#include "sys_mem.h"
using namespace std;

#define SCREEN_WIDTH  640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP    32

#define MAX_FACES  10000
#define MAX_VERTS  100000

struct bspface
{
 int textureID;           // The index into the texture array 
 int effect;              // The index for the effects (or -1 = n/a) 
 int type;                // 1=polygon, 2=patch, 3=mesh, 4=billboard 
 int vertexIndex;         // The index into this face's first vertex 
 int numOfVerts;          // The number of vertices for this face 
 int meshVertIndex;       // The index into the first meshvertex 
 int numMeshVerts;        // The number of mesh vertices 
 int lightmapID;          // The texture index for the lightmap 
 int lMapCorner[1];       // The face's lightmap corner in the image 
 int lMapSize[1];         // The size of the lightmap section 
 float lMapPos[2];        // The 3D origin of lightmap. 
 float lMapBitsets[1][2]; // The 3D space for s and t unit vectors. 
 float vNormal[2];        // The face normal. 
 int size[1];             // The bezier patch dimensions. 
};

//

struct bspvertex
{
 float position[2];      //x y z 
 float texturecoord[1];  //u, v texture coordinate
 float lightmapcoord[1]; //u, v lightmap coordinate
 float normal[2];        //x, y, z normalized vector
 char  color[3];         //RGBA color for the vertex //char = byte?
};

struct bsplump
{
 int offset;
 int length;
};

struct bsp
{
 bsplump   lumps[16];
 bspvertex vertices[MAX_VERTS];
 bspface   faces[MAX_FACES];
};

bsp bspbuffer;

bool running = true;  //if renderer is running 
bool lightmaps;

void loadbsp(string);    //prototype

void init()
{
 glClearColor(0.0,0.0,0.0,1.0);            //Background color
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();                         //Reset 
 gluPerspective(45,640.0/480.0,1.0,500.0); //Perspective 
 glMatrixMode(GL_MODELVIEW);
 glEnable(GL_CULL_FACE);
 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 glEnable( GL_BLEND );
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glEnable(GL_LIGHT1); 
 glEnable(GL_COLOR_MATERIAL);

float light_0_amb[] = {0.2f, 0.2, 0.2};
glLightfv(GL_LIGHT0,GL_AMBIENT, light_0_amb);

float light_0_pos[] = {1.0,3.0,1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_0_pos);

float light_0_dif[] = {1.0,1.0,1.0,0.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_0_dif);

float light_0_spec[] = {1.0, 1.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, light_0_spec);
} 

void display()
{
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 glFlush();
 glLoadIdentity();   

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //OpenGL's texture parameters 
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

 //RENDERLOOP

 SDL_GL_SwapBuffers();
}

int main(int argc, char *argv[])
{
 if(argv[1] == NULL)
   cout << "ERROR: No bsp file used as an argument example \"./bsploader.x86 -map.bsp\"" << endl;
 else
     {
      /*tolkenize argument*/
      istringstream namebuffer(argv[1]);  //zero is ./bsploader
      while (!namebuffer.eof())
           {
            string tolken;                      //tolken buffer
            getline(namebuffer, tolken, '-' );  //split and store in tolken buffer
            if(tolken != "")
              {
               loadbsp(tolken);
              }
           }
     do
       {
        SDL_Surface* screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE|SDL_OPENGL);
                           //Window           //Tab
        SDL_WM_SetCaption( "BSPloader","BSPloader");
        Uint32 start;
        init();
        display(); 
        SDL_Delay(1000/30);
       }while(running);
      
     }

 return 0;
}

void loadbsp(string name)
{
 cout << "Loading BSP \"" << name << "\"" << endl; 
 ifstream bspfile;
 bspfile.open (name.c_str(),ios::in|ios::binary);//Load BSP file into memory
 if(bspfile == NULL)
   cout << "ERROR: No file named \""<< name <<"\" found" << endl;
 else
     {
      char magic[64];           //Number used in BSP header	
      bspfile.read(magic, 4);   //Read the magic number in the header of the BSP file it should be "IBSP"
      if((magic[0] != 'I')||(magic[1] != 'B')||(magic[2] != 'S')||(magic[3] != 'P'))
        {
         cout << "ERROR: Not a valid Quake 3 BSP file" << endl;
        }
      else
          {
           int version;
           version = readInt(bspfile);
           if(version != 46)//46 = 0x2e in hexidecimal
             cout << "ERROR: Unknown version of Quake 3 BSP" << endl;
           else
               {
                for (int i = 0; i <= 16; i++)
                   {                 
                    bspbuffer.lumps[i].offset = readInt(bspfile);
                    bspbuffer.lumps[i].length = readInt(bspfile);
                    cout << "Lump " << i << " offset is " << bspbuffer.lumps[i].offset << endl
                         << "Lump " << i << " length is " << bspbuffer.lumps[i].length << endl << endl;                   
                   }
                //Load vertices
                bspfile.seekg (bspbuffer.lumps[10].offset, ios::beg); //Load vertex data from vertex lump (10)
                long readmemory = 0;
                cout << "Loading";

                for (int j = 0; readmemory <= bspbuffer.lumps[10].length; j++)//Read until end of lump
                   { 
                    //Actual vertexes
                    bspbuffer.vertices[j].position[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[1] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[2] = readFloat(bspfile);

                    //U,V coordinates
                    bspbuffer.vertices[j].texturecoord[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].texturecoord[1] = readFloat(bspfile);

                    //Lightmap U,V coordinates
                    bspbuffer.vertices[j].lightmapcoord[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].lightmapcoord[1] = readFloat(bspfile);

                    //Normalized vertex coordinates
                    bspbuffer.vertices[j].position[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[1] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[2] = readFloat(bspfile);

                    char buffer[64];           	
                    bspfile.read(buffer, 4); //Read RGBA color index
                    bspbuffer.vertices[j].color[0] = buffer[0];
                    bspbuffer.vertices[j].color[1] = buffer[1];
                    bspbuffer.vertices[j].color[2] = buffer[2];
                    bspbuffer.vertices[j].color[3] = buffer[3];
                    //10 floats 4 char so 10(4) + 4(1)
                    readmemory = readmemory + 44;  
                    cout << ".";       
                   }

                bspfile.seekg (bspbuffer.lumps[13].offset, ios::beg); //Load face data from vertex lump (13)
                long readmemory2 = 0;
                cout << "Loading";
                for (int b = 0; readmemory2 <= bspbuffer.lumps[13].length; b++)//Read until end of lump
                   { 
                    bspbuffer.faces[b].textureID     = readInt(bspfile); // The index into the texture array 
                    bspbuffer.faces[b].effect        = readInt(bspfile); // The index for the effects (or -1 = n/a) 
                    bspbuffer.faces[b].type          = readInt(bspfile); // 1=polygon, 2=patch, 3=mesh, 4=billboard 
                    bspbuffer.faces[b].vertexIndex   = readInt(bspfile); // The index into this face's first vertex
                    cout << bspbuffer.faces[b].vertexIndex << endl;
                    bspbuffer.faces[b].numOfVerts    = readInt(bspfile); // The number of vertices for this face 
                    bspbuffer.faces[b].meshVertIndex = readInt(bspfile); // The index into the first meshvertex 
                    bspbuffer.faces[b].numMeshVerts  = readInt(bspfile); // The number of mesh vertices 
                    bspbuffer.faces[b].lightmapID    = readInt(bspfile); // The texture index for the lightmap 

                    bspbuffer.faces[b].lMapCorner[0] = readInt(bspfile); // The face's lightmap corner in the image 
                    bspbuffer.faces[b].lMapCorner[1] = readInt(bspfile); // The face's lightmap corner in the image 

                    bspbuffer.faces[b].lMapSize[0]   = readInt(bspfile); // The size of the lightmap section 
                    bspbuffer.faces[b].lMapSize[1]   = readInt(bspfile); // The size of the lightmap section 

                    bspbuffer.faces[b].lMapPos[0]    = readFloat(bspfile); // The 3D origin of lightmap. 
                    bspbuffer.faces[b].lMapPos[1]    = readFloat(bspfile); // The 3D origin of lightmap. 
                    bspbuffer.faces[b].lMapPos[2]    = readFloat(bspfile); // The 3D origin of lightmap. 

                    bspbuffer.faces[b].lMapBitsets[0][0]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[0][1]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[0][2]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 

                    bspbuffer.faces[b].lMapBitsets[1][0]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[1][1]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[1][2]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
             
                    bspbuffer.faces[b].vNormal[0]    = readFloat(bspfile); // The face normal. 
                    bspbuffer.faces[b].vNormal[1]    = readFloat(bspfile); // The face normal. 
                    bspbuffer.faces[b].vNormal[2]    = readFloat(bspfile); // The face normal. 

                    bspbuffer.faces[b].size[0] = readInt(bspfile);            // The bezier patch dimensions. 
                    bspbuffer.faces[b].size[1] = readInt(bspfile);             // The bezier patch dimensions. 
                    //26(4)
                    readmemory2 = readmemory2 + 104;       
                   }
                
                cout << "Loaded" << endl;
               }
          }

     }
}

the vertex information is mostly gibberish (as that two of the values are zero) Im aware that you have to use vertexIndex for the first vertex and put them into a triangle fan, but how?

0

Share this post


Link to post
Share on other sites

Instead of using triangle fans, you're better off using indexed triangles.  Not every Quake3 map will render properly if you use triangle fans.  I made the same mistake for ages and that's how I fixed my bogus vertex data problem.  My renderer is Direct3D based so it might not help much.  If you want it anyway, I can upload it and hopefully it will help.

 

Shogun.

2

Share this post


Link to post
Share on other sites
blueshogun96  that would be aprecciated. BornToCode how would I fix that? here is my updated code
//standard librarys 
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <sstream>

#include "sys_mem.h"
using namespace std;

#define SCREEN_WIDTH  640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP    32

#define MAX_FACES  10000
#define MAX_VERTS  100000

struct bspface
{
 int textureID;           // The index into the texture array 
 int effect;              // The index for the effects (or -1 = n/a) 
 int type;                // 1=polygon, 2=patch, 3=mesh, 4=billboard 
 int vertexIndex;         // The index into this face's first vertex 
 int numOfVerts;          // The number of vertices for this face 
 int meshVertIndex;       // The index into the first meshvertex 
 int numMeshVerts;        // The number of mesh vertices 
 int lightmapID;          // The texture index for the lightmap 
 int lMapCorner[1];       // The face's lightmap corner in the image 
 int lMapSize[1];         // The size of the lightmap section 
 float lMapPos[2];        // The 3D origin of lightmap. 
 float lMapBitsets[1][2]; // The 3D space for s and t unit vectors. 
 float vNormal[2];        // The face normal. 
 int size[1];             // The bezier patch dimensions. 
};

//

struct bspvertex
{
 float position[3];      //x y z 
 float texturecoord[2];  //u, v texture coordinate
 float lightmapcoord[2]; //u, v lightmap coordinate
 float normal[3];        //x, y, z normalized vector
 char  color[4];         //RGBA color for the vertex //char = byte?
};

struct bsplump
{
 int offset;
 int length;
};

struct bsp
{
 bsplump   lumps[16];
 bspvertex vertices[MAX_VERTS];
 bspface   faces[MAX_FACES];
};

bsp bspbuffer;

bool running = true;  //if renderer is running 
bool lightmaps;

void loadbsp(string);    //prototype

void init()
{
 glClearColor(0.0,0.0,0.0,1.0);            //Background color
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();                         //Reset 
 gluPerspective(45,640.0/480.0,1.0,500.0); //Perspective 
 glMatrixMode(GL_MODELVIEW);
 glEnable(GL_CULL_FACE);
 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 glEnable( GL_BLEND );
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glEnable(GL_LIGHT1); 
 glEnable(GL_COLOR_MATERIAL);

float light_0_amb[] = {0.2f, 0.2, 0.2};
glLightfv(GL_LIGHT0,GL_AMBIENT, light_0_amb);

float light_0_pos[] = {1.0,3.0,1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_0_pos);

float light_0_dif[] = {1.0,1.0,1.0,0.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_0_dif);

float light_0_spec[] = {1.0, 1.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, light_0_spec);
} 

void display()
{
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 glFlush();
 glLoadIdentity();   

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //OpenGL's texture parameters 
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

 //RENDERLOOP

 SDL_GL_SwapBuffers();
}

int main(int argc, char *argv[])
{
 if(argv[1] == NULL)
   cout << "ERROR: No bsp file used as an argument example \"./bsploader.x86 -map.bsp\"" << endl;
 else
     {
      /*tolkenize argument*/
      istringstream namebuffer(argv[1]);  //zero is ./bsploader
      while (!namebuffer.eof())
           {
            string tolken;                      //tolken buffer
            getline(namebuffer, tolken, '-' );  //split and store in tolken buffer
            if(tolken != "")
              {
               loadbsp(tolken);
              }
           }
     do
       {
        SDL_Surface* screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE|SDL_OPENGL);
                           //Window           //Tab
        SDL_WM_SetCaption( "BSPloader","BSPloader");
        Uint32 start;
        init();
        display(); 
        SDL_Delay(1000/30);
       }while(running);
      
     }

 return 0;
}

void loadbsp(string name)
{
 cout << "Loading BSP \"" << name << "\"" << endl; 
 ifstream bspfile;
 bspfile.open (name.c_str(),ios::in|ios::binary);//Load BSP file into memory
 if(bspfile == NULL)
   cout << "ERROR: No file named \""<< name <<"\" found" << endl;
 else
     {
      char magic[64];           //Number used in BSP header	
      bspfile.read(magic, 4);   //Read the magic number in the header of the BSP file it should be "IBSP"
      if((magic[0] != 'I')||(magic[1] != 'B')||(magic[2] != 'S')||(magic[3] != 'P'))
        {
         cout << "ERROR: Not a valid Quake 3 BSP file" << endl;
        }
      else
          {
           int version;
           version = readInt(bspfile);
           if(version != 46)//46 = 0x2e in hexidecimal
             cout << "ERROR: Unknown version of Quake 3 BSP" << endl;
           else
               {
                for (int i = 0; i <= 16; i++)
                   {                 
                    bspbuffer.lumps[i].offset = readInt(bspfile);
                    bspbuffer.lumps[i].length = readInt(bspfile);
                    cout << "Lump " << i << " offset is " << bspbuffer.lumps[i].offset << endl
                         << "Lump " << i << " length is " << bspbuffer.lumps[i].length << endl << endl;                   
                   }
                //Load vertices
                bspfile.seekg (bspbuffer.lumps[10].offset, ios::beg); //Load vertex data from vertex lump (10)
                long readmemory = 0;
                cout << "Loading";

                for (int j = 0; j <= bspbuffer.lumps[10].length/sizeof(bspvertex); j++)//Read until end of lump
                   { 
                    //Actual vertexes
                    bspbuffer.vertices[j].position[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[1] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[2] = readFloat(bspfile);

                    //U,V coordinates
                    bspbuffer.vertices[j].texturecoord[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].texturecoord[1] = readFloat(bspfile);

                    //Lightmap U,V coordinates
                    bspbuffer.vertices[j].lightmapcoord[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].lightmapcoord[1] = readFloat(bspfile);

                    //Normalized vertex coordinates
                    bspbuffer.vertices[j].position[0] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[1] = readFloat(bspfile);
                    bspbuffer.vertices[j].position[2] = readFloat(bspfile);

                    char buffer[64];           	
                    bspfile.read(buffer, 4); //Read RGBA color index
                    bspbuffer.vertices[j].color[0] = buffer[0];
                    bspbuffer.vertices[j].color[1] = buffer[1];
                    bspbuffer.vertices[j].color[2] = buffer[2];
                    bspbuffer.vertices[j].color[3] = buffer[3];
                    //10 floats 4 char so 10(4) + 4(1) 
                    cout << bspbuffer.vertices[j].position[0] << bspbuffer.vertices[j].position[1] << bspbuffer.vertices[j].position[2] << endl;
                   }
                cout << "Lump 10 loaded" << endl;
                bspfile.seekg (bspbuffer.lumps[13].offset, ios::beg); //Load face data from vertex lump (13)
                long readmemory2 = 0;
                cout << "Loading";
                for (int b = 0; readmemory2 <= bspbuffer.lumps[13].length; b++)//Read until end of lump
                   { 
                    bspbuffer.faces[b].textureID     = readInt(bspfile); // The index into the texture array 
                    bspbuffer.faces[b].effect        = readInt(bspfile); // The index for the effects (or -1 = n/a) 
                    bspbuffer.faces[b].type          = readInt(bspfile); // 1=polygon, 2=patch, 3=mesh, 4=billboard 
                    bspbuffer.faces[b].vertexIndex   = readInt(bspfile); // The index into this face's first vertex
                    bspbuffer.faces[b].numOfVerts    = readInt(bspfile); // The number of vertices for this face 
                    bspbuffer.faces[b].meshVertIndex = readInt(bspfile); // The index into the first meshvertex 
                    bspbuffer.faces[b].numMeshVerts  = readInt(bspfile); // The number of mesh vertices 
                    bspbuffer.faces[b].lightmapID    = readInt(bspfile); // The texture index for the lightmap 

                    bspbuffer.faces[b].lMapCorner[0] = readInt(bspfile); // The face's lightmap corner in the image 
                    bspbuffer.faces[b].lMapCorner[1] = readInt(bspfile); // The face's lightmap corner in the image 

                    bspbuffer.faces[b].lMapSize[0]   = readInt(bspfile); // The size of the lightmap section 
                    bspbuffer.faces[b].lMapSize[1]   = readInt(bspfile); // The size of the lightmap section 

                    bspbuffer.faces[b].lMapPos[0]    = readFloat(bspfile); // The 3D origin of lightmap. 
                    bspbuffer.faces[b].lMapPos[1]    = readFloat(bspfile); // The 3D origin of lightmap. 
                    bspbuffer.faces[b].lMapPos[2]    = readFloat(bspfile); // The 3D origin of lightmap. 

                    bspbuffer.faces[b].lMapBitsets[0][0]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[0][1]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[0][2]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 

                    bspbuffer.faces[b].lMapBitsets[1][0]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[1][1]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
                    bspbuffer.faces[b].lMapBitsets[1][2]  = readFloat(bspfile); // The 3D space for s and t unit vectors. 
             
                    bspbuffer.faces[b].vNormal[0]    = readFloat(bspfile); // The face normal. 
                    bspbuffer.faces[b].vNormal[1]    = readFloat(bspfile); // The face normal. 
                    bspbuffer.faces[b].vNormal[2]    = readFloat(bspfile); // The face normal. 

                    bspbuffer.faces[b].size[0] = readInt(bspfile);            // The bezier patch dimensions. 
                    bspbuffer.faces[b].size[1] = readInt(bspfile);             // The bezier patch dimensions. 
                    //26(4)
                    readmemory2 = readmemory2 + 104; 
                    cout << ".";        
                   }
                cout << "Lump 13 loaded" << endl;
               }
          }

     }
}

 

               
           
0

Share this post


Link to post
Share on other sites

blueshogun96  that would be aprecciated.


Sorry for the slow response, my regular job has me working nights so I find myself sleeping all day... (I'm at work now) \/_\/

 

I'll upload it when I get home, but it wasn't until I found this link it made sense (Direct3D wise): http://www.xbdev.net/3dformats/quake3bsp/index.php

 

IIRC, this one also renders BSPs the proper way and uses OpenGL, but it's a bit more complex: http://www.paulsprojects.net/opengl/q3bsp/q3bsp.html

 

Hope this helps,

 

Shogun.

0

Share this post


Link to post
Share on other sites

What i mean is that in your structure for normal for example. Normal cosist of xyz which is 3 elements but your array is using 2 elements for bspface.

0

Share this post


Link to post
Share on other sites

blueshogun96 thanks,  BornToCode an array starts at zero so 0,1,2.          mhagain ok, I will start reading Idtech 3's source code, I have read quake, and quake2's have a fairly good understanding of them 

That is what your index needs to say 3 index 0 1 and 2 are used. When you create an array with one element you do not say int Array[0] you say int Array[1] and you use only used index 0. So if you have x y and z then your Array needs to be defined as int Array[3] not int Array[2]. Look at your code in your bspface you have float vNormal[2]; 

vNormal supposed to have xyz which means vNormal needs to be [3] not [2]

Edited by BornToCode
2

Share this post


Link to post
Share on other sites

I attached the source file I used to render .bsp files.  It's a heavily modified version of the one from gametutorials.com.  I modified it to use Direct3D9 and use triangle lists instead of fans.  Maybe I should have included the entire project source.  If you need it, I'll upload that too.

 

So far, my BSP loader is the only one I've ever seen render the Simpsons Q3 map correctly (besides Q3 itself), which is the most complex Q3 map I've seen to date.  Hopefully this helps.

 

Shogun.

 

PS: Be warned, it's messy!

Edited by blueshogun96
0

Share this post


Link to post
Share on other sites

Ok thanks borntocode I was unaware of this. Thanks blueshotgun, Have you actually implemented the PVS system? (like paulsprojects)

0

Share this post


Link to post
Share on other sites

Ok thanks borntocode I was unaware of this. Thanks blueshotgun, Have you actually implemented the PVS system? (like paulsprojects)

 

PVS system?  I'm sorry, what does that mean?  The only thing I used from paulsprojects is his patch rendering code.  My D3D implementation isn't very efficient since it uses D3DDevice::DrawIndexedPrimitiveUP every frame N times per tessellation, but it works.

 

Btw, my nickname is blueshogun, not blueshotgun.  No worries, happens all the time. happy.png

 

Shogun.

0

Share this post


Link to post
Share on other sites

Ok thanks borntocode I was unaware of this. Thanks blueshotgun, Have you actually implemented the PVS system? (like paulsprojects)

 

PVS system?  I'm sorry, what does that mean?  The only thing I used from paulsprojects is his patch rendering code.  My D3D implementation isn't very efficient since it uses D3DDevice::DrawIndexedPrimitiveUP every frame N times per tessellation, but it works.

 

Btw, my nickname is blueshogun, not blueshotgun.  No worries, happens all the time. happy.png

 

Shogun.

PVS=Potensial visibility set. It is a system used in an BSP tree that does Occlusion.

Edited by BornToCode
0

Share this post


Link to post
Share on other sites

 

Ok thanks borntocode I was unaware of this. Thanks blueshotgun, Have you actually implemented the PVS system? (like paulsprojects)

 

PVS system?  I'm sorry, what does that mean?  The only thing I used from paulsprojects is his patch rendering code.  My D3D implementation isn't very efficient since it uses D3DDevice::DrawIndexedPrimitiveUP every frame N times per tessellation, but it works.

 

Btw, my nickname is blueshogun, not blueshotgun.  No worries, happens all the time. happy.png

 

Shogun.

PVS=Potensial visibility set. It is a system used in an BSP tree that does Occlusion.

 

Oh, now I remember.  Yeah, my code does support PVS.  IIRC, it supports everything except billboards and Q3 shaders.  Everything else works, but my beizer patch code isn't perfect because I screwed up the fragment colour thing.

 

Shogun

0

Share this post


Link to post
Share on other sites

Ok guys (blueshogun96 BornToCode mhagain) I read the xbox dev tutorial. Then I worked on it a week got frustrated and then started working on other parts of my engine instead (Finished normal mapping biggrin.png )

anyway I started working on it a week ago and just got it working but now faces wont render correctly.

 

http://postimg.org/image/o2lf8vlp9/ Here are the vertices for a map

 

 

and here's what happens when I render faces on a map

 

http://postimg.org/image/6hmoht7ep/

 

here's the code to it

#include <stdio.h>                        
#include <cstdio>
#include <string>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <GL/GL.h>                                    
#include <SDL/SDL.h>

#include <assert.h>                                  

#include "sys_mem.h"
using namespace std; 

 int SCREEN_WIDTH = 640;
 int SCREEN_HEIGHT = 480;
 int SCREEN_BPP = 24;
 bool running = true;
 bool lightmaps;
 SDL_Event event;

#define MAX_BRUSHES   10000
#define MAX_FACES     10000
#define MAX_VERTS     10000000
#define MAX_TEXTURES  1000

struct bspface
{
 int   textureid;        // The index into the texture array 
 int   effect;           // The index for the effects (or -1 = n/a) 
 int   type;             // 1=polygon, 2=patch, 3=mesh, 4=billboard 
 int   vertexindex;      // The index into this face's first vertex 
 int   numofverts;       // The number of vertices for this face 
 int   meshvertindex;    // The index into the first meshvertex 
 int   nummeshverts;     // The number of mesh vertices 
 int   lightmapid;       // The texture index for the lightmap 
 int   lmapcorner[2];    // The face's lightmap corner in the image 
 int   lmapsize[2];      // The size of the lightmap section 
 float lmappos[3];     // The 3D origin of lightmap. 
 float lmapbitsets[2][3]; // The 3D space for s and t unit vectors. 
 float vnormal[3];     // The face normal. 
 int   size[2];          // The bezier patch dimensions. 
};

struct bspvertex
{
 float position[3];      //x y z 
 float texturecoord[2];  //u, v texture coordinate
 float lightmapcoord[2]; //u, v lightmap coordinate
 float normal[3];        //x, y, z normalized vector
 char  color[4];         //RGBA color for the vertex 
};

struct bsptexture
{
 char name[64];      // The name of the texture w/o the extension 
 int flags;          // The surface flags (unknown) 
 int contents;       // The content flags (unknown)
};

struct bspbrush 
{
 int brushSide;           // The starting brush side for the brush 
 int numofbrushsides;     // Number of brush sides for the brush
 int textureid;           // The texture index for the brush
};

struct bsplump
{
 int offset;
 int length;
};

class bsp
{
 public:
  ifstream    bspfile;
  bsplump     lumps[16];
  char        entities[10000]; 
  bspvertex   vertices[MAX_VERTS];
  bspface     faces[MAX_FACES];
  bsptexture  textures[MAX_TEXTURES];
  bspbrush    brushs[MAX_BRUSHES];
  void load(string);
  void render();  
};

void bsp::load(string name)
{
 cout << "Loading BSP \"" << name << "\"" << endl; 
 bsp::bspfile.open (name.c_str(), istream::binary);
 if(bsp::bspfile == NULL)
   cout << "ERROR: No file named \""<< name <<"\" found" << endl;
 else
     {
      char magic[64];           //Number used in BSP header	
      bsp::bspfile.read(magic, 4);   //Read the magic number in the header of the BSP file it should be "IBSP"
      if((magic[0] != 'I')||(magic[1] != 'B')||(magic[2] != 'S')||(magic[3] != 'P'))
        {
         cout << "ERROR: Not a valid Quake 3 BSP file" << endl;
        }
      else
          {
           int version;
           version = readInt(bsp::bspfile);
           if(version != 46)//46 = 0x2e in hexidecimal
             cout << "ERROR: Unknown version of Quake 3 BSP" << endl;
           else
               {
                for (int i = 0; i <= 16; i++)
                   {                 
                    bsp::lumps[i].offset = readInt(bsp::bspfile);
                    bsp::lumps[i].length = readInt(bsp::bspfile);
                    cout << "Lump " << i << " offset is " << bsp::lumps[i].offset << endl
                         << "Lump " << i << " length is " << bsp::lumps[i].length << endl << endl;                   
                   }
				   
				//Load entities (LUMP 0)
			    bsp::bspfile.seekg (bsp::lumps[0].offset, ios::beg); 
		        bsp::bspfile.read(bsp::entities, bsp::lumps[0].length);  
                
                //Load textures	(LUMP 1)			
				bsp::bspfile.seekg (bsp::lumps[1].offset, ios::beg); //Load face data from vertex lump (13)
                for (int j = 0; j <= bsp::lumps[1].length/sizeof(bsptexture); j++)//Read until end of lump
                   {			   
				    char buffer[72];           
                    bsp::bspfile.read(buffer, 72);  
					
                    for (int k = 0; k <= 71; k++)//Read until end of lump
                       {
					    ((char*)&bsp::textures[j])[k] = buffer[k];
					   }
                   }
				   
                //Load vertices (LUMP 10)
                bsp::bspfile.seekg (bsp::lumps[10].offset, ios::beg); //Load vertex data from vertex lump (10)
                for (int j = 0; j <= bsp::lumps[10].length/sizeof(bspvertex); j++)//Read until end of lump
                   { 
				    char buffer[44];           //create buffer for verts	
                    bsp::bspfile.read(buffer, 44);   //Read 
                    for (int k = 0; k <= 43; k++)//Read until end of lump
                       {
					    ((char*)&bsp::vertices[j])[k] = buffer[k];
					   }
                   }
				
                //Load faces (LUMP 13)
                bsp::bspfile.seekg (bsp::lumps[13].offset, ios::beg); //Load vertex data from vertex lump (10)
                for (int j = 0; j <= bsp::lumps[13].length/sizeof(bspface); j++)//Read until end of lump
                   {
				    char buffer[104];           //create buffer for verts	
                    bsp::bspfile.read(buffer, 104);   //Read 
                    for (int k = 0; k <= 103; k++)//Read until end of lump
                       {
					    ((char*)&bsp::faces[j])[k] = buffer[k];
					   }
                   }


                cout << "Lump 13 loaded" << endl;
               }
          }

     }
}
//glVertex3f(bspbuffer.vertices[j].position[0], bspbuffer.vertices[j].position[1], bspbuffer.vertices[j].position[2]);
void bsp::render()
{  
 for (int j = 0; j <= bsp::lumps[13].length/sizeof(bspface); j++)//Read until end of lump
    {
	 if ((bsp::faces[j].type == 1)||(bsp::faces[j].type == 3))       // 1=polygon, 2=patch, 3=mesh, 4=billboard	 
       {		
		 glFrontFace(GL_CW);
         glBegin(GL_TRIANGLE_STRIP); 
	          //cout << bsp::faces[j].vertexindex << " " << bsp::faces[j].numofverts <<endl;
              for (int k = 0; k <=  bsp::faces[j].numofverts - 1; k++)//Read until end of lump
                 {
                  //cout<< " " <<bsp::faces[j].vertexindex+k << " vertex" << endl;
                  glVertex3f(bsp::vertices[bsp::faces[j].vertexindex+k].position[0], bsp::vertices[bsp::faces[j].vertexindex+k].position[1], bsp::vertices[bsp::faces[j].vertexindex+k].position[2]);
		         }
		      glEnd();
			 
		}
    }
}

bsp bspbuffer;

 bool initGL() 
 { 
    //Initialize Projection Matrix 
	glMatrixMode( GL_PROJECTION ); 
	glLoadIdentity(); 
	//Initialize Modelview Matrix 
	glMatrixMode( GL_MODELVIEW ); 
	glLoadIdentity(); 
	//Initialize clear color 
	glClearColor( 0.f, 0.f, 0.f, 1.f ); 
	
    //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
	return true; 
 }
 
 float angle;
 void render() 
  { 
   angle = angle + 1;
   glPushMatrix();
   //Clear color buffer 
   glClear( GL_COLOR_BUFFER_BIT ); 
   //Render quad 
   glPointSize(5.0);
   glRotatef(angle,1,1,1);
   glScalef(.002,.002,.002);
   bspbuffer.render();
   //Update screen
   glPopMatrix();
   SDL_GL_SwapBuffers(); 
   
   //While there are events to handle 
   while( SDL_PollEvent( &event ) ) 
        { 
		 if(event.type == SDL_QUIT) 
		   { 
		    running = false;
		    exit(0); 
           }
        }	   
   SDL_Delay( 1000 / 30 );
 }
 
 bool init() 
 { 

  //Initialize SDL 
  if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) 
    {
     return false; 
	 } 
  //Create Window 
  if( SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL ) == NULL ) 
    {
     return false; 
	} 
  //Initialize OpenGL 
  if( initGL() == false ) 
    {
     return false; 
	} //Set caption 
  SDL_WM_SetCaption( "OpenGL BSP", NULL ); 
  return true; 
 }

#undef main
int main()
{
 init();
 bspbuffer.load("test1.bsp");
 do
   {
    render(); 
   }while(running);   
 return 0;
}//End main()


Edited by industrialgrok
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • By fllwr0491
      I googled around but are unable to find source code or details of implementation.
      What keywords should I search for this topic?
      Things I would like to know:
      A. How to ensure that partially covered pixels are rasterized?
         Apparently by expanding each triangle by 1 pixel or so, rasterization problem is almost solved.
         But it will result in an unindexable triangle list without tons of overlaps. Will it incur a large performance penalty?
      B. A-buffer like bitmask needs a read-modiry-write operation.
         How to ensure proper synchronizations in GLSL?
         GLSL seems to only allow int32 atomics on image.
      C. Is there some simple ways to estimate coverage on-the-fly?
         In case I am to draw 2D shapes onto an exisitng target:
         1. A multi-pass whatever-buffer seems overkill.
         2. Multisampling could cost a lot memory though all I need is better coverage.
            Besides, I have to blit twice, if draw target is not multisampled.
       
    • By mapra99
      Hello

      I am working on a recent project and I have been learning how to code in C# using OpenGL libraries for some graphics. I have achieved some quite interesting things using TAO Framework writing in Console Applications, creating a GLUT Window. But my problem now is that I need to incorporate the Graphics in a Windows Form so I can relate the objects that I render with some .NET Controls.

      To deal with this problem, I have seen in some forums that it's better to use OpenTK instead of TAO Framework, so I can use the glControl that OpenTK libraries offer. However, I haven't found complete articles, tutorials or source codes that help using the glControl or that may insert me into de OpenTK functions. Would somebody please share in this forum some links or files where I can find good documentation about this topic? Or may I use another library different of OpenTK?

      Thanks!
    • By Solid_Spy
      Hello, I have been working on SH Irradiance map rendering, and I have been using a GLSL pixel shader to render SH irradiance to 2D irradiance maps for my static objects. I already have it working with 9 3D textures so far for the first 9 SH functions.
      In my GLSL shader, I have to send in 9 SH Coefficient 3D Texures that use RGBA8 as a pixel format. RGB being used for the coefficients for red, green, and blue, and the A for checking if the voxel is in use (for the 3D texture solidification shader to prevent bleeding).
      My problem is, I want to knock this number of textures down to something like 4 or 5. Getting even lower would be a godsend. This is because I eventually plan on adding more SH Coefficient 3D Textures for other parts of the game map (such as inside rooms, as opposed to the outside), to circumvent irradiance probe bleeding between rooms separated by walls. I don't want to reach the 32 texture limit too soon. Also, I figure that it would be a LOT faster.
      Is there a way I could, say, store 2 sets of SH Coefficients for 2 SH functions inside a texture with RGBA16 pixels? If so, how would I extract them from inside GLSL? Let me know if you have any suggestions ^^.
    • By KarimIO
      EDIT: I thought this was restricted to Attribute-Created GL contexts, but it isn't, so I rewrote the post.
      Hey guys, whenever I call SwapBuffers(hDC), I get a crash, and I get a "Too many posts were made to a semaphore." from Windows as I call SwapBuffers. What could be the cause of this?
      Update: No crash occurs if I don't draw, just clear and swap.
      static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 32, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 24, // 24Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; if (!(hDC = GetDC(windowHandle))) return false; unsigned int PixelFormat; if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) return false; if (!SetPixelFormat(hDC, PixelFormat, &pfd)) return false; hRC = wglCreateContext(hDC); if (!hRC) { std::cout << "wglCreateContext Failed!\n"; return false; } if (wglMakeCurrent(hDC, hRC) == NULL) { std::cout << "Make Context Current Second Failed!\n"; return false; } ... // OGL Buffer Initialization glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glBindVertexArray(vao); glUseProgram(myprogram); glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, (void *)indexStart); SwapBuffers(GetDC(window_handle));  
    • By Tchom
      Hey devs!
       
      I've been working on a OpenGL ES 2.0 android engine and I have begun implementing some simple (point) lighting. I had something fairly simple working, so I tried to get fancy and added color-tinting light. And it works great... with only one or two lights. Any more than that, the application drops about 15 frames per light added (my ideal is at least 4 or 5). I know implementing lighting is expensive, I just didn't think it was that expensive. I'm fairly new to the world of OpenGL and GLSL, so there is a good chance I've written some crappy shader code. If anyone had any feedback or tips on how I can optimize this code, please let me know.
       
      Vertex Shader
      uniform mat4 u_MVPMatrix; uniform mat4 u_MVMatrix; attribute vec4 a_Position; attribute vec3 a_Normal; attribute vec2 a_TexCoordinate; varying vec3 v_Position; varying vec3 v_Normal; varying vec2 v_TexCoordinate; void main() { v_Position = vec3(u_MVMatrix * a_Position); v_TexCoordinate = a_TexCoordinate; v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0)); gl_Position = u_MVPMatrix * a_Position; } Fragment Shader
      precision mediump float; uniform vec4 u_LightPos["+numLights+"]; uniform vec4 u_LightColours["+numLights+"]; uniform float u_LightPower["+numLights+"]; uniform sampler2D u_Texture; varying vec3 v_Position; varying vec3 v_Normal; varying vec2 v_TexCoordinate; void main() { gl_FragColor = (texture2D(u_Texture, v_TexCoordinate)); float diffuse = 0.0; vec4 colourSum = vec4(1.0); for (int i = 0; i < "+numLights+"; i++) { vec3 toPointLight = vec3(u_LightPos[i]); float distance = length(toPointLight - v_Position); vec3 lightVector = normalize(toPointLight - v_Position); float diffuseDiff = 0.0; // The diffuse difference contributed from current light diffuseDiff = max(dot(v_Normal, lightVector), 0.0); diffuseDiff = diffuseDiff * (1.0 / (1.0 + ((1.0-u_LightPower[i])* distance * distance))); //Determine attenuatio diffuse += diffuseDiff; gl_FragColor.rgb *= vec3(1.0) / ((vec3(1.0) + ((vec3(1.0) - vec3(u_LightColours[i]))*diffuseDiff))); //The expensive part } diffuse += 0.1; //Add ambient light gl_FragColor.rgb *= diffuse; } Am I making any rookie mistakes? Or am I just being unrealistic about what I can do? Thanks in advance
  • Popular Now