Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: How to create a camera to a 3D (game)

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    21

    How to create a camera to a 3D (game)

    Hi,

    im studying from the superbible 6th edition, and i want to make a camera to my 3D "game" but, I dont know how. The source is:
    Code :
    #include <sb6.h>
    #include <vmath.h>
    #include <time.h>
    #include <stdio.h>
    #include <object.h>
    using namespace vmath;
    // Remove this to draw only a single cube!
    #define MANY_CUBES
    /*float r;
    float p;*/
    class singlepoint_app : public sb6::application
    {
        void init()
        {
            static const char title[] = "OpenGL SuperBible - Spinny Cube";
     
            sb6::application::init();
     
            memcpy(info.title, title, sizeof(title));
     
        }
     
        virtual void startup()
        {
            static const char * vs_source[] =
            {
                "#version 410 core                                                  \n"
                "                                                                   \n"
                "in vec4 position;                                                  \n"
                "                                                                   \n"
                "out VS_OUT                                                         \n"
                "{                                                                  \n"
                "    vec4 color;                                                    \n"
                "} vs_out;                                                          \n"
                "                                                                   \n"
                "uniform mat4 mv_matrix;                                            \n"
                "uniform mat4 proj_matrix;                                          \n"
                "                                                                   \n"
                "void main(void)                                                    \n"
                "{                                                                  \n"
                "    gl_Position = proj_matrix * mv_matrix * position;              \n"
                "    vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);      \n"
                "}                                                                  \n"
            };
     
            static const char * fs_source[] =
            {
                "#version 410 core                                                  \n"
                "                                                                   \n"
                "out vec4 color;                                                    \n"
                "                                                                   \n"
                "in VS_OUT                                                          \n"
                "{                                                                  \n"
                "    vec4 color;                                                    \n"
                "} fs_in;                                                           \n"
                "                                                                   \n"
                "void main(void)                                                    \n"
                "{                                                                  \n"
                "    color = fs_in.color;                                           \n"
                "}                                                                  \n"
            };
     
            program = glCreateProgram();
            GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fs, 1, fs_source, NULL);
            glCompileShader(fs);
     
            GLuint vs = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vs, 1, vs_source, NULL);
            glCompileShader(vs);
     
            glAttachShader(program, vs);
            glAttachShader(program, fs);
     
            glLinkProgram(program);
     
            mv_location = glGetUniformLocation(program, "mv_matrix");
            proj_location = glGetUniformLocation(program, "proj_matrix");
     
     
            glGenVertexArrays(1, &vao);
            glBindVertexArray(vao);
     
     
    static const  GLfloat data[] =
            {
                -0.25f,  0.25f, -0.25f,
                -0.25f, -0.25f, -0.25f,
                 0.25f, -0.25f, -0.25f,
     
                 0.25f, -0.25f, -0.25f,
                 0.25f,  0.25f, -0.25f,
                -0.25f,  0.25f, -0.25f,
     
                 0.25f, -0.25f, -0.25f,
                 0.25f, -0.25f,  0.25f,
                 0.25f,  0.25f, -0.25f,
     
                 0.25f, -0.25f,  0.25f,
                 0.25f,  0.25f,  0.25f,
                 0.25f,  0.25f, -0.25f,
     
                 0.25f, -0.25f,  0.25f,
                -0.25f, -0.25f,  0.25f,
                 0.25f,  0.25f,  0.25f,
     
                -0.25f, -0.25f,  0.25f,
                -0.25f,  0.25f,  0.25f,
                 0.25f,  0.25f,  0.25f,
     
                -0.25f, -0.25f,  0.25f,
                -0.25f, -0.25f, -0.25f,
                -0.25f,  0.25f,  0.25f,
     
                -0.25f, -0.25f, -0.25f,
                -0.25f,  0.25f, -0.25f,
                -0.25f,  0.25f,  0.25f,
     
                -0.25f, -0.25f,  0.25f,
                 0.25f, -0.25f,  0.25f,
                 0.25f, -0.25f, -0.25f,
     
                 0.25f, -0.25f, -0.25f,
                -0.25f, -0.25f, -0.25f,
                -0.25f, -0.25f,  0.25f,
     
                -0.25f,  0.25f, -0.25f,
                 0.25f,  0.25f, -0.25f,
                 0.25f,  0.25f,  0.25f,
     
                 0.25f,  0.25f,  0.25f,
                -0.25f,  0.25f,  0.25f,
                -0.25f,  0.25f, -0.25f
            };
     
     
     
     
            glGenBuffers(1, &buffer[0]);
            glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
            glBufferData(GL_ARRAY_BUFFER,
                         sizeof(data),
                         data,
                         GL_STATIC_DRAW);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
            glEnableVertexAttribArray(0);
     
     
     
     
            glEnable(GL_CULL_FACE);
            glFrontFace(GL_CW);
     
            glEnable(GL_DEPTH_TEST);
            glDepthFunc(GL_LEQUAL);
        }
     
        virtual void render(double currentTime)
        {
            static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
            static const GLfloat one = 1.0f;
     
            glViewport(0, 0, info.windowWidth, info.windowHeight);
            glClearBufferfv(GL_COLOR, 0, green);
            glClearBufferfv(GL_DEPTH, 0, &one);
     
            glUseProgram(program);
     
     
            glUniformMatrix4fv(proj_location, 1, GL_FALSE, proj_matrix);
     
    #ifdef MANY_CUBES
     
    		/*if (GetAsyncKeyState('W'))
    		{
    			Sleep (2);
    			p += 0.01f;
    			r += 0.01f;
    		}
    		else if (GetAsyncKeyState('S'))
    		{
    			Sleep (2);
    			p -= 0.01f;
    			r -= 0.01f;
    		}*/
     
            int i;
            for (i = 0; i < 24; i++)
            {
     
     
                float f = (float)i + (float)currentTime * 0.3f;
     
     
    			vmath::mat4 mv_matrix =
    				     vmath::translate(0.0f, 0.0f, -6.0f) *
                                        vmath::rotate( 10.0f, 0.0f, 0.0f /*p*/, 0.0f) *
                                        vmath::rotate( 10.0f, 0.0f /*r*/, 0.0f, 0.0f) *
                                        vmath::translate(sinf(0.1f * f) * 2.0f,
                                                         cosf(0.1f * f) * 2.0f,
                                                         sinf(0.1f * f) * cosf(1.5f * f) * 2.0f);
     
     
                glUniformMatrix4fv(mv_location, 1, GL_FALSE, mv_matrix);
     
                glDrawArrays(GL_TRIANGLES, 0, 36);
     
            }
    #else
            float f = (float)currentTime * 0.3f;
            vmath::mat4 mv_matrix = vmath::translate(0.0f, 0.0f, -4.0f) *
                                    vmath::translate(sinf(2.1f * f) * 0.5f,
                                                        cosf(1.7f * f) * 0.5f,
                                                        sinf(1.3f * f) * cosf(1.5f * f) * 2.0f) *
                                    vmath::rotate((float)currentTime * 45.0f, 0.0f, 1.0f, 0.0f) *
                                    vmath::rotate((float)currentTime * 81.0f, 1.0f, 0.0f, 0.0f);
            glUniformMatrix4fv(mv_location, 1, GL_FALSE, mv_matrix);
            glDrawArrays(GL_TRIANGLES, 0, 36);
    #endif
        }
     
        virtual void shutdown()
        {
            glDeleteVertexArrays(1, &vao);
            glDeleteProgram(program);
            glDeleteBuffers(1, &buffer[0]);
        }
     
        void onResize(int w, int h)
        {
            sb6::application::onResize(w, h);
     
            aspect = (float)w / (float)h;
     
    			proj_matrix = vmath::perspective(60.0f, aspect, 0.1f, 2000.0f);
     
     
        }
     
     
     
    private:
        GLuint          program;
        GLuint          vao;
        GLuint          buffer[2];
        GLint           mv_location;
        GLint           proj_location;
     
        float           aspect;
        vmath::mat4     proj_matrix;
    };
     
    DECLARE_MAIN(singlepoint_app)

    So, iam using the SB6 header file, and vmath, thats the sb6 tool, too. So, Iam thinking about a camera like in a mmorpg games, like wow, savage, fps games.. I think, the my way is not good. I have there that my view matrix will view 24 cubes, thats the first problem, that all of them must be rendered alone. i want to make(if it is possible) something like, a world, and the objects will be there, and if i rotate my camera to a any direction, it will render that objects, which are in that direction. Can anybody help me, pls? It is my dream, to make a 3D world, and the first thing what i need, is a camera.
    Last edited by Kalir44; 09-06-2014 at 05:35 AM.

  2. #2
    Junior Member Regular Contributor
    Join Date
    Dec 2010
    Location
    Oakville, ON, CA
    Posts
    165
    Nice dream!
    This is a basic trivial thing, so just google it. Example:
    http://stackoverflow.com/questions/4...295174#4295174
    Here is the general topic that may be useful also:
    http://www.tomdalling.com/blog/moder...ors-and-input/
    I would also suggest to use the OpenGL legacy matrix functions to manipulate matrices. If if you use higher versions of shaders you can still request matrices using glGet* and upload them into your shaders' uniforms.
    Last edited by Yandersen; 09-06-2014 at 03:39 AM.

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    21
    Thank you, but, Iam learning 4.3 version, that tutorial is for 3.2, so, some things i cant understand, is possible to find something like that, but written in 4.3 ver? btw. this is a camera tut, what about that, world? That i will have a 3D world, and i can rotate my camera to any direction, and it will render the objects in that direction?

    btw2. It is just an idea, stupid idea, but, is it possible to make a lookat matrix, and then, i will rotate that matrix and it will work like a camera?

  4. #4
    Junior Member Regular Contributor
    Join Date
    Dec 2010
    Location
    Oakville, ON, CA
    Posts
    165
    Yeah, that is exactly how it works: initially you place your camera using the glLookAt function (or your emulation of it in case you maintain the modelview matrix by yourself), then you move and rotate it using the glTranslate and glRotate functions (or their emulations). So your camera typically represented with two matrices: movelview (MV) and projection (P). The projection matrix is somewhat constant most of the time as it's purpose is to guide a perspective projection onto the screen. You change it when your screen is resized, or when you want to change the perspective angle, or play with the clipping planes.
    The MV matrix is what you need to modify all the time as this matrix is used to emulate the camera movement. In order to do that, you make a translation or rotation matrix in response to the change in user input related to camera movement (let's call this a transformation matrix for now, "T"). Then you multiply that matrix onto the current modelview matrix to modify it accordingly:
    MV = T * MV;
    Here multiplication is linear, so the columns of first matrix are multiplied by the rows of second one in order to calculate the element in the intersection of both. The result will look like you move and rotate the camera by itself, not the scene. I guess that is what you want, right?
    Just ensure that you normalize the MV matrix after a few hundreds of such transformations to counteract the calculation error. That means that the basis directional vectors your MV matrix consist of slowly runaway from perpendicularity and unit length. So you take first column (3 elements), normalize it (make it a unit length), then you cross the first column vector with the second one to recalculate the third, normalize it's length. Then you cross the third column with the first one to get the second column (first 3 elements only you play with, because the 4th one is 0 for first 3 columns of MV matrix).

    The OpenGL version has nothing to do with the camera.

  5. #5
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    21
    Ok, so lets say, i understand. And, what about that world? Yes, i know about a projection matrix, but the my question is, how to make a....... world That i will made my objects, i will set their position, for example, X 4444, Y 3333, and iam with my camera on X 5445, Y 3121, so i have to move to that position.

  6. #6
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,829
    Quote Originally Posted by Yandersen View Post
    I would also suggest to use the OpenGL legacy matrix functions to manipulate matrices.
    I wouldn't. Either generate the matrices yourself (the actual matrices used for each function are given in the OpenGL 2.1 reference) or use GLM.
    Quote Originally Posted by Yandersen View Post
    If if you use higher versions of shaders you can still request matrices using glGet* and upload them into your shaders' uniforms.
    In the compatibility profile, you can access the standard matrices via the gl_* variables (e.g. gl_ModelViewMatrix for the model-view matrix). glGet* should be avoided, as it can take an inordinate amount of time compared to generating the matrix locally.

  7. #7
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    21
    ok thank you all. So now, i want to learn something about making 3D "world"
    so i will can set objects 3D position, i think it has no something with projection matrix, there you can set if you want to draw "3d, or 2d" but is there something like world matrix? i know something about world space, but in sb6 i have very briefly introduced to that, they did not show me an examples or functions. So i want a help from you, a right direction with which i should go.

  8. #8
    Intern Contributor
    Join Date
    Jul 2014
    Location
    Italy, Lissone
    Posts
    80
    In 3D graphics there are three very important matrices:

    1) Model Matrix: this is unique for every geometry in your "world" and "transforms" the local coordinates of the geometry into world coordinates, thanks to this matrix you can perform geometry rotation, scaling and translation.

    the model matrix is like this:
    Code :
    { 
      ax, bx, cx, dx
      ay, by, cy, dy
      az, bz, cz, dz
      aw, bw, cw, dw
     
      // where dx, dy, and dz indicates the position in the world of your geometry
    }

    2) View Matrix: this is the matrix that defines the position and direction (and up vector but this is not the point) of the eye (or camera, call it how you want), note that the eye position and direction are ever the same, is the "world" that changes around the eye (or camera).
    3) Projection Matrix: this matrix is used to obtain a 3D projection of the "world", there are two projections: the first is Ortographic projection and the second is Perspective projection, this matrix simply transform the vertices in order to simulate the perspective or ortographic projection.

    there are two main multiplication that you can do with this three matrices:

    1) MVP (ModelViewProjection) Matrix: Projection Matrix * View Matrix * Model Matrix
    2) MV (ModelView) matrix: View * Model

    since you are reading Opengl Superbible 6th i suppose that you are using modern Opengl (Opengl 3.x and above), to deal with matrices and vectors you can use GLM math library that come with all operations you'll need.

    what i wrote is the very basic if you want to deepen here there are some links:
    http://www.opengl-tutorial.org/begin...al-3-matrices/
    http://www.minho-kim.com/courses/13f...redbook-05.pdf

  9. #9
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    21
    Thank you, now i can set position of my objects. But, i have another question(maybe i will have to create a new thread, but why? So, i want to create my object, then publish a game. If i will use a png or another format of objects, someone will can change that object, or steal my own object. So, what i have to do that i will can publish my game, and no one will steal my objects? I saw that some games has formats what i have never seen, for example tmh.. So, i have to create my own format, and loader? And, what about that, where I should learn more about that.?

  10. #10
    Intern Contributor
    Join Date
    Jul 2014
    Location
    Italy, Lissone
    Posts
    80
    Well yes, usually an engine uses it's own format, not so much for safety reasons but of convenience: files always contain something you don't need, usually they need lot of memory, they require a lot of loading time and so on..
    So Yes if you have the time, write your own format, but you don't have to care if people can "steal" your object, they probably can do the same even with your own format.
    What you have to encrypt, what you don't want people can access to, are your databases, probably shaders (if you have a revolutionary algorithm), stuff that could allow people to cheat in your game:
    for example gdr games usually need some databases to track items, this databases should be encrypted or everyone might can access to it and cheat... in those cases formats are very important as well as encryption.

    Concerning the loader yes, i think you can go for it and you should write a file exporter, not only for your format but for every format your engine is going to support, the very useful feature of having your own format is that when you want to save a scene you made, is quite sure that you will need a format that track all model matrix of objects, colors, textures and so on..
    I think you understood that Engines and Games are more complicated then what they seem
    Regards and good work.
    Last edited by Ruggero Visitnin; 09-23-2014 at 11:32 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •