2016-04-11 11 views
2

私は前世代の単純なOpenGLアプリケーションを採用しています。これは、正面六面体を持っていて、テクスチャにレンダリングしてそのテクスチャを画面に描画するように変更しています。どういうわけか、テクスチャへのレンダリング中に、私がglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);と呼んだとき、私の全体のテクスチャは私のglClearColorで着色されています。ここで私が持っているものの全体です:glClearColorは私の全体のテクスチャを着色していますか?

#include <stdio.h> 
#include <GL/glew.h> 
#include <GL/freeglut.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 
#include <iostream> 
#include <fstream> 
#include <Windows.h> 

using namespace std; 

void SetupRenderTarget(); 
void EnableLighting(); 
GLuint LoadProgram(char*, char*); 
void draw(); 
float UpdateDelta(); 
unsigned long getFileLength(ifstream&); 
GLuint compileshader(char* file, GLenum shader_type); 
int loadshader(char*, GLchar**, unsigned long*); 

GLuint quad_vertexbuffer; 
GLuint frame = 0; 
GLuint FrameBuffer = 0; 
GLuint texID = 0; 
GLuint timeID = 0; 
GLuint renderedTexture; 

int main(int argc, char** argv) { 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE); 
    glutInitWindowSize(300, 300); 
    glutInitWindowPosition(100, 500); 
    glutCreateWindow("Hello World"); 
    glutDisplayFunc(draw); 

    glewInit(); 

    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_MULTISAMPLE); 
    glEnable(GL_TEXTURE_2D); 
    glViewport(0, 0, 300, 300); 
    EnableLighting(); 
    SetupRenderTarget(); 

    frame = LoadProgram((char*)"passthrough.shader", (char*)"framebuffer.shader"); 
    texID = glGetUniformLocation(frame, "renderedTexture"); 
    timeID = glGetUniformLocation(frame, "time"); 

    glutMainLoop(); 
    return 0; 
} 

void SetupRenderTarget() { 
    glGenFramebuffers(1, &FrameBuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, FrameBuffer); 
    glGenTextures(1, &renderedTexture); 
    glBindTexture(GL_TEXTURE_2D, renderedTexture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 300, 300, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

    GLuint DepthBuffer; 
    glGenRenderbuffers(1, &DepthBuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, DepthBuffer); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 300, 300); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthBuffer); 

    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0); 
    GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; 
    glDrawBuffers(1, DrawBuffers); 

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 
    cout << "Frame Buffer Error!" << endl; 
    return; 
    } 

    cout << "Frame Buffer Setup" << endl; 
} 

void EnableLighting() { 
    float light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; 
    float light_position[] = { -1.0, 1.0, 1.0, 0.0 }; 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); 
    glLightfv(GL_LIGHT0, GL_POSITION, light_position); 
    glEnable(GL_LIGHT0); 
    glEnable(GL_LIGHTING); 

    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK); 

    glEnable(GL_COLOR_MATERIAL); 
} 

GLuint LoadProgram(char* vertex, char* fragment) { 
    GLuint ProgramObject = 0; 
    GLuint v, f; 
    if (vertex != 0) v = compileshader(vertex, GL_VERTEX_SHADER); 
    if (fragment != 0) f = compileshader(fragment, GL_FRAGMENT_SHADER); 

    ProgramObject = glCreateProgram(); 
    if (v != -1) glAttachShader(ProgramObject, v); 
    if (f != -1) glAttachShader(ProgramObject, f); 

    cout << "Linking Shader..." << endl; 
    glLinkProgram(ProgramObject); 

    cout << "Done!" << endl; 
    return ProgramObject; 
} 

GLuint compileshader(char* file, GLenum shader_type) { 
    cout << "Loading Shader: " << file << endl; 
    char* src; 
    unsigned long src_length = 0; 
    int err = loadshader(file, &src, &src_length); 
    if (err != 0) return -1;// something went wrong 

    cout << "Creating Shader..." << endl; 
    GLuint shader = glCreateShader(shader_type); 
    cout << "Loading Shader..." << endl; 
    glShaderSourceARB(shader, 1, (const char**)&src, (const int*)&src_length); 
    cout << "Compiling Shader..." << endl; 
    glCompileShaderARB(shader); 
    delete[] src; 

    GLint compiled; 
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 
    if (!compiled) { 
    GLint blen = 0; 
    GLsizei slen = 0; 

    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &blen); 
    if (blen > 1) { 
     GLchar* compiler_log = (GLchar*)malloc(blen); 
     glGetInfoLogARB(shader, blen, &slen, compiler_log); 
     cout << "Compiler Log:" << endl << compiler_log << endl; 
     free(compiler_log); 
    } else { 
     cout << "Compile error but could not get log!" << endl; 
    } 
    return -1; 
    } 
    return shader; 
} 

void draw() { 
    static float mytime = 0; 
    float delta = UpdateDelta(); 
    mytime += delta; 

    glBindFramebuffer(GL_FRAMEBUFFER, FrameBuffer); 
    glViewport(0, 0, 300, 300); 

    glLoadIdentity(); 
    float x = 0.5f; 
    glClearColor(x, x, x, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glColor3f(0, 1, 0); 

    glRotatef(45, 0, 1, 0); 
    glutSolidIcosahedron(); 

    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    glViewport(0, 0, 300, 300); 

    glUseProgram(frame); 
    glUniform1i(texID, 0); 
    glUniform1f(timeID, mytime * 10); 

    glLoadIdentity(); 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glColor3f(1, 1, 1); 
    glDisable(GL_LIGHTING); 

    glBegin(GL_QUADS); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left Of The Texture and Quad 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right Of The Texture and Quad 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(1.0f, 1.0f, 0.0f); // Top Right Of The Texture and Quad 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left Of The Texture and Quad 
    glEnd(); 

    glEnable(GL_LIGHTING); 
    glUseProgram(0); 

    glFlush(); 
    glutSwapBuffers(); 
    glutPostRedisplay(); 
} 

float UpdateDelta() { 
    static int time_since_start = 0; 
    static int last = 0; 
    time_since_start = glutGet(GLUT_ELAPSED_TIME); 

    float ret = (time_since_start - last)/1000.0f; 
    last = time_since_start; 
    return ret; 
} 

unsigned long getFileLength(ifstream& file) { 
    if (!file.good()) return 0; 

    unsigned long pos = (unsigned long)file.tellg(); 
    file.seekg(0, ios::end); 
    unsigned long len = (unsigned long)file.tellg(); 
    file.seekg(ios::beg); 

    return len; 
} 

int loadshader(char* filename, GLchar** ShaderSource, unsigned long* len) { 
    ifstream file; 
    file.open(filename, ios::in); // opens as ASCII! 
    if (!file) return -1; 

    *len = getFileLength(file); 

    if (*len == 0) return -2; // Error: Empty File 

    *ShaderSource = (GLchar*) new char[*len + 1]; 
    if (*ShaderSource == 0) return -3; // can't reserve memory 

             // len isn't always strlen cause some characters are stripped in ascii read... 
             // it is important to 0-terminate the real length later, len is just max possible value... 
    (*ShaderSource)[*len] = 0; 

    unsigned int i = 0; 
    while (file.good()) { 
     (*ShaderSource)[i] = file.get();  // get character from file. 
     if (!file.eof()) { 
      i++; 
     } 
    } 
    (*ShaderSource)[i] = 0; // 0-terminate it at the correct position 
    file.close(); 

    return 0; // No Error 
} 

私は部分的にthis tutorialに従い、それのシェーダを使用しています。

passthrough.shader:

#version 330 core 

// Input vertex data, different for all executions of this shader. 
layout(location = 0) in vec3 vertexPosition_modelspace; 

// Output data ; will be interpolated for each fragment. 
out vec2 UV; 

void main() { 
    gl_Position = vec4(vertexPosition_modelspace, 1); 
    UV = (vertexPosition_modelspace.xy + vec2(1, 1))/2.0; 
} 

とframebuffer.shader:

#version 330 core 

in vec2 UV; 

out vec3 color; 

uniform sampler2D renderedTexture; 
uniform float time; 

void main() { 
    color = texture(renderedTexture, UV.xy).rgb; // no change to image 
    //color = texture(renderedTexture, UV + 0.005*vec2(sin(time + 300.0*UV.x), cos(time + 300.0*UV.y))).xyz; // wibbly-wobbly version from tutorial 
} 

[OK]を、私は何が起こっている理解し、私はので、ここでそれは多くのコードを知っている短いと甘いです。

SetupRenderTargetは、私のウィンドウ(300x300)と同じサイズのカラーとデプスバッファを作成します。

EnableLightingシーンを配置して照らすだけです。それはうまく動作しているように見え、見て興味深いものを与える以外の質問には関係ありません。

LoadProgramは、ソースファイルを読み込んでコンパイルし、同じプログラムに配置し、そのプログラムにリンクし、すべてがうまくいけばプログラムIDを返します。を使用します。また、正しく動作しているようです。

drawは、問題の肉が起こっている場所です。私はFrameBufferを使用するように設定しました。私はクリアカラーを設定しました(xは0.0から1.0にそれぞれのパラメータの値を変更して再びうんざりしているからです)、私は二十面体の色を設定しましたシーンはフレーム内で完全にレンダリングされます。

私は自分のプログラムを使い始め、実際の "画面に描画する"フレームバッファーを0に切り替えると、そのバッファーを黒でクリアします(このクリアは私が設定したものではないようです。インパクト)、私はライティングなしで白いクワッドを描き、次のループのためにライティングとプログラムを元に戻します。

この実行中にコンパイルエラーや警告が表示されることはありません。問題は、私がフレームバッファに20面体をレンダリングするときにglClear()と呼ぶときです。その色はテクスチャ全体に色合いを付けます。 xのvarを0に設定して、鮮やかな緑色の背景に黒い背景がありますが、全体のテクスチャは黒くなります。

ここだけ変更することによって、生成されたいくつかの画像だとx VAR:

X = 1.0F; X = 0.5F

x = 1

x = 0.5

X = 0。1f;私の理解へ

x = 0.1

、形状の背景には、明確な色ではなく、形状そのものを反映するために暗くする必要があります。それは、最初のイメージに現れるような活気のある緑のままでなければなりません。

なぜ私のクリアカラーが20面体の描画に影響し、どのように修正するのですか?

Win7 x64でNupenGLライブラリを使用してVisual Studioを使用してコンパイルしており、glGetString(GL_VERSION)には4.3と書かれています。

+0

私は主にESの人ですが、これはかなり固定された/プログラマブルなハイブリッドなので、「glutSolidIcosahedron」がテクスチャリングに関して何を保証していますか?おそらく原因ではありませんが、フレームバッファオブジェクトを技術的に無効にして、そのテクスチャがサンプリングされる可能性がある(つまり、テストは必ずしも実際のサンプリングではない可能性があります) )。定義されていない動作の原因となります。元のルールについては、http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txtの4.4.3を参照してください。 – Tommy

+0

@Tommy [このページ](https://www.opengl.org/resources/libraries/glut/spec3/node80.html)によると、ソリッドシェイプはすべて法線を持ちますが、ティーポットだけがテクスチャ座標を持っています。もちろん、それは1996年以来更新されていません... –

+0

これは、呼び出しを削除することによって問題ではないことを確認することができます:glEnable(GL_TEXTURE_2D);私はしばらくの間、コードを見てきましたが、私は "古い" OpenGLにあまり精通していませんが、どちらも明らかな問題は見えません。私はあなたの質問をupvotedしました。 –

答えて

0

ICOを描画するときにシェーダを使用していないので、デフォルトのパイプラインを使用します。 glEnable(GL_TEXTURE_2D);は、パイプラインにテクスチャリングを使用するよう指示します。どのテクスチャにバインドされていますか?

レンダリングするテクスチャをglBindTexture(GL_TEXTURE_2D, renderedTexture);にバインドし、glBindTexture(GL_TEXTURE_2D, 0);を呼び出してアンバインドしないようにします。そのため、描画する図形のテクスチャデータを取り出すICOを描画しています。このとき、背景色は(x,x,x)のみです。

技術的には、書き込み中にテクスチャから読み込むと、定義されていない動作になると思います。したがって、今回の動作が「正しい」場合でも、この動作を一貫して動作させることはできません。

さらに、glEnable(GL_COLOR_MATERIAL);はあなたのテクスチャが色と混ざり合っていることを知っていなければならないので、ICO(私は思う)は全く緑色にならないでしょう!

関連する問題