Функция изменения формы глутена не работает - PullRequest
0 голосов
/ 17 июля 2011

Когда я пытаюсь изменить размер окна перенасыщения, экран гаснет.

Это код функции изменения формы обратного вызова:

void Resize(int width, int height) 
{  
    CurrentWidth = width;
    CurrentHeight = height;


    glViewport(0, 0, (GLsizei)CurrentWidth, (GLsizei)CurrentHeight); 

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); 
    glOrtho(0, CurrentWidth, CurrentHeight, 0, NearPlane, FarPlane);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glutPostRedisplay();
}

Я довольно новичок в мире opengl, но из того, что я узнал, это должно сработать.

И это весь код вместе взятый:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <gl/glut.h>

#include "Utils.h"

int LEFT = 0;
int RIGHT = 0;
int UP = 0;
int DOWN = 0;

int CurrentWidth = 800,
    CurrentHeight = 800,
    WindowHandle = 0;

float NearPlane = 1.0f,
      FarPlane = 100.0f;

float lightX,
      lightY;

void Initialize(int, char*[]);
void InitWindow(int, char*[]);
void Idle(void);
void Resize(int, int);
void KeyPressed(unsigned char, int, int);
void SpecialPressed(int, int, int);
void SpecialReleased(int, int, int);
void Update(void);
void Render(void);
void FillZBuffer(void);
void ClearAlpha(void);
void RenderLightAlpha(float);
void GeometryPass(void);
void Draw(void);

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

    glutMainLoop(); 

    exit(EXIT_SUCCESS);
}

void Initialize(int argc, char* argv[])
{
    InitWindow(argc, argv);

    fprintf(
        stdout,
        "INFO: OpenGL Version: %s\n",
        glGetString(GL_VERSION)
    );

    lightX = 300.0f;
    lightY = 300.0f;
}

void InitWindow(int argc, char* argv[])
{
    glutInit(&argc, argv);

    glutInitContextVersion(3, 3);
    glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);

    glutSetOption(
        GLUT_ACTION_ON_WINDOW_CLOSE,
        GLUT_ACTION_GLUTMAINLOOP_RETURNS
    );

    glutInitWindowSize (CurrentWidth, CurrentHeight); 
    glutInitWindowPosition (100, 100);

    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA);

    WindowHandle = glutCreateWindow ("Shadows");  

    if(WindowHandle < 1) {
        fprintf(
            stderr,
            "ERROR: Could not create a new rendering window.\n"
        );
        exit(EXIT_FAILURE);
    }

    glutDisplayFunc(Render); 
    glutReshapeFunc(Resize);
    glutIdleFunc(Idle);
    glutKeyboardFunc(KeyPressed);
    glutSpecialFunc(SpecialPressed);
    glutSpecialUpFunc(SpecialReleased);
} 

void Update()
{
    int speed = 10;
    if (LEFT)
    {
        lightX -= speed;
    }
    if (RIGHT)
    {
        lightX += speed;
    }
    if (UP)
    {
        lightY -= speed;
    }
    if (DOWN)
    {
        lightY += speed;
    }
}

void Draw()
{
    float x = 200;
    float y = 200;
    float w = 100;
    float h = 100;
    float depth = 0.0f;

    // floor
    glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
    depth = -10.0f;
    glBegin(GL_QUADS);
    {
        glVertex3f(0, 0, depth);
        glVertex3f((float)CurrentWidth, 0, depth);
        glVertex3f((float)CurrentWidth, (float)CurrentHeight, depth);
        glVertex3f(0, (float)CurrentHeight, depth);
    }
    glEnd();

    // square
    glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
    depth = -5.0;
    glBegin(GL_QUADS);
    {
        glVertex3f( x,  y, depth);
        glVertex3f( x + w, y, depth);
        glVertex3f(x + w, y + h, depth);
        glVertex3f(x,  y + h, depth);
    }
    glEnd();
}

void Render() 
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDisable(GL_CULL_FACE);

    Update();

    FillZBuffer();

    ClearAlpha();

    RenderLightAlpha(1.0f);

    GeometryPass();

    glutSwapBuffers();
    glutPostRedisplay(); 
}  

void FillZBuffer()
{
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glDepthMask(GL_TRUE);

    Draw();

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glDepthMask(GL_FALSE);
}

void ClearAlpha()
{
    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
    glColor4f(0.0f, 0.0f, 0.0f, 0.0f);

    glBegin (GL_QUADS);
    {
        glVertex2f(0, 0);
        glVertex2f((float)CurrentWidth, 0);
        glVertex2f((float)CurrentWidth, (float)CurrentHeight);
        glVertex2f(0, (float)CurrentHeight);
    }
    glEnd ();
}

void RenderLightAlpha(float intensity)
{
    float depth = -1.0f;  
    float radius = 300.0f;
    float angle;
    int numSubdivisions = 32;

    glDisable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glBegin(GL_TRIANGLE_FAN);
    {
        glColor4f(0.0f, 0.0f, 0.0f,  intensity);
        glVertex3f(lightX, lightY, depth);

        // Set edge colour for rest of shape
        glColor4f(0.0f, 0.0f, 0.0f, 0.0f);

        for (angle = 0; angle <= (float)PI * 2; angle += (((float)PI * 2) / numSubdivisions))
        {
            glVertex3f( radius*(float)cos(angle) + lightX, radius*(float)sin(angle) + lightY, depth);  
        }

        glVertex3f(lightX + radius, lightY, depth);
    }
    glEnd();
}

void GeometryPass()
{
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_BLEND);
    glBlendFunc(GL_DST_ALPHA, GL_ONE);

    Draw();
}

void Idle()
{
    glutPostRedisplay();
}

void Resize(int width, int height) 
{  
    CurrentWidth = width;
    CurrentHeight = height;


    glViewport(0, 0, (GLsizei)CurrentWidth, (GLsizei)CurrentHeight); 

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); 
    glOrtho(0, CurrentWidth, CurrentHeight, 0, NearPlane, FarPlane);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glutPostRedisplay();
}

void KeyPressed(unsigned char key, int x, int y)
{
    UNREFERENCED_PARAMETER(x);
    UNREFERENCED_PARAMETER(y);

    // escape key
    if (key == 27)
    {
        exit(0);
    }
}

void SpecialPressed(int keyCode, int x, int y)
{
    UNREFERENCED_PARAMETER(x);
    UNREFERENCED_PARAMETER(y);

    if (keyCode == GLUT_KEY_LEFT)
    {
        LEFT = 1;
    }
    else if (keyCode == GLUT_KEY_RIGHT)
    {
        RIGHT = 1;
    }
    else if (keyCode == GLUT_KEY_UP)
    {
        UP = 1;
    }
    else if (keyCode == GLUT_KEY_DOWN)
    {
        DOWN = 1;
    }
}

void SpecialReleased(int keyCode, int x, int y)
{
    UNREFERENCED_PARAMETER(x);
    UNREFERENCED_PARAMETER(y);
    if (keyCode == GLUT_KEY_LEFT)
    {
        LEFT = 0;
    }
    else if (keyCode == GLUT_KEY_RIGHT)
    {
        RIGHT = 0;
    }
    else if (keyCode == GLUT_KEY_UP)
    {
        UP = 0;
    }
    else if (keyCode == GLUT_KEY_DOWN)
    {
        DOWN = 0;
    }
}

Дайте мне знать, если вам нужна дополнительная информация.

1 Ответ

1 голос
/ 17 июля 2011

В функции FillZBuffer маска глубины отключается в конце и включается только в начале той же функции. Поэтому при повторном вызове Render вызов для очистки бита буфера глубины ничего не делает, потому что маска глубины отключена.

Чтобы исправить это, маска глубины должна быть повторно включена перед вызовом, чтобы очистить бит буфера глубины.

Так вот как должен выглядеть Render.

void Render() 
{
    glDepthMask(GL_TRUE); // insert this line
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDisable(GL_CULL_FACE);

    Update();

    FillZBuffer();

    ClearAlpha();

    RenderLightAlpha(1.0f);

    GeometryPass();

    glutSwapBuffers();
    glutPostRedisplay(); 
} 
...