Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - bkaxrf

Pages: [1]
1
Graphics / VBO, RenderWindow, FPS Drop
« on: January 11, 2011, 07:27:21 pm »
I downloaded gDEBugger (which is amazing btw) and used it to debug my app.  

My theory is that by using extension functions from your global context, it's not working for the window context,  and by doing the VBO stuff first, it avoids using the window context.  Or possibly it does work but makes the draws slower for some reason.  I did some research and found this:
Quote

Be careful because the function returned by wglGetProcAddress is only guaranteed to work for the pixel format type of the OpenGL rendering context that was current when wglGetProcAddress was called. If you have multiple contexts created for different pixel formats, then keeping a single function addresses in a global variable as shown above may create problems. You may need to maintain distinct function addresses on a per-pixel format basis. Specifically, the Microsoft documentation for wglGetProcAddress warns:

The [Microsoft] OpenGL library supports multiple implementations of its functions. Extension functions supported in one rendering context are not necessarily available in a separate rendering context. Thus, for a given rendering context in an application, use the function addresses returned by the wglGetProcAddress function only.

http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node396.html

Also something similar here:
http://msdn.microsoft.com/en-us/library/dd374390.aspx

So my question is, does the global context have a different pixel format type?  Could this be related to my problem?

Going to give up on this problem for a while and accept that I have to create the VBOs first.

2
Graphics / VBO, RenderWindow, FPS Drop
« on: January 11, 2011, 03:12:43 pm »
So I converted the minimal code to SDL and it has the same performance, which I expected since the slowdown happens at swapbuffers, which means opengl is busy doing stuff.  At this point I'm thinking most likely my opengl VBO loading/drawing commands are incorrect somewhere.  I'll update again if I figure it out.

Edit:
The slowdown in the minimal code was because the texture I was using was too big, which was slowing down the fill rate.  So I'm back to where I started.

On a side note, I found out that
Code: [Select]

sf::ContextSettings contextsettings(32, 8, 0, 2, 0);
sf::Window context(sf::VideoMode(1024, 768, 32), "SFML OpenGL", sf::Style::Default, contextsettings);

is roughly 4 times as fast as
Code: [Select]

sf::ContextSettings contextsettings(32, 8, 0, 2, 0);
sf::RenderWindow context(sf::VideoMode(1024, 768, 32), "SFML OpenGL", sf::Style::Default, contextsettings);


So by using sf::Window and reducing the texture dimensions, I now get
Code: [Select]

QUADCOUNT 10,000, WINDOWWIDTH 1024, WINDOWHEIGHT 768  =  96fps

Which was 16fps before...huge improvement!
Unfortunately, for 100,000 quads I only get 11fps in the minimal code.

I made the sf::Window change in the original code and it still matters if I create the VBOs first or the Window first.  If I create the VBOs first I get 72fps,  if I create them after I get less than 5 fps.

Edit2:
My original code works when generating the VBOs after the window, but the more I run it, the more likely it is to have the fps drop.  It seems that when I open photoshop and close it,  the fps goes back to normal.  When I create the VBOs before the window, it avoids the FPS drop problem, but doesn't fix it in the same way opening/closing photoshop does,  because when I reverse the order it goes back to fps drop.  So now...I'm looking for a way to put opengl back into a "clean" state, and/or avoid whatever leaks I'm having.

3
Graphics / VBO, RenderWindow, FPS Drop
« on: January 10, 2011, 03:54:40 am »
Here is my minimal example:
Code: [Select]


#include <GLee.h>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
using namespace std;

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

#define QUADCOUNT 10000
#define WINDOWWIDTH 1024
#define WINDOWHEIGHT 768

struct MyQuad
{
    float x1, y1, z1, nx1, ny1, nz1, tx1, ty1;
    float x2, y2, z2, nx2, ny2, nz2, tx2, ty2;
    float x3, y3, z3, nx3, ny3, nz3, tx3, ty3;
    float x4, y4, z4, nx4, ny4, nz4, tx4, ty4;
};

sf::RenderWindow* context;
sf::Event event;
sf::Clock timer;
GLuint VBOVertices;
GLuint texture;
MyQuad* qo;
float ftime;
int fps, nfps;
float fpstime;

int main(int argc, char** argv) {

  context = new sf::RenderWindow(sf::VideoMode(WINDOWWIDTH, WINDOWHEIGHT, 32), "WindowTitle");

  qo = new struct MyQuad[QUADCOUNT];
  for (int x=0; x<QUADCOUNT; x++) {
    qo[x].x1=1; qo[x].y1=1; qo[x].z1=-5; qo[x].nx1=0; qo[x].ny1=0; qo[x].nz1=1; qo[x].tx1=1; qo[x].ty1=0;
    qo[x].x2=0; qo[x].y2=1; qo[x].z2=-5; qo[x].nx2=0; qo[x].ny2=0; qo[x].nz2=1; qo[x].tx2=0; qo[x].ty2=0;
    qo[x].x3=0; qo[x].y3=0; qo[x].z3=-5; qo[x].nx3=0; qo[x].ny3=0; qo[x].nz3=1; qo[x].tx3=0; qo[x].ty3=1;
    qo[x].x4=1; qo[x].y4=0; qo[x].z4=-5; qo[x].nx4=0; qo[x].ny4=0; qo[x].nz4=1; qo[x].tx4=1; qo[x].ty4=1;
  }

  glGenBuffers(1, &VBOVertices);
  glBindBuffer(GL_ARRAY_BUFFER, VBOVertices);
  glBufferData(GL_ARRAY_BUFFER, sizeof(MyQuad)*QUADCOUNT, NULL, GL_DYNAMIC_DRAW);
  glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(MyQuad)*QUADCOUNT, &qo[0].x1);

  delete [] qo;

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(60.0,(float)WINDOWWIDTH/(float)WINDOWHEIGHT,1, 100.0);
  glViewport(0,0,WINDOWWIDTH,WINDOWHEIGHT);
  glMatrixMode(GL_MODELVIEW);

  glEnable(GL_TEXTURE_2D);
 
  sf::Image surface;
  if (!surface.LoadFromFile("texture.png")) return 1;
  glGenTextures( 1, &texture );
  glBindTexture( GL_TEXTURE_2D, texture );
  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface.GetWidth(), surface.GetHeight(), 0,
                GL_RGBA, GL_UNSIGNED_BYTE, surface.GetPixelsPtr() );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
 
  while (1)
  {
    while (context->GetEvent(event))
      if (event.Type == sf::Event::KeyPressed)
      {
        if (event.Key.Code == sf::Key::Escape) {
          context->Close();
          exit(0);
        }
      }

    ftime = timer.GetElapsedTime();
    timer.Reset();
    nfps++; fpstime+=ftime; if (fpstime>1.0) { fps = nfps; nfps = 0; fpstime=0; cout << fps << endl; }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0.8,0.8,1.0,1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER, VBOVertices);
    glVertexPointer(3, GL_FLOAT, 32, BUFFER_OFFSET(0));
    glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(12));
    glTexCoordPointer(2, GL_FLOAT, 32, BUFFER_OFFSET(24));
    glDrawArrays(GL_QUADS, 0, QUADCOUNT*4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    context->Display();
  }

  return 0;
}


You'll have to have a texture.png for it to run...

Here are some fps tests I did:
Code: [Select]

QUADCOUNT 10000, WINDOWWIDTH 1024, WINDOWHEIGHT 768  =  16fps
QUADCOUNT 10000, WINDOWWIDTH 800,  WINDOWHEIGHT 600  =  16fps
QUADCOUNT 10000, WINDOWWIDTH 640,  WINDOWHEIGHT 480  =  17fps
QUADCOUNT 10000, WINDOWWIDTH 320,  WINDOWHEIGHT 240  =  63fps

QUADCOUNT 5000, WINDOWWIDTH 1024, WINDOWHEIGHT 768  =  28fps
QUADCOUNT 5000, WINDOWWIDTH 800,  WINDOWHEIGHT 600  =  31fps
QUADCOUNT 5000, WINDOWWIDTH 640,  WINDOWHEIGHT 480  =  32fps
QUADCOUNT 5000, WINDOWWIDTH 320,  WINDOWHEIGHT 240  =  125fps

QUADCOUNT 1000, WINDOWWIDTH 1024, WINDOWHEIGHT 768  =  123fps
QUADCOUNT 1000, WINDOWWIDTH 800,  WINDOWHEIGHT 600  =  143fps
QUADCOUNT 1000, WINDOWWIDTH 640,  WINDOWHEIGHT 480  =  150fps
QUADCOUNT 1000, WINDOWWIDTH 320,  WINDOWHEIGHT 240  =  560fps


It seems to be suffering from the same problem as my original code.  In my original code, I can render 425000 quads with ease,  as long as I create the VBOs before the RenderWindow.

In this minimal code,  it doesn't seem to matter if I create the RenderWindow before or after.   So now I'm really confused, I must be doing something wrong.  :shock:

4
Graphics / Sprite colors bleeding when using subrect
« on: January 09, 2011, 11:20:12 pm »
You're right about it being 0,0,32,32 since its texture coordinates...

But that shouldn't affect the smoothing, it would just be 31x31 instead.

So yeah, your image needs SetSmooth(false),  but you already did that so I'm stumped.  Hrmmm

5
Graphics / Sprite colors bleeding when using subrect
« on: January 09, 2011, 09:37:04 pm »
Do you have the tileset used in the second image?  

Maybe the subrect is okay, but the position that you're drawing the tile to is off by 1?

6
Graphics / Sprite colors bleeding when using subrect
« on: January 09, 2011, 09:31:00 pm »
Did you try..
Code: [Select]

spr.SetSubRect(
   sf::IntRect(
      tileWidth * tilePosInTileSet.x,
      tileHeight * tilePosInTileSet.y,
      tileWidth * (tilePosInTileSet.x + 1) - 1,
      tileHeight * (tilePosInTileSet.y + 1) - 1
);

For 0,0 you get 0,0,31,31
For 1,1 you get 32, 32, 63, 63
etc

7
SFML projects / The Core Passage
« on: January 09, 2011, 06:12:13 pm »
If you want to create a random map generator in the future, an easy way is to use a perlin noise generator.  It will give you a "height" value for each tile position, then you can decide which tile block to use for that specific height.  For instance: y<=10 could be water, 10<y<=15 could be sand, 15<y<=40 could be grass, y>40 could be mountain tops or something.  Then, if the height is in the grass range, you could randomly put trees, rocks, etc

Perlin noise generators can be confusing to understand how they work,  but they are extremely simple to use.  Just set a few parameters, pass in an x,y pair, get back a height value.

You could either use libnoise or just a simple perlin nosie class like this one: http://www.flipcode.com/archives/Perlin_Noise_Class.shtml

8
Graphics / VBO, RenderWindow, FPS Drop
« on: January 09, 2011, 03:31:47 pm »
Sure, each object is a class, in the constructor I call
Code: [Select]
glGenBuffers(1, &VBOVertices);

This is the function that fills the VBO, called once for opaque and once for transparent:
Code: [Select]

void Model::writeToBuffer(bool trans)
{
    //These are variables in the class:
    //GLuint VBOVertices;
    //MyQuad* qo; //Opaque Quads
    //MyQuad* qt; //Transparent Quads
    //int co, ct; //Count of opaque, transparent quads
    //When this function is called, all of these variables have been set

    glBindBuffer(GL_ARRAY_BUFFER, VBOVertices);
    glBufferData(GL_ARRAY_BUFFER, sizeof(MyQuad)*ct+sizeof(MyQuad)*co, NULL, GL_DYNAMIC_DRAW);
    if (!trans)
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(MyQuad)*co, &qo[0].x1);
    else
        glBufferSubData(GL_ARRAY_BUFFER, sizeof(MyQuad)*co, sizeof(MyQuad)*ct, &qt[0].x1);
}


This is the structure for MyQuad:
Code: [Select]

struct MyQuad
{
//Position, normals, texture coords
    float x1, y1, z1;
    float nx1, ny1, nz1;
    float tx1, ty1;

    float x2, y2, z2;
    float nx2, ny2, nz2;
    float tx2, ty2;

    float x3, y3, z3;
    float nx3, ny3, nz3;
    float tx3, ty3;

    float x4, y4, z4;
    float nx4, ny4, nz4;
    float tx4, ty4;
};


This is the function that creates my renderwindow:
Code: [Select]

void DisplayManager::createWindow(int windowWidth, int windowHeight)
{
    _windowWidth = windowWidth;
    _windowHeight = windowHeight;
    if (g.context!=NULL)
    {
      g.context->Close();
      delete g.context;
      g.context = NULL;
    }
    g.context = new sf::RenderWindow(sf::VideoMode(_windowWidth, _windowHeight, 32), "Window");
}


This is the function that draws the objects,  where the actual slowdown happens.  It's called once for opaque and once for transparent:
Code: [Select]

void Model::render(bool trans)
{
  //BUFFER_OFFSET is defined as:
  //#define BUFFER_OFFSET(i) ((char *)NULL + (i))

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_NORMAL_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  glBindTexture(GL_TEXTURE_2D, g.displayManager->texture );
  glBindBuffer(GL_ARRAY_BUFFER, VBOVertices);
  glVertexPointer(3, GL_FLOAT, 32, BUFFER_OFFSET(0));
  glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(12));
  glTexCoordPointer(2, GL_FLOAT, 32, BUFFER_OFFSET(24));
  glPushMatrix();
 
  glTranslatef(posx, posy, posz);
  if (!trans) glDrawArrays(GL_QUADS, 0, co*4);
  else glDrawArrays(GL_QUADS, co*4, ct*4);

  glPopMatrix();

  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_NORMAL_ARRAY);
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}


So thats about everything except for the function that actually builds the models,  but its somewhat lengthy.  Thanks for your help so far!

9
Graphics / Sprite colors bleeding when using subrect
« on: January 09, 2011, 08:08:07 am »
I haven't used subrect, but 0,0,32,32 seems like 33x33 pixels.  Try 0,0,31,31?

10
Graphics / VBO, RenderWindow, FPS Drop
« on: January 09, 2011, 07:57:46 am »
Hello,  I'm not sure if this problem is related to OpenGL or SFML, hoping that someone here might have advice for me.  

I have an application that displays 25 objects using 25 VBOs.

I have a function that builds all 25 VBO's using glGenBuffers, glBufferData, and glBufferSubData.

If I call the function AFTER I create my RenderWindow,  everything works great as long as my window size is about 800x600 or less, I get 90+ fps.  If my window size is 1024x768, the fps drops to ~3, and my CPU usage goes way up, around 50-75%.

If I call the function BEFORE I create my RenderWindow, everything works great no matter the window size,  I get 90+ fps at 1680x1050, and cpu usage is low.  Also, after I create the RenderWindow I can still delete the VBOs and create new ones and the fps doesn't drop.

So the easy solution is just to do what seems to be working,  but is it okay to create the VBOs before the RenderWindow?  Shouldn't I be able to create them after?

Pages: [1]