Sign in to follow this  
echnaton

OpenGL only 1 render function?

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
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
Guest Anonymous Poster
Hi Smitty

Yes you're right, I alredy knew that but wrote it wrong here :D

Is there any sample code which calls an external function so I can see that it SHOULD really work?

Share this post


Link to post
Share on other sites
I think a lot of people are a bit confused as to exactly what problem you're having. To me it just sounds like you don't understand how functions work (forgive me if I'm wrong). For example, what exactly do you mean by an "external function"?

As Simian Man said, there's nothing special or magical about calling opengl from different functions. So for example:


void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);

RenderTriangle();

Sdl_GL_SwapBuffers();
}

void RenderTriangle()
{
glBegin(GL_TRIANGLES);
glVertex3f(0,1,0);
glVertex3f(-1,0,0);
glVertex3f(0,0,1);
glEnd();
}



is the same as:


void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLES);
glVertex3f(0,1,0);
glVertex3f(-1,0,0);
glVertex3f(0,0,1);
glEnd();

Sdl_GL_SwapBuffers();
}



So you get the same result whether the code is in one function or two (note that I didn't test this specific code).

I suggest you check out the tutorials on http://nehe.gamedev.net/ . They're how a lot of people (myself included) started out. They have detailed explanations and will show you how opengl code can be split between functions (one for initialisation, another for shutting down, others for rendering, etc).

Share this post


Link to post
Share on other sites
@Simian Man:

this is true, your code does work but i alredy knew that.
now because all are confused, forget what i told.

my situation:

I want to draw a line (or whatever else) as long as I
press a button but i do not want to to check for the button state
IN the while-loop.

the exact problem is, that i swap the buffer before any
events are handled, so nothing will be drawn.

(doubleBuffered) i tried to add glutSwapBuffers() in the key event handler
but it looks crappy....

Share this post


Link to post
Share on other sites
When you do your event handling, store the key state in a bool (true for pressed, false for not).

When rendering, check the state of the bool. If it's false, don't render the line.

Share this post


Link to post
Share on other sites
<quote>When rendering, check the state of the bool. If it's false, don't render the line.</quote>

i exactely try to get rid of that.


but i see, you don't got any solutions (or it isn't possible).

thanks everybody

Share this post


Link to post
Share on other sites
If you want to display a line / polygon / mesh only while a button is pressed you have 2 options:

1) Just as mentioned before check a bool i the render loop. The bool is updated by press / release events. This is the easiest way to go.

2) Use a function pointer or a delegate. This means your press / release events change the delegate or function that renders the line etc. The onPress() event would set the function pointer to a function that renders the line, the onRelease() event would set it to a function that doesn't render anything. In your render loop you just call the function pointed to by the function pointer. Note that this approach is much more difficult to implement.

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  

  • Partner Spotlight

  • Forum Statistics

    • Total Topics
      627636
    • Total Posts
      2978319
  • Similar Content

    • By xhcao
      Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness. 
    • By cebugdev
      hi guys, 
      are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
      Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic 
      let me know if you guys have recommendations.
      Thank you in advance!
    • By dud3
      How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below? 
      Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
      Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.
       
      References:
      Code: https://pastebin.com/Hcshj3FQ
      The video shows the difference between blender and my rotation:
       
    • By Defend
      I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
      My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
      * make lots of VAO/VBO pairs and flip through them to render different objects, or
      * make one big VBO and jump around its memory to render different objects. 
      I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
      If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?
       
    • By test opty
      Hello all,
       
      On my Windows 7 x64 machine I wrote the code below on VS 2017 and ran it.
      #include <glad/glad.h>  #include <GLFW/glfw3.h> #include <std_lib_facilities_4.h> using namespace std; void framebuffer_size_callback(GLFWwindow* window , int width, int height) {     glViewport(0, 0, width, height); } //****************************** void processInput(GLFWwindow* window) {     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)         glfwSetWindowShouldClose(window, true); } //********************************* int main() {     glfwInit();     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);     //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);     GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);     if (window == nullptr)     {         cout << "Failed to create GLFW window" << endl;         glfwTerminate();         return -1;     }     glfwMakeContextCurrent(window);     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))     {         cout << "Failed to initialize GLAD" << endl;         return -1;     }     glViewport(0, 0, 600, 480);     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);     glClear(GL_COLOR_BUFFER_BIT);     while (!glfwWindowShouldClose(window))     {         processInput(window);         glfwSwapBuffers(window);         glfwPollEvents();     }     glfwTerminate();     return 0; }  
      The result should be a fixed dark green-blueish color as the end of here. But the color of my window turns from black to green-blueish repeatedly in high speed! I thought it might be a problem with my Graphics card driver but I've updated it and it's: NVIDIA GeForce GTX 750 Ti.
      What is the problem and how to solve it please?
  • Popular Now