2012-08-16 3 views
2

나는 이것으로 인해 매우 당황 스럽습니다. 나는 약간의 사후 처리를 수행 할 수 있도록 오프 스크린 텍스처로 렌더링하려하지만 텍스처를 수정하지 않고 화면에 그릴 수는 없다. 현재 iPhone 시뮬레이터에서 OpenGL ES 2.0을 타겟팅하고 있습니다.GLSL texture2D()는 항상 (0, 0, 0, 1)을 반환합니다.

vec4 (0, 0, 0, 1)를 반환하는 GLSL의 texture2D() 함수에 문제를 한정했습니다.이 호출을 상수 색상으로 바꾸면 화면이 지정된 색상으로 채워집니다. 텍스처가 생성되어 텍스처 유닛 0에 바인드되고 스토리지가 할당되며 MIN 및 AUTO로 설정된 최소 및 최대 필터가 0으로 설정됩니다.

모든 렌더 - 투 - 텍스처 코드를 초기화하고 데이터를 명시 적으로 초기화하면 동일한 결과를 얻을 수 있습니다. 스크린 프레임 버퍼를 직접 대상으로하면 예상 한 이미지를 얻을 수 있으므로 샘플 데이터를 모두 샘플링하려고하면 텍스처 데이터가 모두 정의됩니다.

텍스처가 렌더링되는 동안 텍스처가 바인딩되지 않았는지 확인하려고했으나 차이는 없습니다.

나는 glEnable (GL_TEXTURE_2D)도 시도했지만 더 이상 ES 2.0에서는 문제가되지 않는다고 생각합니다. 그것은 어쨌든 도움이되지 못했습니다.

실제로 OpenGL ES 2.0에서 내 자신의 얇은 C++ 래퍼 라이브러리를 사용하고 있지만 OpenGL ES 2.0을 잘 알고 있다면이 코드에서 어떤 일이 일어나는지에 관계없이 명확해야합니다. 일반 OpenGL 코드가 아닌 것에 대해 사과드립니다. 내 다음 디버깅 단계는 래퍼 라이브러리없이 코드를 다시 작성하는 것입니다. 어쨌든 나는 골치 아픈 실수를하고 있는지 궁금해하고있었습니다.

그러나 마지막 drawArrays가 설정 한 모든 상태 변수를 호출하기 전에 일반 OpenGL glGet *() 쿼리를 추가했는데 모든 것이 예상대로 설정됩니다.

코드의 극도로 명백한 부분은 스마트 <> 개체입니다. 그들은 단순히 GL 객체 참조와 참조 배열을 감싸고 소멸자에서 연관된 glDelete *()를 호출합니다.

#include <tsvl/vec.hpp> 
using namespace tsvl; 

#include <tsgl2/Context.hpp> 
#include <tsgl2/Smart.hpp> 
using namespace tsgl2; 

#include <array> 
#include <exception> 
#include <string> 
using namespace std; 

#define SHADER_SOURCE(text) "#version 100\n" #text 


namespace { 

const AttributeLocation vertexPositionAttributeLocation(0); 

const string vec2PassthroughVertexShaderSource = SHADER_SOURCE(
    attribute vec2 vertexPosition; 
    void main() { 
    gl_Position = vec4(vertexPosition, 0, 1); 
    } 
); 

const string greenFragmentShaderSource = SHADER_SOURCE(
    void main() { 
    gl_FragColor = vec4(0, 1, 0, 1); 
    } 
); 

const string combineTexturesFragmentShaderSource = SHADER_SOURCE(
    precision highp float; 

    uniform vec2 screenSize; 
    uniform sampler2D samplers[1]; 

    void main() { 
    vec2 texCoord = gl_FragCoord.xy/screenSize; 
    gl_FragColor = texture2D(samplers[0], texCoord); 
    } 
); 

const vec2 vertices[] = { 
    vec2(-0.9f, -0.9f), 
    vec2(0.9f, -0.9f), 
    vec2(0.0f, 0.9f), 
}; 
const int vertexCount = sizeof(vertices)/sizeof(vertices[0]); 

const vec2 screenCorners[] = { 
    vec2(-1.0f, -1.0f), 
    vec2(1.0f, -1.0f), 
    vec2(1.0f, 1.0f), 
    vec2(-1.0f, 1.0f), 
}; 
const int screenCornerCount = sizeof(screenCorners)/sizeof(screenCorners[0]); 

} // unnamed namespace 


void drawDemoScene(int screenWidth, int screenHeight) { 
    FramebufferRef screenFramebuffer = Framebuffer::currentBinding(); 

    // 

    Smart<array<TextureRef, 8>> renderTextures(Context::genTextures<8>()); 
    Smart<array<FramebufferRef, 8>> renderFramebuffers(Context::genFramebuffers<8>()); 

    Context::setActiveTextureUnit(TextureUnit(0)); // My wrapper translates this to GL_TEXTURE0 
    Texture2D::bind(renderTextures.get()[0]); 
    Texture2D::setStorage(TextureFormat::RGBA8, IntRect::Size(screenWidth, screenHeight)); 
    Texture2D::setMinificationFilter(TextureMinificationFilter::NEAREST); 
    Texture2D::setMagnificationFilter(TextureMagnificationFilter::NEAREST); 

    Framebuffer::bind(renderFramebuffers.get()[0]); 
    Framebuffer::ColorAttachment::set(renderTextures.get()[0], FramebufferTextureTarget::TEXTURE_2D); 
    if (Framebuffer::status() != FramebufferStatus::COMPLETE) 
    throw exception(); 

    // 

    vertexPositionAttributeLocation.enableAttributeArray(); 

    Smart<ShaderRef> vec2PassthroughVertexShader(Context::createShader(ShaderType::VERTEX)); 
    vec2PassthroughVertexShader->setSource(vec2PassthroughVertexShaderSource); 
    vec2PassthroughVertexShader->compile(); 
    if (!vec2PassthroughVertexShader->compileWasSuccessful()) 
    throw exception(); 

    Smart<ShaderRef> greenFragmentShader(Context::createShader(ShaderType::FRAGMENT)); 
    greenFragmentShader->setSource(greenFragmentShaderSource); 
    greenFragmentShader->compile(); 
    if (!greenFragmentShader->compileWasSuccessful()) 
    throw exception(); 

    Smart<ShaderRef> combineTexturesFragmentShader(Context::createShader(ShaderType::FRAGMENT)); 
    combineTexturesFragmentShader->setSource(combineTexturesFragmentShaderSource); 
    combineTexturesFragmentShader->compile(); 
    if (!combineTexturesFragmentShader->compileWasSuccessful()) 
    throw exception(); 

    Smart<ProgramRef> vec2PassthroughGreenProgram(Context::createProgram()); 
    vec2PassthroughGreenProgram->attach(*vec2PassthroughVertexShader); 
    vec2PassthroughGreenProgram->attach(*greenFragmentShader); 
    vec2PassthroughGreenProgram->bindAttributeToLocation(
     "vertexPosition", vertexPositionAttributeLocation); 
    vec2PassthroughGreenProgram->link(); 
    vec2PassthroughGreenProgram->validate(); 
    if (!vec2PassthroughGreenProgram->validationWasSuccessful()) 
    throw exception(); 

    Smart<ProgramRef> combineTexturesProgram(Context::createProgram()); 
    combineTexturesProgram->attach(*vec2PassthroughVertexShader); 
    combineTexturesProgram->attach(*combineTexturesFragmentShader); 
    combineTexturesProgram->bindAttributeToLocation(
     "vertexPosition", vertexPositionAttributeLocation); 
    combineTexturesProgram->link(); 
    combineTexturesProgram->validate(); 
    if (!combineTexturesProgram->validationWasSuccessful()) 
    throw exception(); 

    UniformLocation screenSizeUniformLocation = 
     combineTexturesProgram->locationOfUniform("screenSize"); 
    UniformLocation samplersUniformLocation = 
     combineTexturesProgram->locationOfUniform("samplers"); 

    // 

    Context::setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f); 
    Context::setLineWidth(2.0f); 
    Context::setViewport(IntRect(0, 0, screenWidth, screenHeight)); 
    Context::useProgram(*vec2PassthroughGreenProgram); 

    Framebuffer::bind(renderFramebuffers.get()[0]); 

    vertexPositionAttributeLocation.setAttributeArrayPointerAndStride(
     DONT_NORMALIZE, 2, AttributeLocation::ArrayDataType::FLOAT, vertices, 0); 

    Context::clear(CLEAR_COLOR_BUFFER); 
    Context::drawArrays(DrawMode::LINE_LOOP, 0, vertexCount); 

    // 

    Context::enableBlending(); 
    Context::setBlendFuncs(SourceBlendFunc::SRC_ALPHA, DestBlendFunc::ONE_MINUS_SRC_ALPHA); 
    Context::setColorClearValue(1.0f, 1.0f, 1.0f, 1.0f); 
    Context::setViewport(IntRect(0, 0, screenWidth, screenHeight)); 
    Context::useProgram(*combineTexturesProgram); 

    Framebuffer::bind(screenFramebuffer); 

    vertexPositionAttributeLocation.setAttributeArrayPointerAndStride(
     DONT_NORMALIZE, 2, AttributeLocation::ArrayDataType::FLOAT, screenCorners, 0); 

    screenSizeUniformLocation.setUniformValue(vec2(screenWidth, screenHeight)); 
    samplersUniformLocation.setUniformValue(TextureUnit(0)); // Even though setActiveTextureUnit() 
                  // translated this to GL_TEXTURE0 
                  // It stays plain int 0 here. 

    Context::clear(CLEAR_COLOR_BUFFER); 
    Context::drawArrays(DrawMode::TRIANGLE_FAN, 0, screenCornerCount); 
} 

내 랩퍼 라이브러리가 여기에 구현하는 방법을 볼 수 있습니다 https://github.com/jbat-es/tsgl2 편집

:

좋아, 나는 일반 OpenGL을 매우 버전을 박탈를 쓰고 동일한 문제가있다 :

void drawDemoScenePlainGL(int screenWidth, int screenHeight) { 
    GLuint texture; 
    glGenTextures(1, &texture); 

    glBindTexture(GL_TEXTURE_2D, texture); 
    int data[320][460]; 
    memset(data, 0xFF, 320*460*sizeof(int)); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenWidth, screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glBindTexture(GL_TEXTURE_2D, 0); 

    // 

    glEnableVertexAttribArray(0); 

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    const char* source = vec2PassthroughVertexShaderSource.c_str(); 
    int sourceLength = vec2PassthroughVertexShaderSource.length(); 
    glShaderSource(vertexShader, 1, &source, &sourceLength); 
    glCompileShader(vertexShader); 

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    source = combineTexturesFragmentShaderSource.c_str(); 
    sourceLength = combineTexturesFragmentShaderSource.length(); 
    glShaderSource(fragmentShader, 1, &source, &sourceLength); 
    glCompileShader(fragmentShader); 

    GLuint program = glCreateProgram(); 
    glAttachShader(program, vertexShader); 
    glAttachShader(program, fragmentShader); 
    glBindAttribLocation(program, 0, "vertexPosition"); 
    glLinkProgram(program); 

    GLuint screenSizeUniformLocation = glGetUniformLocation(program, "screenSize"); 
    GLuint samplersUniformLocation = glGetUniformLocation(program, "samplers"); 

    // 

    glClearColor(1, 1, 1, 1); 
    glUseProgram(program); 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, screenCorners); 
    glViewport(0, 0, screenWidth, screenHeight); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texture); 

    glUniform2f(screenSizeUniformLocation, screenWidth, screenHeight); 
    glUniform1i(samplersUniformLocation, 0); 

    glClear(GL_COLOR_BUFFER_BIT); 
    glDrawArrays(GL_TRIANGLE_FAN, 0, screenCornerCount); 
} 

답변

5

질감 감싸기 모드는 기본적으로 두 개의 2 차수 텍스처 만 지원하는 GL_REPEAT가 기본입니다. 간단히 추가

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

문제를 해결합니다.

+2

와우. 이걸 찾는데 네 시간 걸렸어. GL은 초보자에게 친숙하지 않습니다. – nmr

관련 문제