glBindTexture(GL_TEXTURE_2D, 1);
What is this "1"? You're supposed to bind one of the texture identifiers that you generated previously (stored in myTextures).
Thanks to my work on the SFGUI renderer I know that texture coordinates in SFML are pixel-based a.k.a. not normalized (between 0 and 1) most of the time. If you want to use normalized texture coordinates in your application alongside other SFML drawing you mustn't forget [...]
This applies only in the special case of manual optimization. The expected behaviour when mixing SFML and OpenGL is to call the pushGLStates/popGLStates functions, which ensure that there's no state conflict.
glBindTexture(GL_TEXTURE_2D, 1);
What is this "1"? You're supposed to bind one of the texture identifiers that you generated previously (stored in myTextures).
Thanks to my work on the SFGUI renderer I know that texture coordinates in SFML are pixel-based a.k.a. not normalized (between 0 and 1) most of the time. If you want to use normalized texture coordinates in your application alongside other SFML drawing you mustn't forget [...]
This applies only in the special case of manual optimization. The expected behaviour when mixing SFML and OpenGL is to call the pushGLStates/popGLStates functions, which ensure that there's no state conflict.
That wasn't always like that, even with it proper, still had problems. However I just ended up using Texture.bind() with my loaded textures.
HOWEVER new problem i'm having, and I don't know where else to post, sorry if this is the wrong place, but I figured it's better than a new thread o.o
I transferred my terrain code, to a VBO, and it loads/renders the triangles perfectly. But with Random colors.
Texture is off, but I bet that's just my math, the colors stumped me.
no matter what I change, the color on each triangle is always random, even with a texture on it.
AND on top of that, my SFML 2d code no longer renders!
Updated Code Snips:
Update Code
while (isRunning){
sf::Event _Evn;
while (Screen->pollEvent(_Evn)){
if (_Evn.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
isRunning = false;
if (_Evn.type == sf::Event::Resized)
glViewport(0, 0, _Evn.size.width, _Evn.size.height);
if (_Evn.type == sf::Event::KeyPressed){
if (sf::Keyboard::isKeyPressed(sf::Keyboard::F2))
{
switch (FLY_MODE){
case 0:
FLY_MODE = 1;
break;
case 1:
FLY_MODE = 0;
break;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::F3))
terrain.ReloadHeightMap();
}
}
oldMouse = sf::Mouse::getPosition(*Screen);
sf::Mouse::setPosition(sf::Vector2i(Screen->getSize().x / 2, Screen->getSize().y / 2), *Screen);
newMouse = sf::Mouse::getPosition(*Screen);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Same as SFML clear, but with some Buffering ;)
//glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 800.f / 600.f, 0.1f, 500.f);
this->Update();
terrain.Draw(&Graphics, &myPos);
Screen->resetGLStates();
myDebugText.setString(sf::String("FPS: " + ConvertToString((int)(1.f / FPSCounter.getElapsedTime().asSeconds()))
+ "\nRotation: " + ConvertToString(myRot.y)
+ "\nPosition: (" + ConvertToString(myPos.x) + ", " + ConvertToString(myPos.y) + ", " + ConvertToString(myPos.z) + ")"
));
Screen->draw(myDebugText);
Screen->display();
if (Ticker.getElapsedTime().asSeconds() > 1 )
{
std::cout << "FPS: " << (int)(1.f / FPSCounter.getElapsedTime().asSeconds()) << std::endl;
Ticker.restart();
}
FPSCounter.restart();
}
terrain .h file
typedef struct{
float x, y, z;
}Vertex;
typedef struct{
float u, v;
}TextureCoord;
class Terrain{
private:
Vertex * vertices;
TextureCoord * texcoords;
GLuint VBOverticeID;
GLuint VBOtexcoordsID;
int VertexCount;
int myWidth;
int myHeight;
float Scale;
sf::Clock timer;
sf::Texture grassTexture;
int myRenderStyle;
public:
Terrain(){
vertices = NULL;
texcoords= NULL;
}
~Terrain(){
if (vertices != NULL)
delete[] vertices;
if (texcoords != NULL)
delete [] texcoords;
vertices = NULL;
texcoords = NULL;
}
void Smooth(float k);
void SetTexture(GLuint * texture);
void Draw(Texture_Controller * graphics, sf::Vector3f *PlayerPos); //graphics holds textures
void LoadHeightMap(Texture_Controller * graphics, std::string Map);
void GenerateHeightMap(int sizeX, int sizeZ);
void ReloadHeightMap();
void Dispose();
};
terrain.Draw Code
glPushMatrix();
//glPolygonMode ( GL_FRONT_AND_BACK , GL_LINES ) ;
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
grassTexture.bind(sf::Texture::Pixels);
glBindBuffer(GL_ARRAY_BUFFER, VBOtexcoordsID);
glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, VBOverticeID);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
glDrawArrays(GL_TRIANGLES, 0, VertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
Terrain Loading Code
void Terrain::GenerateHeightMap(int sizeX, int sizeZ){
myWidth = sizeX;
myHeight = sizeZ;
const int MAPSIZE = sizeX * sizeZ * 6;
vertices = new Vertex[MAPSIZE];
texcoords = new TextureCoord[MAPSIZE];
VertexCount = MAPSIZE;
float Amp = Randomizer::Random(0.0f, 3.5f);
float Freq = 0.04f;
int RandomSeed = Randomizer::Random(-500, 500);
int Octaves = Randomizer::Random(3, 10);
if (grassTexture.getSize().x <= 0)
grassTexture.loadFromFile("Textures/grass.jpg");
if (vertices != NULL){
int hmWidth = sizeX;
int hmHeight = sizeZ;
PerlinNoise PN(0.2f, Freq, Amp, Octaves, RandomSeed );
int index = 0;
for (int hMapX = 0; hMapX < hmWidth; hMapX++){
for (int hMapZ = 0; hMapZ < hmHeight; hMapZ++){
for (int nTri = 0; nTri < 6; nTri++){
float flX = (float)hMapX + ((nTri == 1 || nTri == 2 || nTri == 5) ? 1 : 0);
float flZ = (float)hMapZ + ((nTri == 2 || nTri == 4 || nTri == 5) ? 1 : 0);
double height = PN.GetHeight(flX, flZ) * 45.f;
vertices[index].x = flX;
vertices[index].y = height;
vertices[index].z = flZ;
texcoords[index].u = 0.f;
texcoords[index].v = 0.f;
if (nTri == 0 || 3){
texcoords[index].u = 0.f;
texcoords[index].v = 0.f;
}//
if (nTri == 1 || 4){
texcoords[index].u = grassTexture.getSize().x;
texcoords[index].v = 0.f;
}
if (nTri == 2 || 5){
texcoords[index].u = grassTexture.getSize().x;
texcoords[index].v = grassTexture.getSize().y;
}
float Light = 30.f / height;
if (Light > 1.f) Light = 1.f;
if (Light < 0.f) Light = 0.f;
index++;
}
}
}
this->Smooth(0.90f);
}
Scale = 3.5f;
glGenBuffers(1, &VBOverticeID);
glBindBuffer(GL_ARRAY_BUFFER, VBOverticeID);
glBufferData(GL_ARRAY_BUFFER, VertexCount * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &VBOtexcoordsID);
glBindBuffer(GL_ARRAY_BUFFER, VBOtexcoordsID);
glBufferData(GL_ARRAY_BUFFER, VertexCount * 2 * sizeof(float), texcoords, GL_STATIC_DRAW);
delete [] vertices;
delete [] texcoords;
vertices = NULL;
texcoords = NULL;
}
GLEW init code
void InitGLEW(){
glewInit();
glGenBuffers = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferData");
glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffers");
}
openGL init Code
void Init_OpenGL(void){
glClearDepth(1.f);
glClearColor(0.1f, 0.1f, 0.1f, 0.f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 800.f / 600.f, 0.1f, 500.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
std::cout << "You are running openGL Version: " << glGetString(GL_VERSION) << std::endl;
InitGLEW();
glColor4f(1.f, 1.f, 1.f, 1.f);
}
Any other code is the same as previously posted.
What am I doing wrong!?
Screenshot of problem:
http://img171.imageshack.us/img171/3222/examplexa.png
I'm such a openGL noob :(, any openGL tips is GREATLY appreciated!
I tried to read through your code, but it is too long, code highlighting is disabled (use the code=cpp tag to enable highlighting) and some things are a bit complicated, which is normal when using VBOs. Your best bet is to make a copy of your project and comment out stuff until the SFML text shows up again. Does the trick for me all the time.
When debugging stuff using VBOs I also normally don't load such complex geometry when trying to debug draw problems. Try drawing flat terrain (1 Quad with 4 vertices or 1 Triangle with 3 vertices) and see what happens.
You could also try calling your SFML stuff in between Screen->pushGLStates() and Screen->popGLStates().
grassTexture.bind(sf::Texture::Pixels);
Are you sure this necessary? Since you use the full texture all the time you can just use 0.0 and 1.0 in Normalized mode instead of the width/height of the texture in Pixel mode.
I'm such a openGL noob :(, any openGL tips is GREATLY appreciated!
I normally also provide color data to OpenGL when using VBOs. If you apply a texture to something, the color of the texture is modulated (fancy multiplication) with the active color of the fragment. If it is anything other than white (1*something=something) then you will get colors different from the ones in your texture.
I tried to read through your code, but it is too long, code highlighting is disabled (use the code=cpp tag to enable highlighting) and some things are a bit complicated, which is normal when using VBOs. Your best bet is to make a copy of your project and comment out stuff until the SFML text shows up again. Does the trick for me all the time.
When debugging stuff using VBOs I also normally don't load such complex geometry when trying to debug draw problems. Try drawing flat terrain (1 Quad with 4 vertices or 1 Triangle with 3 vertices) and see what happens.
You could also try calling your SFML stuff in between Screen->pushGLStates() and Screen->popGLStates().
grassTexture.bind(sf::Texture::Pixels);
Are you sure this necessary? Since you use the full texture all the time you can just use 0.0 and 1.0 in Normalized mode instead of the width/height of the texture in Pixel mode.
I'm such a openGL noob :(, any openGL tips is GREATLY appreciated!
I normally also provide color data to OpenGL when using VBOs. If you apply a texture to something, the color of the texture is modulated (fancy multiplication) with the active color of the fragment. If it is anything other than white (1*something=something) then you will get colors different from the ones in your texture.
I tried the different bind settings and coordinates, nothing.
also, I DID pass a color VBO alongside the vertices, but nothing changed so I removed.
i'll try removing things until sfml shows back up, but the code posted is as minimal as I can get, with random stuff removed (other than timer).
EDIT: apparently this section of code in Terrain::Draw is causing the sfml draw problem.
glGenBuffers(1, &VBOverticeID);
glBindBuffer(GL_ARRAY_BUFFER, VBOverticeID);
glBufferData(GL_ARRAY_BUFFER, VertexCount * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &VBOtexcoordsID);
glBindBuffer(GL_ARRAY_BUFFER, VBOtexcoordsID);
glBufferData(GL_ARRAY_BUFFER, VertexCount * 2 * sizeof(float), texcoords, GL_STATIC_DRAW);
You are still testing with too much stuff going on. When I wrote the SFGUI VBO renderer crap loads of stuff was displaying wrong when the initial code was done. I just switched everything off (texturing, lighting, coloring, depth testing, alpha testing, blending etc.) and also commented out the places where the VBO data is written to the buffer. Instead I hardcoded a simple triangle into the VBO with simple coordinates so I could verify that it was drawing at the right location with the right size. If the triangle is anything but pure white then you already know that something else is messing up with your state management (be it texturing, color data or whatever). You would have to find out what that thing is and rectify that. After you are sure your code and the results match up you can proceed to activating coloring again and see if that produces the expected results. If not repeat the same procedure. Then on to texturing. When that all works you can start to test with 2 triangles, then 3 and see if it produces the expected results. Then you should be able to use your generated geometry again and if all those previous cases were successful your landscape geometry should also render properly. If not you know that you messed something up in the generation of the geometry VBO data and you can search for the problem there.
Thanks for the help so far, it's been great :)
I managed to get the textures AND colors working perfectly now, :D
My last and final problem is...getting 2D to draw again.
Basically what happens when I try to glPush/Pop OR Screen Push/pop around the SFML drawing part, the following happens:
Everything is rendered normal first until I move, then the scene is rendered the clear color (gray), and the movement updating goes whack, terrain still renders, but skybox stops.
and no 2d rendering.
Code I changed was basically just some things in the update code, and added a color VBO:
Modified Main Loop
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.f, (float)Screen->getSize().x / (float)Screen->getSize().y, 0.1f, 5000.f);
this->Update();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
terrain.Draw(&Graphics, &myPos);
glPopMatrix();
glPushMatrix();
Screen->resetGLStates();
myDebugText.setString(sf::String("FPS: " + ConvertToString((int)(1.f / FPSCounter.getElapsedTime().asSeconds()))));
Screen->draw(myDebugText);
glPopMatrix();
Screen->display();
And is there any documentation on using Shaders from SFML with openGL? I'd love to start delving in Shaders :D