Jump to content
  • Advertisement
Sign in to follow this  
echnaton

OpenGL only 1 render function?

This topic is 4215 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys I have got a beginner question about a serious problem while developing with openGL. As far as i know, there is only 1 function where you can render to a surface, which normally runs in a while-loop, something like: while (!complete) { processEvents(); glBegin(GL_dunnoWhat); glVertex3d(0,0,0,0); glEnd(); if (somethingstrue) { glBegin(whatever); glEnd(); } } It is very inelegant to write rendering code in this one function directly with a lot of IFs and elses. Is there any possibility to add rendering code in another function? Or how do you fellas handle this problem? I personally cannot understand how big game developers solve their complex code in one loop in the same function... I know there are rendering context but I dont know if that's the right point to do. Can you give me some suggestions? thanks, echnaton P.S.: When i try to call a function inside an IF condition, and add rendering code inside that function, it doesn't work (no surprise)

Share this post


Link to post
Share on other sites
Advertisement
You should be able to make OpenGL rendering calls from any function! Post your code and the exact problems, and someone here will probably be able to help you with that.

Share this post


Link to post
Share on other sites
OK, actually i tried it with 2 different methods: SDL and freeGLUT, both didnt work.

Heres the code snippet for freeGLUT:

void DrawGLScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0, 1.0, 1.0);
glTranslatef(scrollX, scrollY, 0.0);
glBegin(GL_LINES);
glVertex2f(0.0, 0.0);
glVertex2f(1.0, 1.0);
glEnd();
glutSwapBuffers();
}


It is called by the glut display function in the main function:
glutDisplayFunc(&DrawGLScene);



And heres the SDL snippet (only the important code):

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

SDL_Init( SDL_INIT_VIDEO );
SDL_Surface *pSDLSurface = SDL_SetVideoMode( windowWidth, windowHeight, 32, nFlags );
while(!isDone) {
SDL_PollEvent(&event);
render();
}
SDL_Quit();
}

void render(void) {
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
//here comes everything that will be drawn
SDL_GL_SwapBuffers();
}




I do apologize for this bad display of the code, but somehow whitespaces and tabs are ignored in this forum.

the question is: how do i add code from a function like:

void filleWithBlack() {
glClear(0,0,0,0);
}

and call it from the while loop in the 'main' function (eg. mouse press or something)?

Share this post


Link to post
Share on other sites
If you're doing it that way you still have to be between glBegin() / glEnd() calls, are you doing that?

Basically like this:

void function1()
{
glBegin();
function2();
glEnd()
}

void function2()
{
// gl draw calls here ...
}

Share this post


Link to post
Share on other sites
One way to solve the complex IF / ELSE cases is to use std::stack to hold different game-states.

For example, create a structure like so...
// Function pointer typedefs
typedef bool (*UPDATE_FUNCTION)(); // Pointer to a bool function
typedef void (*RENDER_FUNCTION)(); // Pointer to a void function

struct GameState
{
UPDATE_FUNCTION Update;
RENDER_FUNCTION Render;
};



Then, say you have an update and a render routine for a START game-state, say START_Update() and START_Render()...
#include <stack>

// Used to hold game-states
std::stack<GameState> StateStack;

// Your functions
bool START_Update() { return(true); }
void START_Render() { /* Your rendering code here */ }

// Create new game state
GameState NewState;
NewState.Update = START_Update;
NewState.Render = START_Render;

// Add new game-state to stack
StateStack.push(NewState);



Then, in your main game loop, you do something like this...
while(GameRunning)
{
if(!StateStack.top().Update()) { GameRunning = false; }
StateStack.top().Render();
}



This probably goes WAY beyond what you were asking, but it eliminates the messy game loop and it is one way for developers to handle their "complex code". And, as Simian Man already said, you can use OpenGL calls in any function (even in your update routines, but that's just bad practice - you should keep your update and render code separate).

NOTE - If there are any errors in the code I provided, please point them out.
EDIT - It would seem my post had barely anything to do with your question. Still, something to look at after you solve your other problems.

Share this post


Link to post
Share on other sites
yes that is pretty close to what i want to do:

void defaultRenderFunction()
{
glBegin();
myOwnFunction();
glEnd()
}

void myOwnFunction() {
glBegin();
//whatever comes here shouldn't matter
glEnd();
}



first - this does NOT work! i don't get any error but the code i have written inside 'myOwnFunction' won't be visible (it will when i add it to my 'defaultRenderFunction' (which was called by glut or sdl).

later i want to "display" code from another function which will be called/triggered by an event, like a mousebutton.

an example:

i want to display a square when i press the left mousebutton.

one way would be over the If-Way:

void defaultRenderFunction()
{
if (mouseButtonPressed) {
glBegin();
//display the square here
glEnd()
}
}


but that is inelegant because bigger projects won't be concise!

so i like to do something like:

void defaultRenderFunction()
{

switch (keys) { //alredy implemented
case leftmousebutton: //alredy implemented
drawANiceSquare();
break;
}
}

void drawANiceSquare() {
glBegin();
// draw it here by calling glVertex3f();
glEnd();
}

Do you guys understand me?

Share this post


Link to post
Share on other sites
@TheShadow344:

Thanks, i appreciate your code and will further implement it :D
I'm no pro and don't know tricks like the stack way...

But unfortunately thats not the point i'm looking for.

the precise question is the example i posted above this post.

Share this post


Link to post
Share on other sites
Quote:
Original post by echnaton
yes that is pretty close to what i want to do:

void defaultRenderFunction()
{
glBegin();
myOwnFunction();
glEnd()
}

void myOwnFunction() {
glBegin();
//whatever comes here shouldn't matter
glEnd();
}



first - this does NOT work! i don't get any error but the code i have written inside 'myOwnFunction' won't be visible (it will when i add it to my 'defaultRenderFunction' (which was called by glut or sdl).

The reason you don't get any errors is because you aren't checking for them. I imagine if you added some glGetError( ) calls, you'd see something along the lines of GL_INVALID_OPERATION, since, according to the documentation,
Quote:
[A GL_INVALID_OPERATION error is generated if] ... glBegin was called within a glBegin/glEnd sequence.


This isn't your actual code, is it:
Quote:
void defaultRenderFunction()
{

switch (keys) { //alredy implemented
case leftmousebutton: //alredy implemented
drawANiceSquare();
break;
}
}

void drawANiceSquare() {
glBegin();
// draw it here by calling glVertex3f();
glEnd();
}

If what I pointed out above doesn't solve the problem, can you post your actual code? It's hard to see what's wrong when we don't see what's actually going on.

-jouley

Share this post


Link to post
Share on other sites
this is my program:

http://www.file-upload.net/download-214287/test.zip.html


execute it with 'make'


the important section is in the 'keyPressed'-function in the file doctorTest.cpp

quote of the function:

// SAMPLE CODE:
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex2f(0.5, 0.0);
glVertex2f(1.0, 0.1);
glEnd();



this will NOT be displayed but it should...

i will check for errors tomorrow

Share this post


Link to post
Share on other sites
The render function is simply the entry point into your rendering logic. You can call as many functions as you want, and they can call as many as they want (stack prohibiting, of course), etc...

The code snippet you showed SHOULD work if it is actually representative of your code.

EDIT: I see others have mentioned it, but you can't call glBegin() then call a function that in turn calls glBegin() again. Just call glBegin when you are ready to ACTUALLY send geometry to the pipeline.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!