2014-04-13 79 views
0

我在网上找到了一个精彩的体绘制教程: volume rendering tutorial 。示例代码是在Windows中编写的,因为我在Mac上工作,所以我根据自己的理解尝试编写自己的代码。目前,我的程序只是将Z轴上-1到1的2D帧排列而不应用alpha和混合。所以如果一切顺利的话,我应该能够看到第一片。但是,当我运行该程序时,我会感到奇怪。基于2D纹理的体绘制

我的代码:

// 
// VolumeRendering.cpp 
// Volume_Rendering 
// 
// Created by HOBBY on 4/5/14. 
// Copyright (c) 2014 Yihao Jiang. All rights reserved. 
// 
#include <GLTools.h> 
#include <GL/glew.h> 
#include <Opengl/gl.h> 
#include <glut/glut.h> 
#include <fstream> 
#include "VolumeRendering.h" 
#include <GLMatrixStack.h> 
#include <GLFrustum.h> 
#include <GLGeometryTransform.h> 

int m_uImageCount; 
int m_uImageWidth; 
int m_uImageHeight; 
GLuint* m_puTextureIDs; 

GLMatrixStack modelViewMatrix; 
GLMatrixStack projectionMatrix; 
GLFrame  cameraFrame; 
GLFrustum  viewFrustum; 
GLBatch  myBatch; 
GLGeometryTransform transformPipeline; 
GLShaderManager  shaderManager; 

void ChangeSize(int w, int h) 
{ 
    glViewport(0, 0, w, h); 
    GLdouble aspectRatio = (GLdouble)(w)/(GLdouble)(h); 
    if (w <= h) 
    { 
     viewFrustum.SetOrthographic(-1.0f, 1.0f, -(1.0f/aspectRatio), 1.0f/aspectRatio, -1.0f, 1.0f); 
    } 
    else 
    { 
     viewFrustum.SetOrthographic(-1.0f, 1.0f, -(1.0f * aspectRatio), 1.0f * aspectRatio, -1.0f, 1.0f); 
    } 
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); 
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix); 

} 

void SetupRC() 
{ 
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 
    shaderManager.InitializeStockShaders(); 

    glEnable(GL_DEPTH_TEST); 

    const char* filePath = "/Users/WensarHobby/Documents/Codes/workspace/Volume_Rendering/Volume_Rendering/head256x256x109"; 
    if(!InitTextures2D(filePath)) 
    { 
     printf("InitTexture error"); 
    } 

} 

bool InitTextures2D(const char* filePath) 
{ 
    std::fstream myFile; 
    myFile.open(filePath, std::ios::in | std::ios::binary); 

    m_uImageCount = 109; 
    m_uImageWidth = 256; 
    m_uImageHeight = 256; 

    // Holds the texuture IDs 
    m_puTextureIDs = new GLuint[m_uImageCount]; 

    // Holds the luminance buffer 
    char* chBuffer = new char[m_uImageWidth * m_uImageHeight]; 
    char* chRGBABuffer = new char[m_uImageWidth * m_uImageHeight * 4]; 
    glGenTextures(m_uImageCount, (GLuint*)m_puTextureIDs); 

    // Read each frames and construct the texture 
    for(int nIndx = 0; nIndx < m_uImageCount; ++nIndx) 
    { 
     // Read the frame 
     myFile.read(chBuffer, m_uImageWidth*m_uImageHeight); 

     // Set the properties of the texture. 
     glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]); 
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 

     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_uImageWidth, m_uImageHeight , 0, 
       GL_LUMINANCE, GL_UNSIGNED_BYTE,(GLvoid *) chBuffer); 
     glBindTexture(GL_TEXTURE_2D, 0); 
    } 

    delete[] chBuffer; 
    delete[] chRGBABuffer; 
    return true; 
} 

void SpecialKeys(int key, int x, int y) 
{ 
    if(key == GLUT_KEY_UP) 
    {} 

    if (key == GLUT_KEY_DOWN) 
    { 

    } 

    if (key == GLUT_KEY_LEFT) 
    { 

    } 

    if (key == GLUT_KEY_RIGHT) 
    { 

    } 

    glutPostRedisplay(); 
} 

void RenderScene(void) 
{ 
    static GLfloat vLightPos [] = { 1.0f, 1.0f, 0.0f }; 
    static GLfloat vWhite [] = { 1.0f, 1.0f, 1.0f, 1.0f }; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 


    modelViewMatrix.PushMatrix(); 
    M3DMatrix44f mCamera; 
    cameraFrame.GetCameraMatrix(mCamera); 
    modelViewMatrix.MultMatrix(mCamera); 

    for(int nIndx=0; nIndx <m_uImageCount;++nIndx) 
    { 
     glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]); 
     MakeQuads(nIndx); 
     glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]); 

    } 


    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, 
          transformPipeline.GetModelViewMatrix(), 
          transformPipeline.GetProjectionMatrix(), 
          vLightPos, vWhite, 0); 
    myBatch.Draw(); 


    modelViewMatrix.PopMatrix(); 

    glutSwapBuffers(); 

} 

void MakeQuads(int quads_index) 
{ 
    myBatch.Begin(GL_QUADS, 4, 1); 
    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(quads_index, 0.0f, 0.0f); 
    myBatch.Vertex3f(-1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 

    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(quads_index, 1.0f, 0.0f); 
    myBatch.Vertex3f(1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 

    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(quads_index, 0.0f, 1.0f); 
    myBatch.Vertex3f(-1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 

    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(quads_index, 1.0f, 1.0f); 
    myBatch.Vertex3f(1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 
    myBatch.End(); 
} 

void ShutdownRC(void) 
{ 
    glDeleteTextures(m_uImageCount, (GLuint*)m_puTextureIDs); 
} 


int main(int argc, char* argv[]) 
{ 
    gltSetWorkingDirectory(argv[0]); 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); 
    glutInitWindowSize(400, 400); 
    glutCreateWindow("Volume_Rendering"); 
    glutReshapeFunc(ChangeSize); 
    glutSpecialFunc(SpecialKeys); 
    glutDisplayFunc(RenderScene); 

    GLenum err = glewInit(); 
    if (GLEW_OK != err) { 
     fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); 
     return 1; 
    } 

    SetupRC(); 

    glutMainLoop(); 
    ShutdownRC(); 
    return 0; 

} 

这是我怪异的结果: weird result

我是新来的OpenGL和容积再现,在我看来,应该有什么问题我使用的着色器管理器。但我不太确定。任何人都可以告诉我问题在哪里?非常感谢你。

+0

这看起来非常典型的第一步调试任何opengl或directx在我看来哈哈。你应该看看如果摆弄你的四坐标,你不会得到更好的东西。这看起来像启用了脸部剔除的一些错误的顶点旋转顺序。可能是任何事情。它已经很好,你看到蓝色! –

+0

我建议发布着色器代码(我没有发现任何明显的东西)。正如@ v.oddou所说,这对于首次使用新代码进行渲染并不罕见。我还建议暂时敲掉所有的纹理代码,并着重于首先获取几何图形(使用固定的颜色)。 – holtavolt

+0

@ v.oddou我做了一些测试,我改变了正投影到透视投影,看来工作。那么在我的代码中使用setOrthographic函数有什么问题? – NJUHOBBY

回答

1

最后,我明白了!我是对的,问题在于函数MultiTexCoord2f()。这个函数的第一个参数应该总是为0而不是quads_​​index。这里没有多重纹理!新代码看起来像这样:

#include <GLTools.h> 
#include <GL/glew.h> 
#include <Opengl/gl.h> 
#include <glut/glut.h> 
#include <fstream> 
#include "VolumeRendering.h" 
#include <GLMatrixStack.h> 
#include <GLFrustum.h> 
#include <GLGeometryTransform.h> 

int m_uImageCount; 
int m_uImageWidth; 
int m_uImageHeight; 
GLuint* m_puTextureIDs; 

GLMatrixStack modelViewMatrix; 
GLMatrixStack projectionMatrix; 
GLFrame  cameraFrame; 
GLFrame  objectFrame; 
GLFrustum  viewFrustum; 
GLBatch  myBatch; 
GLGeometryTransform transformPipeline; 
GLShaderManager  shaderManager; 

void ChangeSize(int w, int h) 
{ 
    glViewport(0, 0, w, h); 
    viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 500.0f); 
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); 
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix); 
}  

void SetupRC() 
{ 
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 
    shaderManager.InitializeStockShaders(); 

    glEnable(GL_DEPTH_TEST); 

    const char* filePath =  "/Users/WensarHobby/Documents/Codes/workspace/Volume_Rendering/Volume_Rendering/head256x256x109"; 
    if(!InitTextures2D(filePath)) 
    { 
     printf("InitTexture error"); 
    } 

    cameraFrame.MoveForward(-7.0f); 
} 

bool InitTextures2D(const char* filePath) 
{ 
    std::fstream myFile; 
    myFile.open(filePath, std::ios::in | std::ios::binary); 

    m_uImageCount = 109; 
    m_uImageWidth = 256; 
    m_uImageHeight = 256; 

    // Holds the texuture IDs 
    m_puTextureIDs = new GLuint[m_uImageCount]; 

    // Holds the luminance buffer 
    char* chBuffer = new char[m_uImageWidth * m_uImageHeight]; 
    //char* chRGBABuffer = new char[m_uImageWidth * m_uImageHeight * 4]; 
    glGenTextures(m_uImageCount, m_puTextureIDs); 

    // Read each frames and construct the texture 
    for(int nIndx = 0; nIndx < m_uImageCount; ++nIndx) 
    { 
     // Read the frame 
     myFile.read(chBuffer, m_uImageWidth*m_uImageHeight); 

     // Set the properties of the texture. 
     glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]); 
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 

     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_uImageWidth, m_uImageHeight , 0, 
       GL_LUMINANCE, GL_UNSIGNED_BYTE,(GLvoid *) chBuffer); 
     glBindTexture(GL_TEXTURE_2D, 0); 
    } 

    delete[] chBuffer; 
    // delete[] chRGBABuffer; 
    return true; 
} 

void SpecialKeys(int key, int x, int y) 
{ 
glutPostRedisplay(); 
} 

void RenderScene(void) 
{ 
    static GLfloat vLightPos [] = { 1.0f, 1.0f, 0.0f }; 
    static GLfloat vWhite [] = { 1.0f, 1.0f, 1.0f, 1.0f }; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 


    modelViewMatrix.PushMatrix(); 
    M3DMatrix44f mCamera; 
    cameraFrame.GetCameraMatrix(mCamera); 
    modelViewMatrix.MultMatrix(mCamera); 

    M3DMatrix44f mObjectFrame; 
    objectFrame.GetMatrix(mObjectFrame); 
    modelViewMatrix.MultMatrix(mObjectFrame); 

    for(int nIndx=0; nIndx <m_uImageCount;++nIndx) 
    { 
     glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]); 
     MakeQuads(nIndx); 
     glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]); 
     shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, 
           transformPipeline.GetModelViewMatrix(), 
           transformPipeline.GetProjectionMatrix(), 
           vLightPos, vWhite, 0); 
     myBatch.Draw(); 
    } 

    modelViewMatrix.PopMatrix(); 

    glutSwapBuffers(); 

} 

void MakeQuads(int quads_index) 
{ 
    myBatch.Begin(GL_QUADS, 4, 1); 

    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(0, 0.0f, 0.0f); 
    myBatch.Vertex3f(-1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 
    //myBatch.Vertex3f(-1.0f, -1.0f, 1.0f); 

    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(0, 1.0f, 0.0f); 
    myBatch.Vertex3f(1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 
    //myBatch.Vertex3f(1.0f, -1.0f, 1.0f); 

    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(0, 1.0f, 1.0f); 
    myBatch.Vertex3f(1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 
    //myBatch.Vertex3f(1.0f, 1.0f, 1.0f); 

    myBatch.Normal3f(0.0f, 0.0f, -1.0f); 
    myBatch.MultiTexCoord2f(0, 0.0f, 1.0f); 
    myBatch.Vertex3f(-1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount)); 
    //myBatch.Vertex3f(-1.0f, 1.0f, 1.0f); 

    myBatch.End(); 
} 

void ShutdownRC(void) 
{ 
    glDeleteTextures(m_uImageCount, (GLuint*)m_puTextureIDs); 
} 


int main(int argc, char* argv[]) 
{  
    gltSetWorkingDirectory(argv[0]); 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); 
    glutInitWindowSize(400, 400); 
    glutCreateWindow("Volume_Rendering"); 
    glutReshapeFunc(ChangeSize); 
    glutSpecialFunc(SpecialKeys); 
    glutDisplayFunc(RenderScene); 

    GLenum err = glewInit(); 
    if (GLEW_OK != err) { 
     fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); 
     return 1; 
    } 

    SetupRC(); 

    glutMainLoop(); 

    ShutdownRC(); 
    return 0; 

}