Как правильно оформить прозрачность поверхности трехмерного объекта с помощью освещения с помощью OpenGLC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Как правильно оформить прозрачность поверхности трехмерного объекта с помощью освещения с помощью OpenGL

Сообщение Anonymous »

Я создал приложение для настольного компьютера Windows с помощью Visual Studio и добавляю немного кода для настройки библиотеки OpenGL.
В непрозрачном состоянии, затенение и глубина объекта хорошо представлены. Однако при регулировке прозрачности с использованием ползунка на поверхности появляется неравномерное затенение, что делает ее неестественным. Я был бы признателен за вашу помощь в изменении кода для решения этой проблемы.void InitOpenGL(HWND hWnd)
{
HDC hDC = GetDC(hWnd);
PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };

int format = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, format, &pfd);

HGLRC hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);

glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
SetupLighting();
}
< /code>
Функция SetUplights была настроена для применения соответствующих эффектов освещения. < /p>
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -25.0f);

glRotatef(rotationX, 1.0f, 0.0f, 0.0f);
glRotatef(rotationY, 0.0f, 1.0f, 0.0f);

if (showSphere) draw_Sphere();
if (showStructure) draw_Structure();

SwapBuffers(wglGetCurrentDC());
}

void UpdateTransparency(int value)
{
transparency = value / 100.0f;
InvalidateRect(hWnd, NULL, FALSE);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_LBUTTONDOWN:
isDragging = true;
lastMouseX = LOWORD(lParam);
lastMouseY = HIWORD(lParam);
break;

case WM_LBUTTONUP:
isDragging = false;
break;

case WM_MOUSEMOVE:
if (isDragging)
{
int mouseX = LOWORD(lParam);
int mouseY = HIWORD(lParam);

rotationX += (mouseY - lastMouseY) * 0.5f;
rotationY += (mouseX - lastMouseX) * 0.5f;

lastMouseX = mouseX;
lastMouseY = mouseY;

InvalidateRect(hWnd, NULL, FALSE);
}
break;

case WM_COMMAND:
{
int wmId = LOWORD(wParam);
HMENU hMenu = GetMenu(hWnd);
switch (wmId)
{
case IDM_DRAW_STRUCT:
showStructure = !showStructure;
CheckMenuItem(hMenu, IDM_DRAW_STRUCT, showStructure ? MF_CHECKED : MF_UNCHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_DRAW_SPHERE:
showSphere = !showSphere;
CheckMenuItem(hMenu, IDM_DRAW_SPHERE, showSphere ? MF_CHECKED : MF_UNCHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);

RenderScene();
EndPaint(hWnd, &ps);
}
break;
case WM_HSCROLL:
UpdateTransparency(SendMessage(hSlider, TBM_GETPOS, 0, 0));
break;
case WM_SIZE:
ResizeGLScene(LOWORD(lParam), HIWORD(lParam));
break;

case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

void ResizeGLScene(int width, int height)
{
if (height == 0) height = 1;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)width / (GLfloat)height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
< /code>
drawfunctions.cpp, данный как < /p>
void draw_Structure()
{
float vertices[14][3] = {
{2.0, 0.0, 7.0}, {2.0, 2.0, 5.0},
{2.0, 0.0, 0.0}, {0.0, 0.0, 7.0},
{4.0, 2.0, 5.0}, {0.0, 0.0, 0.0},
{4.0, 2.0, 7.0}, {2.0, 2.0, 7.0},
{2.0, 0.0, 5.0}, {2.0, 2.0, 0.0},
{0.0, 2.0, 7.0}, {4.0, 0.0, 5.0},
{0.0, 2.0, 0.0}, {4.0, 0.0, 7.0}
};
int faces[24][3] = {
{7, 3, 0}, {3, 12, 5},
{10, 7, 1}, {2, 12, 9},
{5, 2, 8}, {2, 1, 8},
{7, 4, 1}, {6, 11, 4},
{13, 8, 11}, {11, 1, 4},
{6, 0, 13}, {7, 10, 3},
{3, 10, 12}, {9, 12, 1},
{12, 10, 1}, {2, 5, 12},
{8, 0, 3}, {3, 5, 8},
{2, 9, 1}, {7, 6, 4},
{6, 13, 11}, {13, 0, 8},
{11, 8, 1}, {6, 7, 0}
};
float faceNormals[24][3] = {
{0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0},
{0.0, -1.0, 0.0}, {1.0, 0.0, 0.0},
{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
{0.0, -1.0, 0.0}, {0.0, 0.0, -1.0},
{0.0, 0.0, 1.0}, {0.0, 0.0, 1.0},
{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0},
{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0},
{0.0, -1.0, 0.0}, {0.0, -1.0, 0.0},
{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0},
{1.0, 0.0, 0.0}, {0.0, -1.0, 0.0},
{0.0, 0.0, -1.0}, {0.0, 0.0, 1.0}
};

auto vertexNormals = compute_VertexNormals(vertices, faces, faceNormals);

GLfloat materialAmbient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat materialDiffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat materialSpecular[] = { 1.5f, 1.5f, 1.5f, 1.0f };
GLfloat materialShininess[] = { 64.0f };

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, materialAmbient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, materialDiffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materialSpecular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, materialShininess);

std::vector sortedFaces;
for (int i = 0; i < 24; i++) {
float z_avg = (vertices[faces[0]][2] + vertices[faces[1]][2] + vertices[faces[2]][2]) / 3.0f;
sortedFaces.push_back({ z_avg, i });
}

std::sort(sortedFaces.begin(), sortedFaces.end(), [](const auto& a, const auto& b) {
return a.first > b.first; }
);

int iopt = 1;
if (iopt == 0) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_COLOR_MATERIAL);

glBegin(GL_TRIANGLES);
for (const auto& face : sortedFaces) {
int i = face.second;
for (int j = 0; j < 3; j++) {
int index = faces[j];
glNormal3f(vertexNormals[index][0], vertexNormals[index][1], vertexNormals[index][2]);
glColor4f(0.6f, 0.6f, 0.6f, transparency);
glVertex3f(vertices[index][0], vertices[index][1], vertices[index][2]);
}
}
glEnd();

glDisable(GL_COLOR_MATERIAL);
glDisable(GL_BLEND);
}
else if (iopt == 1) {
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

glBegin(GL_TRIANGLES);
for (int i = 0; i < 24; i++) {
for (int j = 0; j < 3; j++) {
int index = faces[j];
glNormal3f(vertexNormals[index][0], vertexNormals[index][1], vertexNormals[index][2]);
glColor4f(0.8f, 0.8f, 0.8f, 1.0f);
glVertex3f(vertices[index][0], vertices[index][1], vertices[index][2]);
}
}
glEnd();

if (transparency < 1.0f) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);

glBegin(GL_TRIANGLES);
for (const auto& face : sortedFaces) {
int i = face.second;
for (int j = 0; j < 3; j++) {
int index = faces[j];
glNormal3f(vertexNormals[index][0], vertexNormals[index][1], vertexNormals[index][2]);
glColor4f(0.6f, 0.6f, 0.6f, transparency);
glVertex3f(vertices[index][0], vertices[index][1], vertices[index][2]);
}
}
glEnd();

glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/794 ... lighting-u
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»